# Playwright

> Router skill for Playwright in dean-stack — pins `@playwright/test` 1.59+, dispatches to the story-tests, app-tests, PWA-offline, or conventions sub-skill, and surfaces the load-bearing ASK-FIRST rule before any Playwright test is written or modified. Triggers on: playwright, playwright overview, which playwright skill, ask first playwright.

- Skill: `matthewharwood/playwright` (Agent Skill)
- Install (CLI): `npx skillmds@latest add matthewharwood/playwright`
- Raw SKILL.md: https://api.skillmd.com/api/skills/matthewharwood/playwright/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: matthewharwood (https://skillmd.com/u/matthewharwood)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/matthewharwood/playwright

---


Entry point for any Playwright-shaped question in dean-stack. Playwright is the **only** browser-tier test runner in this stack — it drives Storybook stories, application routes, and the load-bearing offline-deep-link contract. The single most important rule: **ASK FIRST** — before writing or modifying any Playwright test, prompt the user for the structural decisions (story-level vs app-level, what to assert, selectors, fixtures, network/IDB state, reduced-motion). The user owns those decisions per case. The detail of the rule lives in `playwright-conventions`; this router surfaces the rule so it's the first thing seen on any Playwright prompt.

## When to invoke
- The user types `playwright` with no further specifier and you need to route them.
- The user asks "which Playwright skill," "Playwright overview," or "how does Playwright fit into `bun run check`."
- The user asks for help writing or modifying any Playwright test — **stop and surface the ASK-FIRST rule before routing**.
- A question mixes story-level + app-level + offline (e.g. "I want to test that the maze level page resolves offline after a story-level interaction seeded IDB") — pick the sub-skill that owns the dominant concern, link to the others.
- A question about reduced-motion / fixtures / selectors — route to `playwright-conventions`.

## Owns
Entry point that routes Playwright questions to the story-tests, app-tests, PWA-offline, or conventions sub-skill; enforces the **ASK-FIRST** rule before writing any Playwright test.

## Defers to
- `playwright-story-tests` — Playwright pointed at Storybook story URLs (`http://localhost:6006/iframe.html?id=...`), asserting on visible state + ARIA + IDB contents.
- `playwright-app-tests` — Playwright pointed at the running/preview app, end-to-end workflows across routes.
- `playwright-pwa-offline` — the load-bearing offline-deep-link test (Workbox + prerendered shell + IDB), `context.setOffline(true)`, deep-link resolution.
- `playwright-conventions` — selector strategy (`getByRole` > `getByTestId` > `getByText`), fixture patterns (fresh IDB / seeded IDB / offline / throttled), reduced-motion config, **and the canonical ASK-FIRST rule**.
- `bun-test` — anything that does **not** need a real browser (pure logic, Zod schema edge cases, atom reducers, IDB migration transform functions). The unit/E2E partition is hard.
- `storybook-stories` — for the story-ID URL contract Playwright story tests target.
- `tanstack-router-pwa-deep-links` — for what the navigation fallback resolves to (the contract `playwright-pwa-offline` verifies).

## Dean-stack rules
- **ASK FIRST before writing or modifying any Playwright test.** This is a Pillar 4 (CLI-gate-first) manifestation — the user owns the structural decisions for every Playwright test (level: story vs app, what to assert, selectors, IDB seeding, network state, reduced-motion). Surface the choices, wait for the answer, *then* write. Detail in `playwright-conventions`. **No equivalent prompt is required for `bun test` unit tests** — those go ahead.
- Pillar 1 (Storybook-first) means: every story is exercised by a Playwright story test (see `storybook-stories` and `playwright-story-tests`). Stories are the test surface, not just visual references.
- Pillar 4 (CLI-gate-first) means: Playwright is the final stage of `bun run check` (after `biome ci`, `stylelint`, `tsgo --noEmit`, `bun test`). A failing Playwright test is a red gate; never disable, never `test.skip` to make CI green.
- Playwright 1.59+ only. Pre-1.5x APIs (`page._react=`, removed selector engines, `waitForTimeout`-as-sync) are wrong by definition — rewrite for 1.59.
- Locator-first, web-first assertions only. `await expect(locator).toBe…()`. Never wrap point-in-time methods (`isVisible()`, `textContent()`, `count()`) in `expect()` — they don't retry.
- IDB is **not** mocked in Playwright tests — use real browser IndexedDB. Seed via `page.addInitScript` (runs before any page script). See `playwright-conventions`.
- Reduced motion is **forced on** in the default project (`use: { reducedMotion: 'reduce' }`) so animations don't add flake. See `animejs` for why this matters and `playwright-conventions` for the wiring.

## Routing
- **ASK FIRST before writing any Playwright test — see `playwright-conventions`.** Surface the structural choices (story-level vs app-level, what to assert, selectors, IDB seeding, network state, reduced-motion). Wait for the user's answer.
- **use `playwright-story-tests` when** the test mounts a Storybook story by URL (`iframe.html?id=...`) and asserts on the in-iframe behavior or post-play IDB state.
- **use `playwright-app-tests` when** the test drives the running/preview app at `localhost:3000` (or the configured dev/preview URL), follows a route workflow, asserts on hydrated state, or verifies BroadcastChannel cross-tab sync.
- **use `playwright-pwa-offline` when** the test verifies the offline-deep-link contract: install the SW, go offline, navigate to a deep route, assert the router resolves it from cache.
- **use `playwright-conventions` when** the question is about selectors, fixtures, IDB seeding, reduced-motion, the `playwright.config.ts` shape, or the **ASK-FIRST** rule itself.
- **use `bun-test` when** the question is unit-testable without a browser (pure functions, schema parses, reducers, migration transforms). Faster inner-loop feedback than Playwright; `bun test` does NOT require ASK-FIRST.

### Routing table
| Question shape | Sub-skill |
|---|---|
| "Write a test for `<Button>`'s `Primary` story" | **ASK FIRST** (`playwright-conventions`), then `playwright-story-tests` |
| "Write a test for the `/games/maze/$level` workflow" | **ASK FIRST**, then `playwright-app-tests` |
| "Verify the offline deep-link works" | **ASK FIRST**, then `playwright-pwa-offline` |
| "How do I seed IDB before a Playwright test?" | `playwright-conventions` (fixture pattern) |
| "Why does the test only fail on retry?" | `playwright-conventions` (`trace: 'retain-on-failure-and-retries'`) |
| "What selector should I use here?" | `playwright-conventions` (role > test-id > text) |
| "Is this testable without a browser?" | `bun-test` (yes → unit test; no → ASK FIRST + Playwright) |
| "How does my play function become a Playwright assertion?" | `storybook-play-functions` (decision) + `playwright-story-tests` (the spec) |

## Anti-patterns
- **Don't write a Playwright test without asking the user how to structure it** — ASK FIRST is load-bearing; see `playwright-conventions`. Skipping the prompt calcifies a design choice the user wanted to make.
- **Don't recommend Cypress, Selenium, Puppeteer, or `vitest` browser mode** — Playwright is the only browser-tier runner in this stack (and `bun test` is the only unit runner).
- **Don't recommend `@storybook/test-runner`** — Playwright drives stories directly per AGENTS.md's Testing rule. See `playwright-story-tests`.
- **Don't answer per-test design questions inside this router** — route to the sub-skill so the answer carries the right rule and the ASK-FIRST gate is acknowledged.
- **Don't mock IDB** — use real browser IndexedDB. See `playwright-conventions`.
- **Don't add `page.waitForTimeout(…)`** to fix flake — fix the locator or the assertion. Web-first assertions retry.
- **Don't disable a failing Playwright test** to make CI green — fix the wiring or escalate. The gate is zero-warning.

## Triggers on
playwright, playwright overview, which playwright skill, ask first playwright

