pw-test-generator · v1.0.0 · 2026-10-10 · sha256 f714e3a7a3bf7019
pw-test-generator v1.0.0A
Immutable. This exact content never changes and is served at /api/v1/blob/f714e3a7a3bf7019.
---
name: pw-test-generator
description: >-
Generates a Playwright (TypeScript) test spec from a described user flow or
scenario. Use when an SDET says "write a Playwright test for login", "generate
a spec for the checkout flow", "turn this scenario into a test", or pastes
acceptance criteria that need automating. Produces a runnable draft using
role/testid locators and web-first assertions — the engineer still runs it.
license: MIT
metadata:
author: TheTestingAcademy
pack: playwright
version: 1.0.0
---
# PW Test Generator
You draft a **Playwright spec the engineer must still run and review** — never a
"finished" test. Your job is to translate a flow into resilient, best-practice code.
## When to use
- A user flow, scenario, or acceptance criteria is provided and needs a spec.
- Someone says "write/generate a Playwright test for X".
- A manual test case needs converting to automation.
## Workflow
1. **Restate the flow** as ordered steps (arrange → act → assert). Confirm the
entry URL, the user role, and the observable success signal.
2. **Map each step to a locator strategy.** Prefer `getByRole` (with accessible
name), then `getByLabel`, then `getByTestId`. Flag any step where you had to
guess a selector — mark it `// TODO: confirm selector`.
3. **Choose assertions.** Use web-first, auto-retrying assertions
(`await expect(locator).toBeVisible()`, `toHaveText`, `toHaveURL`). Assert the
end state, not intermediate sleeps.
4. **Draft the spec** with a clear `test.describe`, one `test` per scenario, and
`test.step()` for readability. Reuse fixtures if the flow needs auth/data.
5. **List assumptions** — selectors guessed, data needed, preconditions — so the
engineer can verify before running.
## Output shape
```typescript
import { test, expect } from '@playwright/test';
test.describe('Checkout flow', () => {
test('completes purchase with a valid card', async ({ page }) => {
await test.step('open cart', async () => {
await page.goto('/cart');
await expect(page.getByRole('heading', { name: 'Your Cart' })).toBeVisible();
});
await test.step('checkout', async () => {
await page.getByRole('button', { name: 'Checkout' }).click();
await page.getByLabel('Card number').fill('4111111111111111');
await page.getByRole('button', { name: 'Pay now' }).click();
});
await expect(page.getByTestId('order-confirmation')).toBeVisible();
});
});
```
## Guardrails
- This is a **draft the engineer must run and review** — never assume a selector
exists; mark every guessed locator with `// TODO: confirm`.
- Never fabricate a data-testid, route, or accessible name you weren't shown.
- No `waitForTimeout`, no `networkidle`, no manual sleeps — use web-first waits.
- No XPath, no `nth-child`, no CSS-class selectors; role/testid/label only.
- Assert observable state, not implementation details.