← ClaudeAtlas

e2e-testinglisted

Write and run TypeScript end-to-end browser tests with Playwright that exercise real user journeys — signup/login, search, the booking flow, and Stripe checkout → confirmation. Use this skill whenever the user wants an e2e test, a browser test, to test a full flow "end to end", to catch regressions before deploy, or to verify the live site still works after a change. Trigger even on casual asks like "make sure booking still works in the browser" or "test the checkout flow".
Marcdaou/claude-qa-suite · ★ 0 · Testing & QA · score 70
Install: claude install-skill Marcdaou/claude-qa-suite
# TypeScript End-to-End Testing An e2e test proves the whole stack works together the way a user experiences it: the browser, the Next.js app, Supabase, and Stripe all in one flow. These are the tests that catch "the button does nothing" and "checkout 500s on deploy" — things unit and API tests miss. They're also the slowest and flakiest, so the craft is in writing flows that are *stable*: resilient selectors, explicit waits on state, and no reliance on timing. ## Setup If the project has no Playwright yet, scaffold it: ```bash bash ${CLAUDE_PLUGIN_ROOT}/scripts/e2e/scaffold.sh ``` This installs `@playwright/test`, drops a `playwright.config.ts` tuned for Next.js + Vercel preview URLs (reads `BASE_URL`, retries on CI, traces on first retry), and creates `e2e/` with a fixtures file. If Playwright already exists, skip the scaffold and just add specs under the existing test dir. ## Writing stable tests The difference between a test suite people trust and one they ignore is flakiness. Follow these because each one removes a class of flake: - **Select by role or test id, not CSS.** `getByRole('button', { name: /book now/i })` survives restyling; `.btn-primary-2` does not. Add `data-testid` to elements that have no accessible name. Selectors coupled to layout are the #1 source of flake. - **Wait on state, never on time.** Use web-first assertions (`await expect(page.getByText('Booking confirmed')).toBeVisible()`) which auto-retry. Never `waitForTimeout` — it's either