| name | e2e-author |
| description | Author Playwright E2E tests for critical user flows by orchestrating the official planner and generator agents. Use when the user asks to write or add E2E tests, create a Playwright test plan, generate specs for a flow, or cover a critical user flow end-to-end. Selects CUFs (flows whose failure breaks revenue, data, or trust), runs the planner agent to produce a Markdown plan behind a user review gate, then the generator agent to produce spec files with live-verified semantic getByRole locators, and burns each new spec in with --repeat-each to block flakes before merge. Requires e2e-setup to have generated the agents first. Run from the user's project root. |
| allowed-tools | Read Write Edit Bash Glob Grep Task AskUserQuestion |
E2E Author — planner -> generator orchestration
Turn a critical user flow into a reliable Playwright spec by driving Playwright's official agents. This skill orchestrates; the agents (generated by e2e-setup via npx playwright init-agents --loop=claude) do the exploration and code generation. A spec read is a behavior contract; a spec run is a sensor.
Precondition check
- Confirm the agents exist:
.claude/agents/playwright-test-planner.md and playwright-test-generator.md, plus .mcp.json and seed.spec.ts. If missing, route the user to e2e-harness:e2e-setup first — do not hand-roll the agents.
- Read the E2E SSOT doc (
e2e/AGENTS.md or .claude/e2e-guidelines.md) for the CUF list and conventions. If absent, run e2e-setup Step 5 or capture the CUFs inline.
Workflow
-
Select the critical user flow(s):
- A CUF is a flow where a regression breaks revenue, data integrity, or user trust (checkout, signup+login, create/edit/delete persistence, permissions). Prefer these over breadth.
- If the SSOT doc lists CUFs, pick from it. Otherwise use AskUserQuestion to confirm the 1-3 flows in scope. Do not auto-pick everything — E2E breadth is a cost.
-
Plan (planner agent) + review gate:
- Dispatch the planner:
Task(subagent_type="playwright-test-planner", prompt="<the CUF + any PRD/notes>. Run seed.spec.ts to set up the environment, explore the app, and write a Markdown test plan under specs/.").
- The planner explores the live app and writes
specs/<flow>.md.
- MANDATORY user review gate: present the plan and get explicit approval (AskUserQuestion) before generating any code. The plan is cheap to fix; generated specs are not. Incorporate edits into
specs/<flow>.md before proceeding.
-
Generate (generator agent):
- Dispatch the generator:
Task(subagent_type="playwright-test-generator", prompt="Turn specs/<flow>.md into Playwright spec files under e2e/. Verify every selector and assertion live as you go.").
- The generator verifies selectors/assertions against the running app as it writes.
- Enforce semantic locators: specs must use
getByRole(role, { name }) / getByLabel / getByText, not CSS/XPath. If the generator emits brittle selectors, send it back to fix them (Playwright's own best-practice is role-first locators).
-
Burn-in (flake gate):
npx playwright test e2e/<flow>.spec.ts --repeat-each=3
--repeat-each=N runs each test N times unconditionally — it surfaces intermittent flakiness before merge.
- A single failure across the repeats = flaky = blocked. Do not merge a spec that is not green on every repeat. If it flakes, hand it to
e2e-harness:e2e-debug (or the healer) and re-burn. Catching flakes at authoring time is far cheaper than in CI.
-
Convention cleanup:
- Split long flows into
test.step("...") blocks for readable traces.
- Match the project's conventions from the SSOT doc (step-name language — English or Korean —, file layout
e2e/<feature>.spec.ts, fixture naming). Learn from existing specs rather than imposing a new style.
- Ensure no arbitrary
waitForTimeout — use web-first assertions (expect(locator).toBeVisible()).
-
Report: list the spec files written, the burn-in result (N/N green), and the locator/convention state. Stage only the new/changed E2E files.
Notes
- Test independence — set state via API, don't replay shared prefixes. When flows share a long common prefix (e.g. consent -> phone auth) before branching, do NOT make each test re-run that prefix through the UI. Have the generator put the user at the branch's start state via a test API, then assert only that branch. This avoids cascade failures (a prefix change failing every test) and cumulative runtime, and keeps tests independent. This is distinct from
storageState (auth only) — it sets mid-flow app state. Capture the available state-setup endpoints in the E2E SSOT doc.
- The planner/generator drive the browser through the
playwright-test MCP server; if their tool calls fail, verify .mcp.json is approved (/mcp).
- This skill does not set up the harness (
e2e-setup) or repair CI failures (e2e-debug).