E2E Testing
Drive end-to-end tests through Playwright's MCP-backed Test Agents — Planner,
Generator, Healer — released in Playwright 1.56 (Oct 2025).
The user writes (or approves) a Markdown feature spec; agents generate the
test, run it against a real browser via the accessibility tree, and self-heal
when locators drift.
This SKILL.md is a thin index.
Decision rules live in rules/*.md and load on demand.
Worked references (agent reference, MCP tool catalog, pyramid math) live
in references/*.md.
Literal boilerplate the skill emits lives in templates/*.md.
Do not preload everything — load only what the current phase asks for.
When to use
Reach for this skill when any of the following is true:
- A feature has user-facing flow that integration tests cannot fully cover.
- A bug repros only through real navigation (multi-page, auth, real network).
- A flake needs a Healer pass instead of a manual locator hunt.
- The repo has no
@playwright/mcp wiring yet and needs Phase 0 setup.
Do not reach for this skill when:
- A unit or component test would catch the same bug — defer to
tdd and the layer rule in
rules/layer-decision.md.
- The change is a pure refactor with no behavioural surface.
- You are adding test infrastructure unrelated to a real flow.
Phase 0 — Preflight (mandatory gate)
Before any agent loop, verify the repo is wired for Playwright Test Agents.
Halt and ask the user before installing anything.
Run these checks (read-only):
# 1. Playwright + MCP server installed?
jq '.devDependencies | keys[]' package.json | grep -E '@playwright/(test|mcp)'
# 2. Test-agent artefacts present?
ls specs/ tests/seed.spec.ts playwright.config.ts 2>/dev/null
Decision table:
| State |
Action |
| Both deps present + artefacts exist |
Proceed to Phase 1. |
| Deps missing |
Halt. Print install plan, ask permission before running. |
| Deps present, artefacts missing |
Halt. Print npx playwright init-agents --loop=claude, ask first. |
Playwright present but version < 1.56 |
Halt. Test Agents require 1.56+. Ask permission to upgrade. |
Print the exact commands; do not run them silently.
The install plan template is in templates/install-plan.md.
Phase 1 — Spec-first feature flow
The agent loop is spec → generate → run → heal.
The spec is human-readable Markdown, not code.
Full rules: rules/spec-first-flow.md.
specs/<flow>.md ─┐
├─→ Generator ─→ tests/<flow>.spec.ts ─→ run ─→ pass?
│ │ no
│ ▼
└──────────────────── Healer ←────────────── failing test
│
▼
patched test or `data-testid` proposal
Two entry points:
- Spec already drafted by the user.
Skip the Planner.
Run the Generator on
specs/<flow>.md.
- App exists, no spec yet.
Run the Planner against the live app to draft
specs/<flow>.md.
User reviews the Markdown plan before generation.
Use the Markdown template in templates/spec.md.
Locator ladder (when generating or healing)
The Generator and the Healer both walk the accessibility tree.
Pick locators in this order — never skip a rung:
getByRole('button', { name: 'Save' }) — accessibility-tree native.
getByLabel, getByPlaceholder, getByText — user-facing strings.
getByTestId('save-draft') — escape hatch only.
data-testid is a source change, not a test workaround.
When the Healer cannot find a stable locator at rungs 1–2, propose a source
diff that adds data-testid to the component, and offer the diff for user
approval before patching the test.
Full rules and decision criteria: rules/locator-strategy.md.
Phase 2 — Token-aware execution
Playwright MCP defaults to snapshot mode (accessibility tree, text-only).
Do not enable --caps=vision unless an explicit pixel-level concern exists.
Full rules: rules/token-budget.md.
Defaults the skill prescribes:
- Snapshot mode (no vision) for all agent calls.
- Run only the changed spec on iteration:
npx playwright test --last-failed.
- Run the Healer only on failure, not on every save.
- Reuse
storageState from tests/seed.spec.ts to skip auth on every run.
- Cap the heal loop at three attempts per failing test before escalating.
Phase 3 — Verification
After the Generator produces a test:
- Run the test once against the live app.
It must pass on first run, or the Healer must converge in ≤ 3 attempts.
- Invoke
test-provenance-guard on
the generated file to ensure the test imports production code instead
of a private re-implementation.
- Open
playwright.config.ts and confirm trace: 'on-first-retry' is set
so a future failure produces a trace bundle.
If the heal loop fails to converge:
- Invoke
confidence(analysis) on the test failure.
- If confidence is below 90%, escalate to the user with the trace, the spec,
and the proposed locator changes — do not keep healing blindly.
Decision flow at a glance
| Signal |
Do |
| Bug fixable by a unit or component test |
Use tdd, not this skill. |
| Multi-page user flow, auth, or real network involved |
Spec-first feature flow (Phase 1). |
| Flaky existing test |
Healer pass only; do not rewrite without spec context. |
| Locator unstable, no stable role / label |
Propose data-testid diff (rule: locator-strategy). |
| Repo missing Playwright or MCP |
Phase 0 halt + ask permission. |
| Heal loop > 3 attempts |
Stop, run confidence(analysis), escalate. |
| Test passes on first run, never seen failing |
Run test-provenance-guard before declaring done. |
Composes with
tdd — owns the unit and component layers.
This skill defers to it for anything below E2E.
test-provenance-guard — runs after
Generator output to catch tests-by-construction.
confidence — gate when the heal loop fails.
holistic-analysis — if a flow is failing
for reasons no test rewrite can fix, step back instead of patching.
playwright-trace-analyzer —
consume the trace produced by a failed test on retry.
References
Templates
- Writing E2E for logic a unit test catches.
- Running the Healer on every save.
- Patching the test with brittle CSS selectors instead of proposing a
data-testid diff.
- Enabling
--caps=vision without a pixel-level requirement.
- Ignoring Healer suggestions and keeping a
.skip() in CI.
- Generating tests against a stub server, not the real app.
Definition of done
1---2name: e2e-testing3description: Plans, generates, runs, and heals end-to-end tests using Playwright Test Agents (Planner, Generator, Healer) and the official `@playwright/mcp` server. Drives a spec-first feature-flow loop, proposes `data-testid` source diffs only when accessibility-tree locators fail, and stays token-aware via snapshot mode and `--last-failed` reruns. Use when adding E2E coverage, verifying a user journey, hardening a flaky flow, or wiring Playwright MCP into a repo. Triggers on "test this flow", "add e2e", "verify the user journey", "write e2e test", "feature test", "playwright agents", "/e2e-testing".4license: MIT5---67# E2E Testing89Drive end-to-end tests through Playwright's MCP-backed Test Agents — Planner,10Generator, Healer — released in Playwright 1.56 (Oct 2025).11The user writes (or approves) a Markdown feature spec; agents generate the12test, run it against a real browser via the accessibility tree, and self-heal13when locators drift.1415> **This `SKILL.md` is a thin index.**16> Decision rules live in [`rules/*.md`](./rules) and load on demand.17> Worked references (agent reference, MCP tool catalog, pyramid math) live18> in [`references/*.md`](./references).19> Literal boilerplate the skill emits lives in [`templates/*.md`](./templates).20> Do not preload everything — load only what the current phase asks for.2122---2324## When to use2526Reach for this skill when any of the following is true:2728- A feature has user-facing flow that integration tests cannot fully cover.29- A bug repros only through real navigation (multi-page, auth, real network).30- A flake needs a Healer pass instead of a manual locator hunt.31- The repo has no `@playwright/mcp` wiring yet and needs Phase 0 setup.3233Do **not** reach for this skill when:3435- A unit or component test would catch the same bug — defer to36 [`tdd`](../../quality/tdd/SKILL.md) and the layer rule in37 [`rules/layer-decision.md`](./rules/layer-decision.md).38- The change is a pure refactor with no behavioural surface.39- You are adding test infrastructure unrelated to a real flow.4041---4243## Phase 0 — Preflight (mandatory gate)4445Before any agent loop, verify the repo is wired for Playwright Test Agents.46Halt and ask the user before installing anything.4748Run these checks (read-only):4950```bash51# 1. Playwright + MCP server installed?52jq '.devDependencies | keys[]' package.json | grep -E '@playwright/(test|mcp)'5354# 2. Test-agent artefacts present?55ls specs/ tests/seed.spec.ts playwright.config.ts 2>/dev/null56```5758Decision table:5960| State | Action |61| ------------------------------------------- | ----------------------------------------------------------------------- |62| Both deps present + artefacts exist | Proceed to Phase 1. |63| Deps missing | **Halt.** Print install plan, ask permission before running. |64| Deps present, artefacts missing | **Halt.** Print `npx playwright init-agents --loop=claude`, ask first. |65| Playwright present but version `< 1.56` | **Halt.** Test Agents require 1.56+. Ask permission to upgrade. |6667Print the exact commands; do not run them silently.68The install plan template is in [`templates/install-plan.md`](./templates/install-plan.md).6970---7172## Phase 1 — Spec-first feature flow7374The agent loop is **spec → generate → run → heal**.75The spec is human-readable Markdown, not code.76Full rules: [`rules/spec-first-flow.md`](./rules/spec-first-flow.md).7778```79specs/<flow>.md ─┐80 ├─→ Generator ─→ tests/<flow>.spec.ts ─→ run ─→ pass?81 │ │ no82 │ ▼83 └──────────────────── Healer ←────────────── failing test84 │85 ▼86 patched test or `data-testid` proposal87```8889Two entry points:90911. **Spec already drafted by the user.**92 Skip the Planner.93 Run the Generator on `specs/<flow>.md`.942. **App exists, no spec yet.**95 Run the Planner against the live app to draft `specs/<flow>.md`.96 User reviews the Markdown plan before generation.9798Use the Markdown template in [`templates/spec.md`](./templates/spec.md).99100### Locator ladder (when generating or healing)101102The Generator and the Healer both walk the accessibility tree.103Pick locators in this order — never skip a rung:1041051. `getByRole('button', { name: 'Save' })` — accessibility-tree native.1062. `getByLabel`, `getByPlaceholder`, `getByText` — user-facing strings.1073. `getByTestId('save-draft')` — escape hatch only.108109`data-testid` is a source change, not a test workaround.110When the Healer cannot find a stable locator at rungs 1–2, propose a source111diff that adds `data-testid` to the component, and offer the diff for user112approval before patching the test.113Full rules and decision criteria: [`rules/locator-strategy.md`](./rules/locator-strategy.md).114115---116117## Phase 2 — Token-aware execution118119Playwright MCP defaults to **snapshot mode** (accessibility tree, text-only).120Do not enable `--caps=vision` unless an explicit pixel-level concern exists.121Full rules: [`rules/token-budget.md`](./rules/token-budget.md).122123Defaults the skill prescribes:124125- Snapshot mode (no vision) for all agent calls.126- Run only the changed spec on iteration: `npx playwright test --last-failed`.127- Run the Healer **only on failure**, not on every save.128- Reuse `storageState` from `tests/seed.spec.ts` to skip auth on every run.129- Cap the heal loop at three attempts per failing test before escalating.130131---132133## Phase 3 — Verification134135After the Generator produces a test:1361371. Run the test once against the live app.138 It must pass on first run, or the Healer must converge in ≤ 3 attempts.1392. Invoke [`test-provenance-guard`](../../quality/test-provenance-guard/SKILL.md) on140 the generated file to ensure the test imports production code instead141 of a private re-implementation.1423. Open `playwright.config.ts` and confirm `trace: 'on-first-retry'` is set143 so a future failure produces a trace bundle.144145If the heal loop fails to converge:146147- Invoke `confidence(analysis)` on the test failure.148- If confidence is below 90%, escalate to the user with the trace, the spec,149 and the proposed locator changes — do **not** keep healing blindly.150151---152153## Decision flow at a glance154155| Signal | Do |156| ------------------------------------------------------------ | ------------------------------------------------------------- |157| Bug fixable by a unit or component test | Use [`tdd`](../../quality/tdd/SKILL.md), not this skill. |158| Multi-page user flow, auth, or real network involved | Spec-first feature flow (Phase 1). |159| Flaky existing test | Healer pass only; do not rewrite without spec context. |160| Locator unstable, no stable role / label | Propose `data-testid` diff (rule: locator-strategy). |161| Repo missing Playwright or MCP | Phase 0 halt + ask permission. |162| Heal loop > 3 attempts | Stop, run `confidence(analysis)`, escalate. |163| Test passes on first run, never seen failing | Run `test-provenance-guard` before declaring done. |164165---166167## Composes with168169- [`tdd`](../../quality/tdd/SKILL.md) — owns the unit and component layers.170 This skill defers to it for anything below E2E.171- [`test-provenance-guard`](../../quality/test-provenance-guard/SKILL.md) — runs after172 Generator output to catch tests-by-construction.173- [`confidence`](../../quality/confidence/SKILL.md) — gate when the heal loop fails.174- [`holistic-analysis`](../../analysis/holistic-analysis/SKILL.md) — if a flow is failing175 for reasons no test rewrite can fix, step back instead of patching.176- [`playwright-trace-analyzer`](../../analysis/playwright-trace-analyzer/SKILL.md) —177 consume the trace produced by a failed test on retry.178179---180181## References182183- [`references/playwright-agents.md`](./references/playwright-agents.md) —184 Planner / Generator / Healer reference, inputs, outputs, invocation.185- [`references/mcp-tool-catalog.md`](./references/mcp-tool-catalog.md) —186 the `@playwright/mcp` tool surface, grouped by category.187- [`references/pyramid-2026.md`](./references/pyramid-2026.md) — testing188 pyramid math in 2026, with the AI-generation caveat.189190## Templates191192- [`templates/spec.md`](./templates/spec.md) — feature-flow Markdown spec.193- [`templates/seed.spec.ts`](./templates/seed.spec.ts) — auth and storage194 bootstrap, produces `storageState`.195- [`templates/playwright.config.ts`](./templates/playwright.config.ts) —196 opinionated config: snapshot mode, traces on first retry, projects per197 browser, parallel CI defaults.198- [`templates/install-plan.md`](./templates/install-plan.md) — Phase 0 halt199 message with the exact commands to install Playwright + MCP.200201---202203## Anti-patterns (one-liner — full list in [`rules/anti-patterns.md`](./rules/anti-patterns.md))204205- Writing E2E for logic a unit test catches.206- Running the Healer on every save.207- Patching the test with brittle CSS selectors instead of proposing a208 `data-testid` diff.209- Enabling `--caps=vision` without a pixel-level requirement.210- Ignoring Healer suggestions and keeping a `.skip()` in CI.211- Generating tests against a stub server, not the real app.212213---214215## Definition of done216217- [ ] Phase 0 preflight passed or installs were user-approved.218- [ ] `specs/<flow>.md` exists and the user reviewed it.219- [ ] `tests/<flow>.spec.ts` passes against the live app.220- [ ] `test-provenance-guard` reports no violations on the new test.221- [ ] `playwright.config.ts` has `trace: 'on-first-retry'`.222- [ ] If a `data-testid` was added, it is in the source diff and committed.