| name | e2e-testing-guidelines |
| description | Conventions for Playwright end-to-end tests in this project. Covers the `e2e/tests` layout and `<name>.test.ts` naming, `test.step` structuring, stable test-id chained/scoped locators (never text matching), framework-native auto-waiting assertions over manual DOM reads, polling/wait-for helpers instead of fixed sleeps for scroll- or animation-driven settling, reusable UI helpers in `e2e/helpers`, the `@scenario` coverage-catalog tagging, and the snapshot-update flow. |
| when_to_use | Use whenever writing, reviewing, refactoring, or running Playwright end-to-end tests, or when a change needs verification via the e2e suite — even when the user only mentions e2e tests, snapshots, test IDs, polling/waiting, focus assertions, or a failing test run. |
| user-invocable | false |
E2E Testing Guidelines
Apply these rules when running, writing or reviewing Playwright end-to-end tests in this project.
End-to-End Test Commands
See commands.md for:
End-to-End Test Structure
See structure.md for:
- Understanding the end-to-end test structure
- Writing end-to-end tests
- Reviewing end-to-end tests
- Refactoring end-to-end tests
End-to-End Test Conventions
See conventions.md for:
- Writing end-to-end tests
- Reviewing end-to-end tests
- Refactoring end-to-end tests
E2E Scenario Coverage
See scenario-coverage.md for:
- The scenario-coverage metric (user journeys, not E2E line coverage)
- The
e2e/scenarios.md catalog (markdown table) and the @scenario:<id> + @area:/@priority: tagging convention
- The reporter, the phased
must-gate, and how to run/read coverage:scenarios
Project Defaults
These are the load-bearing defaults for bombdog's suite — the layout, run command, scenario tagging, locator, and assertion rules a spec must follow.
Guidelines:
- MUST place specs under
e2e/tests/ named <name>.test.ts, and reusable helpers under e2e/helpers/ (Playwright testDir is e2e/tests).
- MUST run the suite with
npm run test:e2e; point at a system Chromium via PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH when Playwright's managed browser is unavailable.
- MUST tag every e2e test with a plain-string
@scenario:<id> join tag from the e2e/scenarios.md catalog plus matching @area:/@priority: facet tags (and @smoke on the fast gates); the suite tracks scenario coverage (user journeys), not E2E line coverage. See scenario-coverage.md.
- MUST wrap each meaningful action/assertion group of a multi-phase scenario (a journey with two or more distinct arrange/act/assert phases) in
test.step("<human sentence>", …) (steps may nest). A short atomic test — a single arrange → act → assert, e.g. most smoke gates — MAY omit steps; do not pad it with a one-step wrapper.
- MUST locate elements with
getByTestId(), chained to narrow scope (e.g. composer(page).getByTestId("log-move")); use locator('[data-testid="…"][data-…="…"]') for entity/state targeting. Reserve getByRole for elements without a test id (e.g. Radix-portaled options); avoid getByText for control targeting.
- MUST prefer locator-native, auto-waiting assertions (
toBeVisible, toBeEnabled, toHaveAttribute); never use fixed sleeps — use expect.poll / waitForFunction when no native assertion fits.
- SHOULD factor repeated navigation/setup into
e2e/helpers/ functions that take page and return Locators or perform a named action.
- SHOULD organise specs by purpose:
smoke.test.ts (a handful of shallow gates — boots, core loop of set-up → log → persist → reset), happy-path.test.ts (the main use cases end to end — each action type, turn rotation, undo/redo, edit, collapse, persistence), and regressions.test.ts (named guards for past bugs). Smoke is the first gate; if it fails, deeper suites aren't worth running.