E2E Testing — critical flows, stable and honest
Playbook for functional end-to-end tests. The e2e-runner agent does the writing; this skill is the pattern set it follows.
Page-object model
- One class/module per page or major component: selectors + actions live there, tests read as user intent (
await loginPage.signInAs(user)), not selector soup.
- Tests assert outcomes; page objects encapsulate how.
Fixtures and isolation
- Each test owns its data and starts from a known state (seeded via API/fixtures, not by clicking through setup). No test depends on another's side effects or ordering.
- Auth via storage-state reuse (log in once, reuse the session) rather than logging in through the UI every test.
Network discipline
- Stub third-party/flaky externals; hit your own backend for real where the journey demands it. Be explicit about which.
waitForResponse/route interception over sleeps.
Artifacts and CI
- Capture trace + screenshot + video ON FAILURE only (cost). Upload as CI artifacts.
- CI: shard across workers for speed; retries allowed ONLY with a report that surfaces the retried specs (so flake stays visible, not buried).
- The critical-flow subset is the gate; the full suite can be broader.
Browser binaries — never assumed present
Never assume Playwright/Cypress browser binaries are already on the machine. hooks/doctor.sh --install-e2e --yes installs the binary for whichever framework the repo already uses (detected from playwright.config.*/cypress.config.* — it never picks a framework for you), cross-platform (macOS, Linux, Windows-via-WSL), no sudo. The e2e-runner agent runs this before every suite in both implement and verify mode. If it comes back missing, that's an environment gap (or, on Linux, missing system libraries that need install-deps and sudo) — report it plainly, never silently skip the gate.
1---2name: e2e-testing3description: E2E Testing — critical flows, stable and honest4---56# E2E Testing — critical flows, stable and honest78Playbook for functional end-to-end tests. The `e2e-runner` agent does the writing; this skill is the pattern set it follows.910<HARD-RULES>11- Test CRITICAL user journeys (the flows that, broken, mean the product is broken) — not every button. Exhaustive UI coverage is unit/component work, not E2E.12- Selectors: role-based (`getByRole`) or test IDs (`data-testid`) — NEVER brittle CSS/text that breaks on copy changes.13- Wait on CONDITIONS (`expect(...).toBeVisible()`, `waitForResponse`) — never on fixed timeouts (`waitForTimeout`). Timeouts are the #1 source of flake.14- Flaky specs are quarantined and reported, never retried-until-green. A hidden flake is a lie about coverage.15</HARD-RULES>1617## Page-object model1819- One class/module per page or major component: selectors + actions live there, tests read as user intent (`await loginPage.signInAs(user)`), not selector soup.20- Tests assert outcomes; page objects encapsulate how.2122## Fixtures and isolation2324- Each test owns its data and starts from a known state (seeded via API/fixtures, not by clicking through setup). No test depends on another's side effects or ordering.25- Auth via storage-state reuse (log in once, reuse the session) rather than logging in through the UI every test.2627## Network discipline2829- Stub third-party/flaky externals; hit your own backend for real where the journey demands it. Be explicit about which.30- `waitForResponse`/route interception over sleeps.3132## Artifacts and CI3334- Capture trace + screenshot + video ON FAILURE only (cost). Upload as CI artifacts.35- CI: shard across workers for speed; retries allowed ONLY with a report that surfaces the retried specs (so flake stays visible, not buried).36- The critical-flow subset is the gate; the full suite can be broader.3738## Browser binaries — never assumed present3940Never assume Playwright/Cypress browser binaries are already on the machine. `hooks/doctor.sh --install-e2e --yes` installs the binary for whichever framework the repo already uses (detected from `playwright.config.*`/`cypress.config.*` — it never picks a framework for you), cross-platform (macOS, Linux, Windows-via-WSL), no sudo. The `e2e-runner` agent runs this before every suite in both `implement` and `verify` mode. If it comes back `missing`, that's an environment gap (or, on Linux, missing system libraries that need `install-deps` and sudo) — report it plainly, never silently skip the gate.