QA Playwright TypeScript Writer
Purpose
Write Playwright tests (E2E, component, unit) from test case specifications. Transform structured test cases into executable Playwright test files with auto-waiting, multi-browser support, Page Object Model, and optional live browser record mode.
Trigger Phrases
- "Write Playwright tests for [feature/flow]"
- "Generate E2E tests from test cases"
- "Create Playwright tests with record mode"
- "Add Playwright component tests for [component]"
- "Playwright tests for [URL/flow]"
- "Record browser interactions and generate test code"
- "POM-based Playwright tests for [page]"
- "Multi-browser Playwright tests"
- "Heal my failing Playwright tests"
Three Modes
| Mode |
When to Use |
Behavior |
| Record Mode |
User wants live browser capture |
Use Playwright MCP (e.g., cursor-ide-browser) → navigate, interact, capture interactions → generate test code from recorded steps |
| Generate Mode |
Default; from test case specs |
Read test cases (from qa-testcase-from-docs, qa-testcase-from-ui, qa-manual-test-designer) → generate Playwright code |
| Heal Mode |
Tests fail after changes |
Delegate to qa-test-healer to auto-fix broken selectors, assertions, waits; mark unfixable as test.fixme() |
Test Types
| Type |
Scope |
Approach |
| E2E |
Full user flows, page navigation |
page.goto, locators, assertions, network interception, multi-browser |
| Component |
Isolated component testing |
@playwright/experimental-ct-react, ct-vue, ct-svelte; mount, interact, assert |
| Unit |
Pure functions, utilities |
Use test runner for logic; Playwright optional for DOM utilities |
E2E Testing
- Navigation: page.goto, page.goBack, page.reload
- Interactions: click, fill, selectOption, check, hover, press
- Assertions: expect(locator).toBeVisible, toHaveText, toHaveURL, etc.
- Network: page.route for API mocking, request/response interception
- Multi-browser: Chromium, Firefox, WebKit via projects in config
- Auto-wait: Playwright auto-waits for elements; avoid page.waitForTimeout
See references/patterns.md for navigation, forms, auth, file upload, drag-drop, iframes, multi-tab, API mocking, visual comparison.
Component Testing
- React:
@playwright/experimental-ct-react — mount components, pass props, assert
- Vue:
@playwright/experimental-ct-vue — mount, slots, provide/inject
- Svelte:
@playwright/experimental-ct-svelte — mount, component API
Component tests run in isolated browser context; use test from @playwright/experimental-ct-*.
Page Object Model (POM)
- Base page: Shared selectors, navigation helpers, common actions
- Page-specific: Extend base; encapsulate page-specific locators and methods
- Component objects: Reusable components (header, modal, form) as classes
See references/best-practices.md for POM structure.
Key Patterns
- Structure: test.describe / test / test.step for grouping
- Locators: getByRole > getByTestId > getByText > getByLabel > CSS selector
- Assertions: expect(locator).toBeVisible, toHaveText, toHaveURL, toHaveCount, etc.
- Network: page.route(url, handler) for mocking; page.unroute to clear
- Fixtures: test.extend for custom fixtures (auth, API client)
- Steps: test.step('description', async () => { ... }) for trace grouping
See references/assertions.md for full assertion reference.
Locator Priority
- getByRole — Accessibility-based; most resilient
- getByTestId — data-testid; explicit, stable
- getByText — Visible text; use for unique labels
- getByLabel — Form labels; good for inputs
- CSS selector — Last resort; brittle for dynamic content
Configuration
- playwright.config.ts — projects (browsers), retries, workers, reporter, baseURL
- Global setup/teardown — Auth state, DB seeding
- Test directory — e2e/, tests/, or colocated
See references/config.md for full config guide.
MCP Integration
- Context7 MCP — Fetch Playwright documentation when needed
- Playwright MCP (cursor-ide-browser, @playwright/mcp) — Record mode: navigate, snapshot, click, type; capture interactions → generate test code
Scope
Can do (autonomous):
- Generate Playwright E2E, component, unit tests from test case specs
- Use Record Mode with Playwright MCP to capture and generate tests
- Apply POM pattern, stable locators, auto-wait
- Configure playwright.config.ts (projects, retries, reporter)
- Use page.route for API mocking
- Delegate to qa-test-healer when tests fail (Heal Mode)
- Use Context7 MCP for Playwright docs
Cannot do (requires confirmation):
- Change production code structure
- Add dependencies not in package.json
- Override project Playwright config without approval
- Navigate to URLs not provided (Record Mode)
Will not do (out of scope):
- Execute tests (user runs
npx playwright test)
- Write Jest/Vitest unit tests (use qa-jest-writer)
- Modify CI/CD pipelines
- Bypass security or access restricted areas
References
references/patterns.md — Navigation, forms, auth, file upload, drag-drop, iframes, multi-tab, API mocking, visual
references/assertions.md — Playwright assertion reference
references/config.md — playwright.config.ts, projects, reporter, setup
references/best-practices.md — POM, locators, flakiness, isolation, debugging
Quality Checklist
Troubleshooting
| Symptom |
Likely Cause |
Fix |
| Element not found |
Selector too specific, dynamic content |
Use getByRole/getByTestId; add data-testid if needed |
| Timeout |
Element not ready, slow network |
Increase expect timeout; use waitFor; check for overlays |
| Flaky tests |
Race conditions, shared state |
Ensure test isolation; use auto-wait; avoid fixed delays |
| Record mode empty |
MCP not capturing steps |
Verify Playwright MCP active; lock browser before actions |
| Multi-tab fails |
Wrong context |
Use page.context().pages() or new context for new tab |
| API mock not applied |
Route registered after request |
Call page.route before page.goto |
| Component test fails |
Missing mount setup |
Check ct config; ensure component imported correctly |
1---2name: qa-playwright-ts-writer3description: Generate Playwright E2E, component, and unit tests for TypeScript with auto-wait, multi-browser support, POM pattern, and live browser record mode via Playwright MCP.4---56# QA Playwright TypeScript Writer78## Purpose910Write Playwright tests (E2E, component, unit) from test case specifications. Transform structured test cases into executable Playwright test files with auto-waiting, multi-browser support, Page Object Model, and optional live browser record mode.1112## Trigger Phrases1314- "Write Playwright tests for [feature/flow]"15- "Generate E2E tests from test cases"16- "Create Playwright tests with record mode"17- "Add Playwright component tests for [component]"18- "Playwright tests for [URL/flow]"19- "Record browser interactions and generate test code"20- "POM-based Playwright tests for [page]"21- "Multi-browser Playwright tests"22- "Heal my failing Playwright tests"2324## Three Modes2526| Mode | When to Use | Behavior |27|------|-------------|----------|28| **Record Mode** | User wants live browser capture | Use Playwright MCP (e.g., cursor-ide-browser) → navigate, interact, capture interactions → generate test code from recorded steps |29| **Generate Mode** | Default; from test case specs | Read test cases (from qa-testcase-from-docs, qa-testcase-from-ui, qa-manual-test-designer) → generate Playwright code |30| **Heal Mode** | Tests fail after changes | Delegate to **qa-test-healer** to auto-fix broken selectors, assertions, waits; mark unfixable as `test.fixme()` |3132## Test Types3334| Type | Scope | Approach |35|------|-------|----------|36| **E2E** | Full user flows, page navigation | page.goto, locators, assertions, network interception, multi-browser |37| **Component** | Isolated component testing | @playwright/experimental-ct-react, ct-vue, ct-svelte; mount, interact, assert |38| **Unit** | Pure functions, utilities | Use test runner for logic; Playwright optional for DOM utilities |3940## E2E Testing4142- **Navigation:** page.goto, page.goBack, page.reload43- **Interactions:** click, fill, selectOption, check, hover, press44- **Assertions:** expect(locator).toBeVisible, toHaveText, toHaveURL, etc.45- **Network:** page.route for API mocking, request/response interception46- **Multi-browser:** Chromium, Firefox, WebKit via projects in config47- **Auto-wait:** Playwright auto-waits for elements; avoid page.waitForTimeout4849See `references/patterns.md` for navigation, forms, auth, file upload, drag-drop, iframes, multi-tab, API mocking, visual comparison.5051## Component Testing5253- **React:** `@playwright/experimental-ct-react` — mount components, pass props, assert54- **Vue:** `@playwright/experimental-ct-vue` — mount, slots, provide/inject55- **Svelte:** `@playwright/experimental-ct-svelte` — mount, component API5657Component tests run in isolated browser context; use `test` from `@playwright/experimental-ct-*`.5859## Page Object Model (POM)6061- **Base page:** Shared selectors, navigation helpers, common actions62- **Page-specific:** Extend base; encapsulate page-specific locators and methods63- **Component objects:** Reusable components (header, modal, form) as classes6465See `references/best-practices.md` for POM structure.6667## Key Patterns6869- **Structure:** test.describe / test / test.step for grouping70- **Locators:** getByRole > getByTestId > getByText > getByLabel > CSS selector71- **Assertions:** expect(locator).toBeVisible, toHaveText, toHaveURL, toHaveCount, etc.72- **Network:** page.route(url, handler) for mocking; page.unroute to clear73- **Fixtures:** test.extend for custom fixtures (auth, API client)74- **Steps:** test.step('description', async () => { ... }) for trace grouping7576See `references/assertions.md` for full assertion reference.7778## Locator Priority79801. **getByRole** — Accessibility-based; most resilient812. **getByTestId** — data-testid; explicit, stable823. **getByText** — Visible text; use for unique labels834. **getByLabel** — Form labels; good for inputs845. **CSS selector** — Last resort; brittle for dynamic content8586## Configuration8788- **playwright.config.ts** — projects (browsers), retries, workers, reporter, baseURL89- **Global setup/teardown** — Auth state, DB seeding90- **Test directory** — e2e/, tests/, or colocated9192See `references/config.md` for full config guide.9394## MCP Integration9596- **Context7 MCP** — Fetch Playwright documentation when needed97- **Playwright MCP** (cursor-ide-browser, @playwright/mcp) — Record mode: navigate, snapshot, click, type; capture interactions → generate test code9899## Scope100101**Can do (autonomous):**102- Generate Playwright E2E, component, unit tests from test case specs103- Use Record Mode with Playwright MCP to capture and generate tests104- Apply POM pattern, stable locators, auto-wait105- Configure playwright.config.ts (projects, retries, reporter)106- Use page.route for API mocking107- Delegate to qa-test-healer when tests fail (Heal Mode)108- Use Context7 MCP for Playwright docs109110**Cannot do (requires confirmation):**111- Change production code structure112- Add dependencies not in package.json113- Override project Playwright config without approval114- Navigate to URLs not provided (Record Mode)115116**Will not do (out of scope):**117- Execute tests (user runs `npx playwright test`)118- Write Jest/Vitest unit tests (use qa-jest-writer)119- Modify CI/CD pipelines120- Bypass security or access restricted areas121122## References123124- `references/patterns.md` — Navigation, forms, auth, file upload, drag-drop, iframes, multi-tab, API mocking, visual125- `references/assertions.md` — Playwright assertion reference126- `references/config.md` — playwright.config.ts, projects, reporter, setup127- `references/best-practices.md` — POM, locators, flakiness, isolation, debugging128129## Quality Checklist130131- [ ] Auto-wait used; no page.waitForTimeout (use expect with timeout or waitFor)132- [ ] No hardcoded waits; prefer expect auto-retry133- [ ] POM pattern applied for page-specific logic134- [ ] Stable locators (getByRole, getByTestId preferred)135- [ ] Tests independent (no shared state, order-independent)136- [ ] Proper teardown (fixtures, afterEach if needed)137- [ ] Traceability to test case IDs where applicable138- [ ] No hardcoded secrets (use env vars)139140## Troubleshooting141142| Symptom | Likely Cause | Fix |143|---------|--------------|-----|144| Element not found | Selector too specific, dynamic content | Use getByRole/getByTestId; add data-testid if needed |145| Timeout | Element not ready, slow network | Increase expect timeout; use waitFor; check for overlays |146| Flaky tests | Race conditions, shared state | Ensure test isolation; use auto-wait; avoid fixed delays |147| Record mode empty | MCP not capturing steps | Verify Playwright MCP active; lock browser before actions |148| Multi-tab fails | Wrong context | Use page.context().pages() or new context for new tab |149| API mock not applied | Route registered after request | Call page.route before page.goto |150| Component test fails | Missing mount setup | Check ct config; ensure component imported correctly |