From johnfink-skills
Use when (a) authoring a new e2e/browser test (selector choice, set-up strategy, what to assert), (b) investigating a flaky test, (c) deciding whether e2e is the right tier for a behavior (vs. unit/integration), (d) reviewing existing e2e tests for design issues, or (e) anyone is about to reach for `sleep` / `waitForTimeout` / `--retries=3` (which is always wrong). NOT needed for minor edits to existing well-shaped e2e tests — load only when an e2e design decision or flake investigation is on the table.
How this skill is triggered — by the user, by Claude, or both
Slash command
/johnfink-skills:e2e-testingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **Draft — first poke.** Edit the rules below to match what you actually want.
Draft — first poke. Edit the rules below to match what you actually want.
E2E tests are the most valuable tests when they pass and the most expensive tests when they fail. Discipline matters more here than in any other tier.
The pyramid is real. E2E covers the seams between layers — auth flow, payment flow, the single critical user journey. It does NOT cover "every form validates correctly" — that's a unit/integration test. If you find yourself writing the 7th e2e test for a CRUD page, stop.
Default: a small e2e suite (single digits of tests for a small app, low double-digits for a big one) covering the journeys you'd ship-block on.
In priority order:
data-testid="checkout-submit" — stable, intentional, survives styling changes.getByRole("button", { name: "Check out" }) — accessible, semi-stable.getByText("Check out") — readable but breaks on copy changes.If you reach for a CSS selector, first ask: should this element have a testid?
sleep, everpage.waitForTimeout(2000) is always wrong. It's either too long (slow tests) or too short (flake). Use the framework's auto-waiting (expect(locator).toBeVisible(), waitForResponse, waitForURL). If something truly has no observable change to wait for, that's a product bug — fix the product, not the test.
Don't share user accounts, fixtures, or DB state across tests. Each test creates what it needs (via API, not UI — see #5) and uses a unique identifier. Otherwise: test order matters → flake → suite-wide pin.
E2E tests are slow. Don't burn 30 seconds clicking through signup + onboarding just to test the dashboard. Hit the API to create the user in a logged-in state, then goto("/dashboard") and start exercising.
The only thing you should test through the UI is the thing under test.
A flaky test is worse than no test — it teaches the team to ignore failures. When a test flakes:
--repeat-each=20.Never --retries=3 to hide a flake. Never skip a flaky test "for now." Either fix it or delete it.
test_user_can_complete_checkout_with_saved_card, not test_checkout_3. The name should let an oncall page-reader know what broke without opening the file.
Run in headed mode (with the browser visible) when authoring or debugging — you see what the test sees. Run headless in CI. If a test passes headless and fails headed (or vice versa), that's a real signal, not a quirk to work around.
Configure the runner to capture screenshot + trace + video on failure. The "it failed in CI but I can't reproduce" loop ends when you can replay the failed run.
npx claudepluginhub johnfink8/skill-repo --plugin johnfink-skillsProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.