Skip to content

Prefer semantic selectors over CSS-first recorder output#35

Open
michaelgichia wants to merge 1 commit intotesting-library:mainfrom
michaelgichia:codex/semantic-selector-priority
Open

Prefer semantic selectors over CSS-first recorder output#35
michaelgichia wants to merge 1 commit intotesting-library:mainfrom
michaelgichia:codex/semantic-selector-priority

Conversation

@michaelgichia
Copy link

What:

Fix selector resolution in the Recorder -> Testing Library export so it no longer blindly uses step.selectors[0] (often CSS). The exporter now prefers semantic selector candidates and emits user-facing RTL queries when possible.

Why:

Recorder exports currently produce brittle document.querySelector(...) calls even when the same step includes richer selector candidates (aria/..., text/...). This goes against the React Testing Library principle of querying the UI the way users perceive it.

Using your integration recordings, a step that includes aria/Add API KEY was exported as a CSS query, making tests implementation-detail driven and unstable.

How:

  • Pass the full selector candidate list into selector stringification for:
    • change
    • click
    • hover
    • doubleClick
    • waitForElement
  • Add candidate ranking:
    1. aria/...
    2. text/...
    3. CSS fallback (then remaining technical selectors)
  • Add richer aria parsing:
    • supports aria/<name>[role="..."]
    • ignores role="generic" and falls back to inferred concrete roles in safe cases
  • Generate semantic queries when possible:
    • screen.getByRole(role, {name})
    • screen.getByText(name) fallback
  • Keep document.querySelector(...) as last resort.
  • Expand tests to cover CSS-first recordings where semantic selectors appear later in the candidate list.

Before / After from recordings:

// Before
await userEvent.click(document.querySelector('#radix-_r_1e_-content-integrations div > button'))

// After
await userEvent.click(screen.getByRole('button', {name: 'Add API KEY'}))
// Before
await userEvent.click(document.querySelector('#radix-_r_1t_'))

// After
await userEvent.click(screen.getByRole('dialog', {name: 'Create an API key'}))
// Before
await userEvent.click(document.querySelector('button.btn-secondary > span'))

// After
await userEvent.click(screen.getByRole('button', {name: 'Cancel'}))

Validation:

  • npm test -- --runInBand --watchman=false src/__tests__/Extension.ts
  • pre-commit + validate hooks passed during commit

Versioning:

  • No version bump in this PR. This repository appears to version for release/publish events rather than per bugfix PR; maintainers can bump at release time.

Checklist:

  • Documentation (N/A)
  • Tests
  • Ready to be merged

@michaelgichia
Copy link
Author

@nickserv, kindly review this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant