Playwright
Run browser-based E2E tests with visible Chrome, capture screenshots at each interaction point, and produce structured reports or interactive spot-check sessions.
Non-Negotiable Rules
- UI design and function validation is ALWAYS non-headless. When the task is validating what a user sees — layout, styling, responsiveness, real rendered content, or that interactions work — the browser must be visible (
headless: false). Headless runs are only acceptable as fast signal loops for pure logic (diagnose-loop Phase 1 recipes), never as evidence that a UI's design or function is correct.
- Never infer — observe. If a page's appearance or behavior is in question, load it in the browser and look. Never guess what a page shows from its source code, never assume a fix worked because tests passed, and never judge design from a headless screenshot. The rendered page is ground truth.
- No blind edits. Screenshots and reports document what exists; they do not authorize changing code without reading it. If a validation failure points at a component, read the component's actual source before concluding anything about it.
Two Modes
Report Mode (default)
Automated test execution that produces a timestamped run directory with screenshots, a structured JSON report, and a human-readable summary. Use this when running as part of qe-agent's integration phase, CI-adjacent verification, or any time you need a documented record of test results.
Spot-Check Mode
Interactive session where the user watches the visible browser and approves each step in real time. Triggered by "let me watch", "spot check", or "walk me through". Pause after each navigation or interaction, describe what's on screen, and wait for the user's go-ahead. Screenshots still land in the timestamped run directory. Full workflow in references/screenshot-workflow.md.
Setup
Before running any tests, verify Playwright is available. Read references/setup.md for the full installation and configuration flow.
Quick check:
# Check if Playwright is installed
npx playwright --version 2>/dev/null || echo "NOT_INSTALLED"
If not installed, install it along with the Chromium browser:
npm init -y 2>/dev/null # ensure package.json exists
npm install -D @playwright/test
npx playwright install chromium
Capture Bounds
Screenshot cost scales with page height, not viewport size, and a long page will exhaust system memory before anything warns you. Measure before you capture:
const h = await page.evaluate(() => document.documentElement.scrollHeight)
Then apply these rules:
- Under ~8,000px —
fullPage: true is fine.
- Over ~8,000px — do not use
fullPage. Scroll in viewport-sized tiles and capture each one. A list page can be 30,000–50,000px tall; at 1280px wide, 31,000px decodes to ~150 MB of raw RGBA per image.
- Reuse one page per viewport. Never create a browser context per screenshot — contexts are spawned faster than they are reclaimed.
- Never hold more than one decoded image pair. Pixel-diffing (
pixelmatch, odiff) needs uncompressed RGBA: two inputs plus an output buffer is three copies. On a 31,000px page that is ~460 MB for a single comparison.
- Capture first, diff in a second pass, freeing each buffer as you go.
Sampling beats exhaustiveness on very long pages: comparing at 25%, 50%, 75%, and bottom catches real regressions at a fraction of the cost. Bound the run before launching it — the failure mode is a stalled machine and lost user work, not a clean error.
Workflow
Determine what to test. Translate inputs (plan excerpt, acceptance criteria, user request) into a list of user flows. See references/selectors-guide.md for how to structure each flow as navigate → interact → assert → screenshot.
Write the test script in non-headless Chromium so screenshots show the real rendered UI. See references/selectors-guide.md for the standard test.use({ headless: false }) block, key patterns (waitForLoadState('networkidle'), descriptive screenshot names, multi-viewport runs), and the accessibility quick-check snippet.
Execute the run. The standard RUN_ID=$(date +%Y-%m-%d_%H-%M-%S) command for both @playwright/test runner and standalone npx tsx execution is in references/selectors-guide.md.
Lay out the outputs. Everything from a run lives under a single gitignored root: .playwright/<run-id>/, with screenshots/ (PNGs) and results/ (traces, raw JSON, logs, the test script) beneath it. One root keeps a project's working tree from sprouting playwright-screenshots/, playwright-results/, .playwright-mcp/, and test-results/ side by side. See references/screenshot-workflow.md for the exact directory layout and naming convention.
Produce the report. Report mode emits two files at the run-dir top level: .playwright/<run-id>/report.json (structured) and report.md (human-readable). See references/screenshot-workflow.md for the exact JSON schema and markdown template.
Coordination with QE Agent
When spawned by qe-agent during Phase 2 (Integration Verification): qe-agent provides base URL + flows + acceptance criteria; you return the run-dir path (.playwright/<run-id>/) — its report.json plus the screenshots/ directory; qe-agent incorporates the findings into the overall QA report. Full handoff details — and standalone invocation — are in references/screenshot-workflow.md.
Troubleshooting
Common issues and fixes are in references/screenshot-workflow.md; the full troubleshooting guide is in references/setup.md. Quick checklist:
- "Browser closed unexpectedly" → missing system deps;
npx playwright install-deps chromium
- "Navigation timeout" → service isn't running; verify the URL first
- "No usable sandbox" (Linux) →
chromiumSandbox: false (non-production only)
- Blank screenshots → add
waitForLoadState('networkidle') before capture
- Machine stalls / swaps during a run →
fullPage on a very tall page, a context per screenshot, or a pixel-diff holding several decoded images. See "Capture Bounds" above and tile instead.
Reference Files
references/setup.md — installation and configuration
references/selectors-guide.md — test-script patterns, key Playwright idioms, accessibility quick-check, run commands
references/screenshot-workflow.md — directory layout, JSON + Markdown report formats, spot-check workflow, QE handoff, troubleshooting
1---2name: playwright3description: Run browser-based E2E tests, capture screenshots, and validate user flows using Playwright with visible Chrome. Use this skill when testing a web UI end-to-end, capturing screenshots for visual review, checking responsive layouts, or auditing accessibility in a real browser. Trigger on: "e2e test", "screenshot the UI", "click through the app", "responsive layout check", "accessibility audit". Also invoke when qe-agent needs browser-level integration testing.4---56# Playwright78Run browser-based E2E tests with visible Chrome, capture screenshots at each interaction point, and produce structured reports or interactive spot-check sessions.910## Non-Negotiable Rules1112- **UI design and function validation is ALWAYS non-headless.** When the task is validating what a user sees — layout, styling, responsiveness, real rendered content, or that interactions work — the browser must be visible (`headless: false`). Headless runs are only acceptable as fast signal loops for pure logic (diagnose-loop Phase 1 recipes), never as evidence that a UI's design or function is correct.13- **Never infer — observe.** If a page's appearance or behavior is in question, load it in the browser and look. Never guess what a page shows from its source code, never assume a fix worked because tests passed, and never judge design from a headless screenshot. The rendered page is ground truth.14- **No blind edits.** Screenshots and reports document what exists; they do not authorize changing code without reading it. If a validation failure points at a component, read the component's actual source before concluding anything about it.1516## Two Modes1718### Report Mode (default)1920Automated test execution that produces a timestamped run directory with screenshots, a structured JSON report, and a human-readable summary. Use this when running as part of qe-agent's integration phase, CI-adjacent verification, or any time you need a documented record of test results.2122### Spot-Check Mode2324Interactive session where the user watches the visible browser and approves each step in real time. Triggered by "let me watch", "spot check", or "walk me through". Pause after each navigation or interaction, describe what's on screen, and wait for the user's go-ahead. Screenshots still land in the timestamped run directory. Full workflow in `references/screenshot-workflow.md`.2526## Setup2728Before running any tests, verify Playwright is available. Read `references/setup.md` for the full installation and configuration flow.2930Quick check:3132```bash33# Check if Playwright is installed34npx playwright --version 2>/dev/null || echo "NOT_INSTALLED"35```3637If not installed, install it along with the Chromium browser:3839```bash40npm init -y 2>/dev/null # ensure package.json exists41npm install -D @playwright/test42npx playwright install chromium43```4445## Capture Bounds4647Screenshot cost scales with page *height*, not viewport size, and a long page will exhaust system memory before anything warns you. **Measure before you capture:**4849```js50const h = await page.evaluate(() => document.documentElement.scrollHeight)51```5253Then apply these rules:5455- **Under ~8,000px** — `fullPage: true` is fine.56- **Over ~8,000px** — do **not** use `fullPage`. Scroll in viewport-sized tiles and capture each one. A list page can be 30,000–50,000px tall; at 1280px wide, 31,000px decodes to ~150 MB of raw RGBA per image.57- **Reuse one page per viewport.** Never create a browser context per screenshot — contexts are spawned faster than they are reclaimed.58- **Never hold more than one decoded image pair.** Pixel-diffing (`pixelmatch`, `odiff`) needs uncompressed RGBA: two inputs plus an output buffer is *three* copies. On a 31,000px page that is ~460 MB for a single comparison.59- **Capture first, diff in a second pass**, freeing each buffer as you go.6061Sampling beats exhaustiveness on very long pages: comparing at 25%, 50%, 75%, and bottom catches real regressions at a fraction of the cost. Bound the run before launching it — the failure mode is a stalled machine and lost user work, not a clean error.6263## Workflow64651. **Determine what to test.** Translate inputs (plan excerpt, acceptance criteria, user request) into a list of user flows. See `references/selectors-guide.md` for how to structure each flow as navigate → interact → assert → screenshot.66672. **Write the test script** in non-headless Chromium so screenshots show the real rendered UI. See `references/selectors-guide.md` for the standard `test.use({ headless: false })` block, key patterns (`waitForLoadState('networkidle')`, descriptive screenshot names, multi-viewport runs), and the accessibility quick-check snippet.68693. **Execute the run.** The standard `RUN_ID=$(date +%Y-%m-%d_%H-%M-%S)` command for both `@playwright/test` runner and standalone `npx tsx` execution is in `references/selectors-guide.md`.70714. **Lay out the outputs.** Everything from a run lives under a single gitignored root: `.playwright/<run-id>/`, with `screenshots/` (PNGs) and `results/` (traces, raw JSON, logs, the test script) beneath it. One root keeps a project's working tree from sprouting `playwright-screenshots/`, `playwright-results/`, `.playwright-mcp/`, and `test-results/` side by side. See `references/screenshot-workflow.md` for the exact directory layout and naming convention.72735. **Produce the report.** Report mode emits two files at the run-dir top level: `.playwright/<run-id>/report.json` (structured) and `report.md` (human-readable). See `references/screenshot-workflow.md` for the exact JSON schema and markdown template.7475## Coordination with QE Agent7677When spawned by qe-agent during Phase 2 (Integration Verification): qe-agent provides base URL + flows + acceptance criteria; you return the run-dir path (`.playwright/<run-id>/`) — its `report.json` plus the `screenshots/` directory; qe-agent incorporates the findings into the overall QA report. Full handoff details — and standalone invocation — are in `references/screenshot-workflow.md`.7879## Troubleshooting8081Common issues and fixes are in `references/screenshot-workflow.md`; the full troubleshooting guide is in `references/setup.md`. Quick checklist:8283- "Browser closed unexpectedly" → missing system deps; `npx playwright install-deps chromium`84- "Navigation timeout" → service isn't running; verify the URL first85- "No usable sandbox" (Linux) → `chromiumSandbox: false` (non-production only)86- Blank screenshots → add `waitForLoadState('networkidle')` before capture87- Machine stalls / swaps during a run → `fullPage` on a very tall page, a context per screenshot, or a pixel-diff holding several decoded images. See "Capture Bounds" above and tile instead.8889## Reference Files9091- `references/setup.md` — installation and configuration92- `references/selectors-guide.md` — test-script patterns, key Playwright idioms, accessibility quick-check, run commands93- `references/screenshot-workflow.md` — directory layout, JSON + Markdown report formats, spot-check workflow, QE handoff, troubleshooting