# Selector Audit — Methodology and Findings

> Detailed documentation of how the `data-testid` audit was conducted, what was found,
> and recommendations for prioritizing the work of adding selectors to the frontend.

---

## Methodology

### 1. Extraction from E2E Tests

All 17 spec files in `tests/e2e/specs/` plus `tests/e2e/tests/smoke.spec.ts` were
searched for three patterns:

- `getByTestId('...')` — Playwright's test ID locator (exact match)
- `[data-testid="..."]` — CSS attribute selector (exact match)
- `[data-testid^="..."]` — CSS attribute prefix selector (starts-with match)
- `[data-testid$="..."]` — CSS attribute suffix selector
- `[data-testid*="..."]` — CSS attribute substring selector

Additionally, `tests/e2e/utils/selectors.ts` was audited for helper functions that
wrap `getByTestId` calls, revealing additional selectors used transitively by specs
(e.g., `forms.submitButton()` resolves to `getByTestId('submit-button')`).

### 2. Extraction from Frontend Source

The entire `frontend/src/` directory was searched with ripgrep for:

- `data-testid=` in JSX attributes
- `data-testid={` for dynamic testid values
- `testId` or `dataTestId` prop patterns

### 3. Cross-Reference

Every selector extracted from tests was checked against the frontend findings.

---

## Findings

### Frontend `data-testid` Inventory

Only **3 production `data-testid` values** exist in the frontend source code
(excluding unit test files):

| Value | File | Line(s) |
|-------|------|---------|
| `mobile-menu-toggle` | `components/layout/TopBar.tsx` | 119 |
| `formula-editor` | `components/formula/FormulaEditor.tsx` | 165 |
| `field-mapping-builder` | `features/flows/components/FieldMappingBuilder.tsx` | 71, 79, 88, 96 |

Additional `data-testid` values exist in unit test files (`*.test.tsx`) but these
are test doubles / mocks and not present in production code:

| Value | File |
|-------|------|
| `searchable-lookup` | `registries/__tests__/UIRegistry.test.tsx` |
| `searchable-select` | `registries/__tests__/UIRegistry.test.tsx` |
| `grid-layout`, `mock-widget` | `pages/Dashboard.test.tsx` |
| `grid-layout`, `markdown-content` | `features/studio/components/dashboard/DashboardCanvas.test.tsx` |
| `icon-*` (9 values) | `features/flows/components/builder/ActionConfigPanel.test.tsx` |
| `resource-picker`, `flow-value-input` | `features/flows/components/builder/ActionConfigPanel.test.tsx` |

### Gap Analysis

| Metric | Count |
|--------|-------|
| Unique exact `data-testid` values referenced by tests | ~170 |
| Unique prefix patterns referenced by tests | ~50 |
| Unique suffix/substring patterns | ~30 |
| `data-testid` values in production frontend | 3 |
| Overlap between tests and frontend | **0** |
| Tests that will fail due to missing selectors | **100%** |

### Selector Types Distribution

The tests use four types of selector patterns:

1. **Exact match** (`getByTestId('login-form')`) — ~170 unique values.
   These need a specific `data-testid="login-form"` attribute on exactly one element.

2. **Prefix match** (`[data-testid^="table-row-"]`) — ~50 patterns.
   These need `data-testid="table-row-0"`, `data-testid="table-row-1"`, etc.
   on repeated elements. The frontend component generating these rows needs to
   include a dynamic `data-testid={`table-row-${index}`}` attribute.

3. **Suffix match** (`[data-testid$="-error"]`) — 2 patterns.
   Used in `object-creation.spec.ts` to find any field's error message.

4. **Substring match** (`[data-testid*="approve"]`) — ~25 patterns.
   Used primarily in `flows.spec.ts`, `approvals.spec.ts`, and `approval-queue.spec.ts`
   for flexible element matching within complex UIs.

---

## Recommendations

### 1. Start with shared utility selectors

The `selectors.ts` utility file defines helper functions used across many specs.
Adding these selectors first will unblock the most tests:

- `submit-button`, `cancel-button`, `save-button` — used in every CRUD spec
- `modal`, `modal-confirm`, `modal-cancel` — used in every delete flow
- `toast-success`, `toast-error` — used in every success/error assertion
- `user-menu`, `user-menu-logout` — used in auth + navigation

### 2. Use a consistent naming convention

The tests follow a clear naming pattern:

- **Page containers**: `{page}-container` (e.g., `dashboard-container`)
- **Tables**: `{object}-table` (e.g., `accounts-table`)
- **Row actions**: `row-view`, `row-edit`, `row-delete`
- **Form inputs**: `{field}-input` (e.g., `name-input`, `email-input`)
- **Validation errors**: `{field}-error` (e.g., `name-error`, `email-error`)
- **Buttons**: `{action}-button` (e.g., `new-button`, `save-button`)
- **Modals**: `{type}-modal` (e.g., `create-object-modal`, `confirm-delete-modal`)

Adopt this convention when adding attributes.

### 3. Add selectors as a separate frontend PR

Rather than mixing selector additions with feature work, create a dedicated PR
that adds `data-testid` attributes to production components. This:

- Keeps the diff focused and easy to review
- Avoids breaking existing component tests
- Can be done incrementally by component area (see priority order in `SELECTOR_AUDIT.md`)

### 4. Consider a data-testid generation pattern

For metadata-driven components (like `PowerList` which renders columns dynamically),
consider a helper that generates `data-testid` from metadata:

```tsx
function fieldTestId(fieldApiName: string, suffix: string) {
  return `field-${fieldApiName.toLowerCase()}-${suffix}`;
}
```

This ensures consistent naming even as objects and fields change.

---

## How to Use `SELECTOR_AUDIT.md`

The top-level `tests/e2e/SELECTOR_AUDIT.md` is organized by component area in
priority order. A frontend developer should:

1. Pick a component area (e.g., "Login & Auth")
2. Open the relevant frontend component(s)
3. Add each `data-testid` attribute listed for that area
4. Run the corresponding spec file to see which tests now pass
5. Move to the next area

Each area includes the spec file(s) that depend on it, so developers can validate
their work immediately.
