plugins/testing-e2e/skills-codex/testing-e2e/SKILL.md
Sequential E2E workflow — identify test targets, generate Playwright test scripts written to /tmp, run them with node, capture failures, fix and re-run until passing. Supports TypeScript tests and Go/HTMX applications.
npx skillsauth add alexei-led/claude-code-config testing-e2eInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Generate and run end-to-end tests using Playwright. Work through the steps sequentially. Keep going after failures — read the error, fix the script, and re-run until all tests pass.
Check $ARGUMENTS:
run — run existing E2E tests in the projectrecord — generate a script that launches a visible browser for recordinggenerate <description> — generate a new test for the described flowverify <feature> — verify a specific feature works end-to-endWait for their answer if nothing was supplied.
Use Glob and Read to understand what already exists. Do not assume. Any E2E workflow or generated-test plan must explicitly include dev-server detection/startup and deterministic test data setup before browser actions.
Look for:
**/*.spec.ts, **/*.test.ts, **/e2e/**playwright.config.ts or playwright.config.js — read it to understand base URLs, timeouts, projects, traces, screenshots, and webServer settingspackage.json scripts (dev, start, serve) or project docsNote the base URL the app runs on. Detect whether the dev server is already reachable; if tests require a server and none is running, start the documented command or report the blocker. Note whether Playwright is already installed (node_modules/@playwright/test).
Use deterministic fixtures: seeded users, fixed dates, stable IDs, known database state, reset commands, and mocked external services where needed. Do not depend on production data, random order, wall-clock time, or previous test runs.
npx playwright test --reporter=list 2>&1
For a specific file:
npx playwright test <path-to-spec> --reporter=list 2>&1
If Playwright is not installed, install it first:
npm install --save-dev @playwright/test && npx playwright install chromium
For manual flows, first define deterministic fixtures such as seeded users/items/coupons, fixed dates, stable IDs, reset database state, and mocked external services where needed. Then translate each manual step into Playwright actions and observable assertions.
Write a Playwright test script to /tmp/e2e-<name>.spec.ts. Use this structure:
import { test, expect } from "@playwright/test";
test("<description of what is verified>", async ({ page }) => {
await page.goto("http://localhost:<port>");
// Navigate and interact using semantic locators
await page.getByRole("button", { name: "Submit" }).click();
await page.waitForURL("**/success");
// Assert outcomes
await expect(page.getByRole("heading", { name: "Done" })).toBeVisible();
});
Locator rules — always prefer in this order:
getByRole — accessible role + namegetByLabel — form labelgetByText — visible textgetByTestId — data-testid attributeNever use fixed waitForTimeout delays. Use waitForSelector, waitForURL, or waitForLoadState instead.
For HTMX applications, verify partial page updates explicitly:
hx-swap results by checking the updated DOM region, not the full pageWrite a recording script to /tmp/e2e-record.js:
const { chromium } = require("playwright");
(async () => {
const browser = await chromium.launch({ headless: false, slowMo: 100 });
const page = await browser.newPage();
await page.goto("http://localhost:<port>");
// Browser stays open — user interacts manually
// Close the browser window to end the session
await page.waitForEvent("close", { timeout: 300000 });
await browser.close();
})();
Run it:
cd ~/.claude/skills/playwright-skill && node /tmp/e2e-record.js
Save the resulting test, screenshots, trace, or notes as artifacts when useful.
Write a focused verification script to /tmp/e2e-verify-<feature>.spec.ts that:
cd ~/.claude/skills/playwright-skill && node run.js /tmp/e2e-<name>.spec.ts 2>&1
Or if running from the project root with a config:
npx playwright test /tmp/e2e-<name>.spec.ts --reporter=list 2>&1
Read the full output. Note which assertions failed and on which line.
For each failure, diagnose before editing:
| Failure type | Likely cause | Fix |
| ----------------- | -------------------------------------- | ----------------------------------------------- |
| Locator not found | Selector doesn't match DOM | Use accessible role/label instead of CSS class |
| Timeout | Element not visible or action too slow | Add waitForSelector or waitForLoadState |
| Wrong assertion | Page state differs from expectation | Read the actual page state and update assertion |
| Navigation error | Wrong URL or server not running | Verify base URL and that dev server is up |
Fix the script, re-run, and repeat until all tests pass. Do not declare done with failing tests. Preserve failure evidence with Playwright traces, screenshots, videos, or HTML reports when available.
Always report PASS/FAIL/BLOCKED, dev server status, fixture/reset summary, test results, and artifact paths for traces/screenshots/videos/reports when relevant. If tests were not run, report BLOCKED or explain exactly why; do not imply success.
E2E TESTING
===========
Action: <run|generate|record|verify>
Result: PASS | FAIL | BLOCKED
Tests written: <count>
Pass: <count>
Fail: <count>
Dev server: <reused|started|not needed|blocked: reason>
Fixtures: <deterministic data/reset summary>
Artifacts: <trace/screenshots/videos/report paths or none>
Results:
- <test name>: PASS
- <test name>: FAIL — <brief reason>
Coverage added:
- <user flow now tested>
Next steps:
- <additional flows worth testing>
tools
Idiomatic shell development for POSIX sh, Bash, Zsh, Fish, hooks, CI shell steps, and scriptable CLI glue. Use when writing or changing `.sh`, `.bash`, `.zsh`, `.fish`, `.bats`, shell functions, shell pipelines, or command-runner recipes. Emphasizes portability, quoting, safe filesystem/process handling, non-TUI CLI tools, ShellCheck, shfmt, Bats, and ShellSpec. NOT for Python, TypeScript, Go, web code, or infrastructure operations.
tools
Use when planning, executing, checkpointing, finishing, or inspecting lightweight spec-driven work. Runs one task at a time using `.spec/` markdown files and the bundled `specctl` helper. NOT for broad product discovery beyond a short requirement interview.
testing
Author, inspect, troubleshoot, and review infrastructure across IaC, Kubernetes, cloud resources, containers, CI/CD, and Linux hosts. Use when changing Terraform/OpenTofu, Kubernetes, Helm, Kustomize, Dockerfiles, GitHub Actions, AWS, GCP, Cloud Run, BigQuery, IAM, logs, instances, or service health. NOT for deploy/apply/rollback workflows (see deploying-infra). NOT for shell scripts or generic command pipelines (see writing-shell).
development
Configure safe git workflow hygiene: pre-commit/pre-push hooks, Gitleaks secret scanning, .gitignore rules, local git config, and guardrails. Use when setting up git hooks, gitleaks/git leaks, staged pre-commit checks, pre-push validation, core.hooksPath, .gitignore, or git config best practices. NOT for creating commits (use committing-code), cleaning branches/worktrees (use cleanup-git), or creating worktrees (use using-git-worktrees).