Install
$ agentstack add skill-cakehurstryan-qe-skills-e2e-setup ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
E2E Setup — one-time Playwright bootstrap
Stands up a working Playwright e2e suite in a repo that has none. Run once per repo. Once it's done, every future run uses the e2e-retrofit skill (the many-times workflow) — this skill is the run-once seed.
> Scope — what setup does and does NOT produce. Setup wires the harness to > the app and writes exactly one spec: smoke.spec.ts, just enough to prove > the wiring works end to end. It does not write feature/acceptance tests, > and it does not mark any coverage as done — that is e2e-retrofit's job, > one section per batch. Setup that emits a pile of green feature specs is > over-reaching: it has no requirements to test against, so those specs would > only assert "the app does what it currently does" (characterization), and > marking them "covered" is self-grading. Keep setup to wiring + smoke.
The reference scaffold is bundled here under harness/. See harness/README.md for its layout and the infrastructure (keep, adapt) vs example (replace with your domain) labelling of every file. The selector/assertion rules this bootstrap follows when wiring helpers live in the sibling skill's ../e2e-retrofit/patterns.md.
This skill drives two Playwrights, set up separately:
| | What | Where it lives | Used by | |---|---|---|---| | Test runner | @playwright/test — runs the specs | the project's e2e dir | retrofit Phases 3–6 | | Playwright MCP | browser-automation server Claude drives | registered in Claude Code, not the repo | recon (setup + retrofit Phase 2) |
Step 0 — Detect: is setup already done?
Look for an e2e dir with a playwright.config.ts (e.g. e2e/, tests/e2e/).
- Found → setup has already run. Stop. Tell the user to use the
e2e-retrofitskill; do not re-instantiate. - Not found → greenfield. Continue.
Step 1 — Clarify (one round, then proceed)
> HARD GATE — the target environment is a blocking prerequisite. Do not > proceed to Step 2 (or any scaffolding, install, or wiring) until the user has > given you a concrete app to point at and you have confirmed it is reachable. > The entire point of this skill is to wire the harness to a real running > app; without one there is nothing to wire, smoke-verify, or seed a matrix > from. If the repo has no app of its own (e.g. it's a library, a CLI, or this > skills repo itself), that does not license you to invent, scaffold, or > assume one — stop and ask which app/URL to target. Never guess the base > URL, never build a stand-in app unless the user explicitly asks for one. > Question 1 below is the gate; questions 2–5 can be inferred or deferred, but > question 1 cannot. > > The gate is cleared by exactly one thing: the user naming the target in the > current conversation. Nothing else counts. In particular: > - Ambient artifacts are not the user. A .playwright-mcp/ recon dump, an > existing COVERAGE.md draft, a half-written .env, prior-session logs, or a > URL in the git history tell you what was looked at once — not what the user > wants wired now. Inferring the target from these is the assumption the > gate forbids. If they make you confident, that is exactly when to ask the user > to confirm, not when to skip asking. Treating them as the answer is a gate > bypass even if they turn out to be right. > - Confidence does not collapse the gate. "I'm sure I know the target" is not > a license to proceed — a hard gate holds regardless of how certain you feel. > If you were uncertain you would ask anyway; being certain changes nothing. > - A reachability check is already proceeding. Do not curl, browser_navigate, > or otherwise probe a candidate URL to "confirm" it before the user has named it. > Probing a guessed URL is acting on the guess. Reachability is verified after > the user gives the target (Step 1, Q1), never as a way to validate a hunch first. > > If you catch yourself reasoning "the user clearly reconned X" or "the draft > points at X, so I'll just verify it" — stop. That is the bypass. Ask.
Ask only what you can't infer from the repo:
- Target environment (REQUIRED — gate) — tests need a running app to point at. Either:
- Local: the app + API base URLs (e.g.
http://localhost:3000) and the$DEV_UPcommand that starts services (npm run dev,docker compose up,make dev, …); or - Running staging/remote: the base URL of an already-running shared env to target instead.
At least one must be reachable. If only a remote env is available, there's no $DEV_UP — point .env at it. Confirm the base URL actually responds before continuing (a quick reachability check, or have the user start $DEV_UP). If you can't get a reachable target, do not scaffold — report that setup is blocked on a target environment.
- Auth model — dev auto-login (navigating to
/lands you in), or a real login form? Where do test-user credentials live? Any HTTP basic-auth on remote/QA? (No auth at all is fine — wire the auth helper to a bare navigate.) - e2e directory — default
e2e/at repo root. Confirm or override. - Targets — local only, remote/staging only, or both?
- Tooling (optional) — issue tracker + code host CLIs present (for retrofit later)? Note but don't block; both are optional.
Step 2 — Instantiate the harness
> Precondition: Step 1's gate is cleared — you have a concrete, reachable target environment. If not, go back; do not scaffold against an unknown app.
Path placeholders used below: **`** = this skill's folder, .claude/skills/e2e-setup (under whichever .claude/skills/ dir it's installed in — resolve it before copying). **** = the target repo root (git rev-parse --show-toplevel`).
Copy the bundled scaffold into the project's e2e dir:
cp -R /harness /e2e # e.g. cp -R .claude/skills/e2e-setup/harness ./e2e
This is a template — every file gets adapted or replaced (Steps 5–6). It is not run from the skill folder.
Step 3 — Install the test runner
Prerequisite: Node ≥ 18 and npm on PATH (node -v). If the repo isn't a JS project, Node still has to be installed for the e2e suite to run.
cd /e2e
npm install
npx playwright install chromium # browser binaries — without this nothing runs
Step 4 — Register the Playwright MCP
The recon in Step 5 (and later in retrofit Phase 2) drives a browser via the Playwright MCP — the mcp__playwright__browser_* tools. It's a Claude Code MCP server, registered once globally, not shipped in the repo.
claude mcp add playwright -s user -- npx @playwright/mcp@latest
Equivalent ~/.claude.json entry under top-level mcpServers:
"playwright": { "type": "stdio", "command": "npx", "args": ["@playwright/mcp@latest"], "env": {} }
Project-scoped alternative (shareable via a committed .mcp.json at the repo root — not inside e2e/, where Claude Code won't read it):
{ "mcpServers": { "playwright": { "type": "stdio", "command": "npx", "args": ["@playwright/mcp@latest"] } } }
Then:
- Verify —
/mcplistsplaywrightconnected andmcp__playwright__browser_*tools are available. - Gitignore the MCP output —
.playwright-mcp/(snapshots/console/network dumps; can contain real app data — keep it out of the repo) and*/.playwright-cli/. The bundledharness/.gitignorecovers the e2e dir, but the MCP writes to the directory Claude Code runs from — usually the repo root — so add.playwright-mcp/to the repo-root.gitignoretoo (not conditional).
Step 5 — Wire the harness to the real app (the actual work)
The harness ships generic widget/collection examples. Adapt the infrastructure edges to the real app — use MCP recon to discover the truth rather than guessing. Authenticate the recon browser first: it's a fresh session that does NOT inherit storageState, so browser_navigate to the base URL (dev auto-login) or drive the login form once.
Discover and wire:
helpers/urls.ts— realBASE_URL/API_BASE_URLand the id-from-route shape.helpers/auth.ts— the real login flow + selectors (or confirm dev auto-login). UpdateformLogin/devAutoLogin(replace the placeholderwaitForURL('**/**')with a real post-login assertion).helpers/api.ts— the real API login/token endpoint inloginApi, and replace thewidget/collectionseed helpers + response predicates with one real entity wired just enough to prove the client works (login → create → get → delete), exercised by the smoke test below, not by a feature spec. This proves the seeding infrastructure is sound; building feature coverage on top of it ise2e-retrofit's job. (No API? Deleteapi.tsand drop its.envvars.)tests/smoke.spec.ts— wire the reachability check (the example pings/api/health) to a real endpoint for your API, and the page-loads test to a real page. Keep smoke dead simple — it is a reachability gate, not a feature test. Three cheap assertions are the target: the app loads, one real page renders (assert a stable heading/landmark), and the API responds. Prefer a directpage.goto('/some-page')over clicking through nav — and if any interaction turns flaky (consent/cookie overlays, ad scripts, async timing on a third-party or heavy app), do not fight it: drop to the simplest assertion that proves the page renders. Resist adding waits, retries, multi-step flows, or overlay-dismissal gymnastics here; that complexity belongs in reale2e-retrofitspecs, not the smoke gate. This is the success gate in Step 7.helpers/db.ts.example— only if a test needs to read state the API doesn't expose: rename todb.tsandnpm i -D pg @types/pg(or your driver). Otherwise leave it as.example(it isn't compiled) and drop theDB_*vars from.env.README.md— the copied harnessREADME.mddocuments the demowidget/collectiondomain. Repoint it to the real app (target URL, auth + API model, layout) or delete it — don't ship a README describing entities the project no longer contains. (Step 6 treatsREADME.mdas the home for app prose, so leaving it stale contradicts that.fixtures/README.mdis generic — leave it.)- Follow
../e2e-retrofit/patterns.md§2 (selectors) and §3–4 (assertions) while wiring, so the seed is canonical from day one.
Delete every example feature spec (tests/widgets/, tests/collections/ — the CRUD + Manage demos) and any example helper you didn't wire. Setup writes no feature tests — smoke.spec.ts is the only spec left in the project. The harness's example specs remain in the e2e-setup skill folder (harness/tests/) as the pattern reference e2e-retrofit's first batch mirrors; they are not shipped into the project.
Step 6 — Scaffold the coverage matrix (gated choice)
Step 2 copied an example COVERAGE.md (the demo widgets/collections matrix). Its demo content must be replaced, but how is the user's call — this is a hard gate, ask before touching the file:
> GATE — ask the user, don't assume: > (a) Seed from observation — I recon the app's nav and enumerate the real sections + workflows as matrix rows (unchecked), or > (b) Blank template — I leave an empty matrix skeleton (headers, legend, env columns, one commented example row) for you to fill in yourself.
Then, whichever they pick:
- Every row stays
[ ](not covered) in both modes. Setup writes no feature tests, so nothing is covered yet — marking a row[x]would claim coverage that doesn't exist. The matrix is the work-list, not a result. - Match the env columns to the real targets. The demo ships Local + Remote columns; a single-target app (remote-only or local-only) gets one
Coveredcolumn. Don't carry a column for a target that doesn't exist — collapse the matrix (and the Coverage Summary) to the targets the suite actually runs against. - It's a tracker, not docs. Keep the file to the matrix + legend. Don't add prose describing the app, its architecture, the environment ("static page, no API, no login"), or how a feature behaves — that belongs in the e2e
README.mdor a spec comment, not the coverage file. - Mode (a) — seeded from observation: populate
### {Section}blocks + workflow rows from recon, keeping the file's format (priority-tagged rows, env columns, legend, summary). **Recon tells you what the app does, not what matters or what's correct — so treat the section taxonomy and especially the priority labels as proposed, flagged for the user to confirm/correct**, not as authoritative fact. Don't manufacture a coverage-summary percentage. - Mode (b) — blank: strip all demo rows; leave the headers, legend, env columns, and a single commented example row showing the row shape.
This file is the $COVERAGE_MATRIX — the work-list every later retrofit batch scopes from.
Step 7 — Verify
Make sure a target environment is running and reachable first — either start local services ($DEV_UP) or point .env at an already-running staging/remote env. Confirm the base URL responds before running specs.
cd /e2e
cp .env.example .env # then fill: E2E_TARGET, BASE_URL/API_BASE_URL, test user
# ensure the target env is up — `$DEV_UP` for local, or a reachable staging URL — then:
npx playwright test smoke.spec.ts # app loads + login works + API reachable
Note: smoke.spec.ts runs in the authenticated project, so it exercises the full auth path (Step 5 wiring) before its assertions — it's a real end-to-end check, not a bare ping. A green smoke run is the whole success gate — it's the only spec setup writes. (There are no leftover example specs to ignore; Step 5 deleted them.) Always run from the e2e dir, never the repo root (../e2e-retrofit/patterns.md §11).
Step 8 — Commit and hand off
- Commit the scaffold — scope the commit to the e2e dir (plus the repo-root
.gitignorechange from Step 4); no secrets (.env,.auth/,.playwright-mcp/stay gitignored). If the repo has no initial commit yet, or unrelated staged/dirty changes, do not sweep them into the setup commit: do a scopedgit addcommit, or — when scoping is ambiguous — hand the diff to the user to commit rather than bundling. (Setup is the only step that commits a scaffold; branch/PR handling ise2e-retrofit's job.) - Report what was wired (entity, auth mode, targets), the smoke result, the coverage-matrix mode chosen (seeded vs blank), and — explicitly — that no feature specs were written (that's the next step's job).
- Tell the user: setup is complete — from here use the
e2e-retrofitskill ("retrofit e2e tests for {ticket}"), which writes the actual feature coverage one section at a time. This skill should not be run again on this repo.
Done-when checklist
- [ ]
e2e/exists withplaywright.config.ts;npx playwright test --listparses;npx tsc --noEmitis clean. - [ ] Playwright MCP connected and verified.
- [ ]
helpers/wired to the real app; if there's an API, one real entity seeds + reads + cleans up (proven via smoke, not a feature spec). - [ ] Exactly one spec exists —
smoke.spec.ts. All example feature specs (CRUD/Manage) deleted; no feature tests written. - [ ]
README.mdrepointed to the real app or deleted — no leftoverwidget/collectiondemo prose. - [ ]
COVERAGE.mdscaffolded per the user's gated choice (seeded-from-recon or blank); no rows marked[x]; priorities/sections flagged as proposed if seeded. - [ ]
smoke.spec.tsgreen against the target env (local or staging/remote). - [ ]
.envpopulated (gitignored);.playwright-mcp/gitignored. - [ ] Scaffold committed; user handed off to
e2e-retrofit.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: cakehurstryan
- Source: cakehurstryan/QE-Skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.