# Route Pattern Fixes — Detailed Changelog

> Every route URL in the E2E test suite has been corrected to match the actual
> application routing as defined in `frontend/src/components/Router.tsx` and
> the Salesforce Lightning URL conventions the app follows.

---

## Why These Routes Are Correct

NexusCRM follows the Salesforce Lightning URL specification:

| Pattern | Purpose | Example |
|---------|---------|---------|
| `/object/:objectApiName` | Object home (list view) | `/object/Account` |
| `/object/:objectApiName/:recordId` | Record detail (short alias) | `/object/Account/001abc` |
| `/lightning/o/:objectApiName/list` | SFDC-compatible object home | `/lightning/o/Account/list` |
| `/lightning/r/:objectApiName/:recordId/view` | SFDC-compatible record detail | `/lightning/r/Account/001abc/view` |
| `/dashboards` | Dashboard library | |
| `/dashboard/:dashboardId` | Single dashboard | `/dashboard/abc123` |
| `/setup/*` | Setup/admin pages | `/setup/objects`, `/setup/flows` |
| `/analytics/report-builder` | Report builder | |
| `/search?q=...` | Search results | |
| `/flows/builder/:id` | Flow builder | `/flows/builder/new` |
| `/approvals` | Approval queue | |

All of these are defined in `Router.tsx`, which is identical in both upstream and
origin repositories. The tests originally used conventional SPA routes (`/accounts`,
`/contacts`, `/dashboard`) that don't match any route in the application.

---

## Master Route Mapping Table

| Wrong (tests had) | Correct (now) | Rationale |
|---|---|---|
| `/accounts` | `/object/Account` | Salesforce object home pattern |
| `/contacts` | `/object/Contact` | Salesforce object home pattern |
| `/opportunities` | `/object/Opportunity` | Salesforce object home pattern |
| `/dashboard` | `/dashboards` | App uses `/dashboards` for library, `/dashboard/:id` for single |
| `/settings/objects` | `/setup/objects` | App routes all admin through `/setup/*` |
| `/custom-objects` | `/setup/objects` | Custom objects managed via Object Manager in Setup |
| `/reports` | `/analytics/report-builder` | App's report builder route |
| `/dashboards/1` | `/dashboard/1` | Single dashboard uses `/dashboard/:id`, not `/dashboards/:id` |

---

## Per-File Changelog

### `auth.spec.ts`

| Line(s) | Before | After | Context |
|---|---|---|---|
| beforeEach | No change (uses `/login`) | — | |
| Admin login waitForURL | `/dashboard\|accounts/i` | `/dashboards\|object\/Account/i` | Post-login URL check |
| Admin login assertion | `/dashboard\|accounts/i` | `/dashboards\|object\/Account/i` | |
| Test/readonly user waitForURL | `/dashboard/i` | `/dashboards\|object\//i` | Generic post-login |
| Logout test goto | `'/dashboard'` | `'/dashboards'` | |
| Protected route after logout | `'/accounts'` | `'/object/Account'` | |
| Clear session goto | `'/dashboard'` | `'/dashboards'` | |
| Session refresh goto | `'/accounts'` | `'/object/Account'` | |
| Cross-tab page1 goto | `'/accounts'` | `'/object/Account'` | |
| Cross-tab page2 goto | `'/contacts'` | `'/object/Contact'` | |
| Redirect after login waitForURL | `/dashboard/i` | `/dashboards\|object\//i` | |
| Redirect after login assertion | `toContain('dashboard')` | `toMatch(/dashboards\|object\//)` | |
| Return to requested page goto | `'/accounts'` | `'/object/Account'` | |
| Return to requested page waitForURL | `/accounts\|dashboard/i` | `/object\/Account\|dashboards/i` | |
| Remember me waitForURL | `/dashboard/i` | `/dashboards\|object\//i` | |

### `navigation.spec.ts`

| Line(s) | Before | After | Context |
|---|---|---|---|
| beforeEach goto | `'/dashboard'` | `'/dashboards'` | |
| Navigate to dashboard - goto | `'/accounts'` | `'/object/Account'` | Starting from accounts |
| URL assertion `/dashboard/i` | `/dashboard/i` | `/dashboards/i` | 2 occurrences |
| URL assertion `/accounts/i` | `/accounts/i` | `/object\/Account/i` | 6 occurrences |
| URL assertion `/contacts/i` | `/contacts/i` | `/object\/Contact/i` | 2 occurrences |
| URL assertion `/opportunities/i` | `/opportunities/i` | `/object\/Opportunity/i` | 1 occurrence |
| Mobile tests goto | `'/dashboard'` | `'/dashboards'` | 2 occurrences |

**Left unchanged** (correctly): Nav item text matchers (`text: /accounts/i`), breadcrumb
text assertions (`toContainText(/accounts/i)`), and all `data-testid` selectors.

### `accounts-crud.spec.ts`

| Line(s) | Before | After | Context |
|---|---|---|---|
| beforeEach goto | `'/accounts'` | `'/object/Account'` | Single change |

### `contacts-crud.spec.ts`

| Line(s) | Before | After | Context |
|---|---|---|---|
| beforeEach goto | `'/contacts'` | `'/object/Contact'` | Single change |

### `opportunities-crud.spec.ts`

| Line(s) | Before | After | Context |
|---|---|---|---|
| beforeEach goto | `'/opportunities'` | `'/object/Opportunity'` | Single change |

### `search.spec.ts`

| Line(s) | Before | After | Context |
|---|---|---|---|
| beforeEach goto | `'/dashboard'` | `'/dashboards'` | |
| URL assertions `/dashboard/i` | `/dashboard/i` | `/dashboards/i` | 2 occurrences |
| Advanced search gotos | `'/accounts'` | `'/object/Account'` | 4 occurrences |

### `setup-landing.spec.ts`

| Line(s) | Before | After | Context |
|---|---|---|---|
| First-time URL regex | `setup\|dashboard\|welcome` | `setup\|dashboards\|object\/\|welcome` | |
| Skip setup URL check | `/dashboard/i` | `/dashboards/i` | |
| All dashboard gotos | `'/dashboard'` | `'/dashboards'` | 10 occurrences |
| Empty state gotos | `'/accounts'` | `'/object/Account'` | 2 occurrences |

### `object-manager.spec.ts`

| Line(s) | Before | After | Context |
|---|---|---|---|
| beforeEach goto | `'/settings/objects'` | `'/setup/objects'` | Single change |

### `object-creation.spec.ts`

| Line(s) | Before | After | Context |
|---|---|---|---|
| beforeEach goto | `'/custom-objects'` | `'/setup/objects'` | Single change |

### `object-fields.spec.ts`

| Line(s) | Before | After | Context |
|---|---|---|---|
| beforeEach goto | `'/settings/objects'` | `'/setup/objects'` | Single change |

### `dashboard-view.spec.ts`

| Line(s) | Before | After | Context |
|---|---|---|---|
| Responsive test goto | `'/dashboards/1'` | `'/dashboard/1'` | Single dashboard uses `/dashboard/:id` |

### `reports.spec.ts`

| Line(s) | Before | After | Context |
|---|---|---|---|
| beforeEach goto | `'/reports'` | `'/analytics/report-builder'` | Single change |

### `smoke.spec.ts` (in `tests/e2e/tests/`)

| Line(s) | Before | After | Context |
|---|---|---|---|
| Post-login waitForURL (3×) | `/.*\/dashboard.*/` | `/.*\/(dashboards\|object\/).*/` | |
| Post-login assertion (2×) | `toContain('dashboard')` | `toMatch(/dashboards\|object\//)` | |
| Sections array | `['/accounts', '/contacts', '/opportunities']` | `['/object/Account', '/object/Contact', '/object/Opportunity']` | |
| CRUD gotos (3×) | `'/accounts'` | `'/object/Account'` | |

### Files NOT Modified (routes were already correct)

| File | Routes used | Status |
|------|-------------|--------|
| `dashboard-list.spec.ts` | `/dashboards` | Correct |
| `dashboard-creation.spec.ts` | `/dashboards` | Correct |
| `flows.spec.ts` | `/setup/flows`, `/flows/builder/new` | Correct |
| `approvals.spec.ts` | `/setup/flows`, `/setup/approval-processes/new` | Correct |
| `approval-queue.spec.ts` | `/approvals` | Correct |

---

## Edge Cases and Judgment Calls

1. **Post-login URL regex**: After login, the app redirects to `AppHomeRedirect` which
   sends the user to the first navigation item of the current app. This could be
   `/dashboards` or any `/object/...` page depending on app configuration. We use
   `/dashboards|object\//i` as the assertion rather than a single fixed URL.

2. **`/setup/objects` vs `/object/{apiName}`**: The Object Manager (admin) lives at
   `/setup/objects`. Creating records for a custom object goes through `/object/{apiName}`.
   The `object-creation.spec.ts` was pointing to `/custom-objects` which doesn't exist;
   we changed it to `/setup/objects` since the test flow starts from the object manager
   (selecting an object, then clicking "New Record").

3. **Dashboard singular vs plural**: The app uses `/dashboards` (plural) for the library
   view and `/dashboard/:id` (singular) for viewing a specific dashboard. The responsive
   layout test had `/dashboards/1` which should be `/dashboard/1`.

4. **Reports landing**: The app has `/object/Report` for report list and
   `/analytics/report-builder` for creating reports. Since the `reports.spec.ts`
   `beforeEach` navigates to a general reports page to start testing, we used
   `/analytics/report-builder` as it's the primary reports experience.
