Puppeteer E2E Tester Skill
This repo uses Puppeteer (via the Puppeteer MCP server, see .vscode/mcp.json) for true browser-driven E2E tests, distinct from Vitest/RTL component tests (DOM-only, no real browser) and Playwright (if also present, used for cross-browser suites).
When to use Puppeteer vs RTL
- RTL (
test-writer-vitest-rtlskill): component-level, fast, no real browser — use for most logic/UI tests. - Puppeteer: full user flows that cross multiple pages/routes, need a real rendered browser (visual checks, real navigation, third-party scripts, file uploads, console-error detection), or are explicitly requested as "E2E"/"browser test".
Process
- Identify the user flow to test (e.g. "sign up → verify email → land on dashboard").
- Create the test file under
e2e/puppeteer/<flow-name>.e2e.tsusing e2e-test-template.ts. - Always:
- Wait for elements via
page.waitForSelector(or better, accessible role-based queries if usingpuppeteer-testing-library) — neverpage.waitForTimeoutas a substitute for a real wait condition. - Assert on visible outcomes (URL changed, text appeared, element state) not implementation details.
- Capture and assert there are no unexpected
console.errorcalls during the flow (see template's console listener).
- Wait for elements via
- For forms, fill via
page.type/page.clickon labeled, role-queryable elements — coordinate with theaccessibility-auditoragent if elements aren't queryable, since that's usually also an a11y gap. - Run with
pnpm test:e2e:puppeteerand confirm pass/fail before reporting done. - Take a screenshot on failure (
page.screenshot) to aid debugging — see template.
Checklist
- Test targets a real user flow, not an implementation detail
- No
waitForTimeoutused as a wait strategy - Console errors during the flow are captured and asserted on
- Screenshot-on-failure configured
- Test is independent (doesn't depend on state left by another test)