Instruction file imported from norielmallari/comprexy (
.cursor/rules/ui-testing.mdc). Copyright stays with the author.
description: UI locator hierarchy, data-testid policy, and Playwright vs unit DoD globs: /*.tsx,/.jsx,**/.ts,**/playwright.config.* alwaysApply: false
UI testing
Locator hierarchy (prefer in order)
- Role + accessible name
- Label text / placeholder only when role is weak
data-testidfor charts, canvas, and custom widgets where role/label is insufficient- CSS / XPath — last resort; do not make them the primary contract
Definition of done (touched UI flows)
- Unit/component tests (Vitest/RTL or app-equivalent) cover logic and accessible behavior where practical
- Committed Playwright smoke for the touched user flow is green under mocked APIs
- Playwright does not replace unit tests; unit tests do not replace Playwright
Playwright defaults
- Mock control-api / BFF by default (
page.routeor fixtures) — live:8130is optional, not merge-default - Assert structure and accessible outcomes, not pixels
- Do not delete assertions or add unconditional waits to force green
- Headless only for agent/CI runs:
npm run test:e2e(forces chrome-headless-shell). Never--headed,test:e2e:headed,test:e2e:ui,PW_HEADED=1, or browser/Playwright MCP — those spawn a visible Chromium/Chrome on the operator machine
Agents
Orchestrator try loops live in .cursor/agents/ — not in this rule. Agents must not open a headed browser.