Generate Playwright Tests
Generate Playwright tests.
How to use it
Claude Code
- Run the line below. It pulls the whole folder into
~/.claude/skills/generate. - Describe your job in plain words. Claude Code follows the skill from there.
Claude Code — installs the whole folder, not just SKILL.md
npx degit alirezarezvani/claude-skills/engineering-team/playwright-pro/skills/generate#main ~/.claude/skills/generateFor one project only, change the path to .claude/skills/generate.
Claude (web or desktop app)
- On this page open ⋯ → Download .md.
- Save it as SKILL.md in a folder, zip the folder, then Customize → Skills → + → Create skill → Upload a skill.
- Pick the file and Save. Claude shows the name and description and runs a security scan.
- Check the skill is switched on.
- Start a new chat and describe your job in plain words. The AI follows the skill from there.
ChatGPT or another app
- ChatGPT: make a Project and paste it into Instructions.
- Neither? Paste it at the top of a new chat — it works for that chat.
Not working?
- Check which app you pasted it into — the steps above name the right one.
- Some skills need the paid tier of Claude or ChatGPT.
Paste into Claude, ChatGPT or Cursor.
Source of Generate Playwright Tests
Show the full text145 lines
| name | description |
|---|---|
| generate | >- Generate Playwright tests. Use when user says "write tests", "generate tests", add tests for", "test this component", "e2e test", "create test for", test this page", or "test this feature". |
Generate Playwright Tests
Generate production-ready Playwright tests from a user story, URL, component name, or feature description.
Input
$ARGUMENTS contains what to test. Examples:
"user can log in with email and password""the checkout flow""src/components/UserProfile.tsx""the search page with filters"
Steps
1. Understand the Target
Parse $ARGUMENTS to determine:
- User story: Extract the behavior to verify
- Component path: Read the component source code
- Page/URL: Identify the route and its elements
- Feature name: Map to relevant app areas
2. Explore the Codebase
Use the Explore subagent to gather context:
- Read
playwright.config.tsfortestDir,baseURL,projects - Check existing tests in
testDirfor patterns, fixtures, and conventions - If a component path is given, read the component to understand its props, states, and interactions
- Check for existing page objects in
pages/ - Check for existing fixtures in
fixtures/ - Check for auth setup (
auth.setup.tsorstorageStateconfig)
3. Select Templates
Check templates/ in this plugin for matching patterns:
| If testing... | Load template from |
|---|---|
| Login/auth flow | ../pw/templates/auth/login.md |
| CRUD operations | templates/crud/ |
| Checkout/payment | templates/checkout/ |
| Search/filter UI | templates/search/ |
| Form submission | templates/forms/ |
| Dashboard/data | templates/dashboard/ |
| Settings page | templates/settings/ |
| Onboarding flow | templates/onboarding/ |
| API endpoints | templates/api/ |
| Accessibility | templates/accessibility/ |
Adapt the template to the specific app — replace {{placeholders}} with actual selectors, URLs, and data.
4. Generate the Test
Follow these rules:
Structure:
import { test, expect } from '@playwright/test';
// Import custom fixtures if the project uses them
test.describe('Feature Name', () => {
// Group related behaviors
test('should <expected behavior>', async ({ page }) => {
// Arrange: navigate, set up state
// Act: perform user action
// Assert: verify outcome
});
});
Locator priority (use the first that works):
getByRole()— buttons, links, headings, form elementsgetByLabel()— form fields with labelsgetByText()— non-interactive text contentgetByPlaceholder()— inputs with placeholder textgetByTestId()— when semantic options aren't available
Assertions — always web-first:
// GOOD — auto-retries
await expect(page.getByRole('heading')).toBeVisible();
await expect(page.getByRole('alert')).toHaveText('Success');
// BAD — no retry
const text = await page.textContent('.msg');
expect(text).toBe('Success');
Never use:
page.waitForTimeout()page.$(selector)orpage.$$(selector)- Bare CSS selectors unless absolutely necessary
page.evaluate()for things locators can do
Always include:
- Descriptive test names that explain the behavior
- Error/edge case tests alongside happy path
- Proper
awaiton every Playwright call baseURL-relative navigation (page.goto('/')notpage.goto('http://...'))
5. Match Project Conventions
- If project uses TypeScript → generate
.spec.ts - If project uses JavaScript → generate
.spec.jswithrequire()imports - If project has page objects → use them instead of inline locators
- If project has custom fixtures → import and use them
- If project has a test data directory → create test data files there
6. Generate Supporting Files (If Needed)
- Page object: If the test touches 5+ unique locators on one page, create a page object
- Fixture: If the test needs shared setup (auth, data), create or extend a fixture
- Test data: If the test uses structured data, create a JSON file in
test-data/
7. Verify
Run the generated test:
npx playwright test <generated-file> --reporter=list
If it fails:
- Read the error
- Fix the test (not the app)
- Run again
- If it's an app issue, report it to the user
Output
- Generated test file(s) with path
- Any supporting files created (page objects, fixtures, data)
- Test run result
- Coverage note: what behaviors are now tested
| 1 | |
| 2 | name "generate" |
| 3 | description >- |
| 4 | Generate Playwright tests. Use when user says "write tests", "generate tests", |
| 5 | "add tests for", "test this component", "e2e test", "create test for", |
| 6 | "test this page", or "test this feature". |
| 7 | |
| 8 | |
| 9 | # Generate Playwright Tests |
| 10 | |
| 11 | Generate production-ready Playwright tests from a user story, URL, component name, or feature description. |
| 12 | |
| 13 | ## Input |
| 14 | |
| 15 | `$ARGUMENTS` contains what to test. Examples: |
| 16 | `"user can log in with email and password"` |
| 17 | `"the checkout flow"` |
| 18 | `"src/components/UserProfile.tsx"` |
| 19 | `"the search page with filters"` |
| 20 | |
| 21 | ## Steps |
| 22 | |
| 23 | ### 1. Understand the Target |
| 24 | |
| 25 | Parse `$ARGUMENTS` to determine: |
| 26 | **User story**: Extract the behavior to verify |
| 27 | **Component path**: Read the component source code |
| 28 | **Page/URL**: Identify the route and its elements |
| 29 | **Feature name**: Map to relevant app areas |
| 30 | |
| 31 | ### 2. Explore the Codebase |
| 32 | |
| 33 | Use the `Explore` subagent to gather context: |
| 34 | |
| 35 | Read `playwright.config.ts` for `testDir`, `baseURL`, `projects` |
| 36 | Check existing tests in `testDir` for patterns, fixtures, and conventions |
| 37 | If a component path is given, read the component to understand its props, states, and interactions |
| 38 | Check for existing page objects in `pages/` |
| 39 | Check for existing fixtures in `fixtures/` |
| 40 | Check for auth setup (`auth.setup.ts` or `storageState` config) |
| 41 | |
| 42 | ### 3. Select Templates |
| 43 | |
| 44 | Check `templates/` in this plugin for matching patterns: |
| 45 | |
| 46 | | If testing... | Load template from | |
| 47 | |---|---| |
| 48 | | Login/auth flow | `../pw/templates/auth/login.md` | |
| 49 | | CRUD operations | `templates/crud/` | |
| 50 | | Checkout/payment | `templates/checkout/` | |
| 51 | | Search/filter UI | `templates/search/` | |
| 52 | | Form submission | `templates/forms/` | |
| 53 | | Dashboard/data | `templates/dashboard/` | |
| 54 | | Settings page | `templates/settings/` | |
| 55 | | Onboarding flow | `templates/onboarding/` | |
| 56 | | API endpoints | `templates/api/` | |
| 57 | | Accessibility | `templates/accessibility/` | |
| 58 | |
| 59 | Adapt the template to the specific app — replace `{{placeholders}}` with actual selectors, URLs, and data. |
| 60 | |
| 61 | ### 4. Generate the Test |
| 62 | |
| 63 | Follow these rules: |
| 64 | |
| 65 | **Structure:** |
| 66 | |
| 67 | import { test, expect } from '@playwright/test'; |
| 68 | // Import custom fixtures if the project uses them |
| 69 | |
| 70 | test.describe('Feature Name', () => { |
| 71 | // Group related behaviors |
| 72 | |
| 73 | test('should <expected behavior>', async ({ page }) => { |
| 74 | // Arrange: navigate, set up state |
| 75 | // Act: perform user action |
| 76 | // Assert: verify outcome |
| 77 | }); |
| 78 | }); |
| 79 | |
| 80 | |
| 81 | **Locator priority** (use the first that works): |
| 82 | `getByRole()` — buttons, links, headings, form elements |
| 83 | `getByLabel()` — form fields with labels |
| 84 | `getByText()` — non-interactive text content |
| 85 | `getByPlaceholder()` — inputs with placeholder text |
| 86 | `getByTestId()` — when semantic options aren't available |
| 87 | |
| 88 | **Assertions** — always web-first: |
| 89 | |
| 90 | // GOOD — auto-retries |
| 91 | await expect(page.getByRole('heading')).toBeVisible(); |
| 92 | await expect(page.getByRole('alert')).toHaveText('Success'); |
| 93 | |
| 94 | // BAD — no retry |
| 95 | const text = await page.textContent('.msg'); |
| 96 | expect(text).toBe('Success'); |
| 97 | |
| 98 | |
| 99 | **Never use:** |
| 100 | `page.waitForTimeout()` |
| 101 | `page.$(selector)` or `page.$$(selector)` |
| 102 | Bare CSS selectors unless absolutely necessary |
| 103 | `page.evaluate()` for things locators can do |
| 104 | |
| 105 | **Always include:** |
| 106 | Descriptive test names that explain the behavior |
| 107 | Error/edge case tests alongside happy path |
| 108 | Proper `await` on every Playwright call |
| 109 | `baseURL`-relative navigation (`page.goto('/')` not `page.goto('http://...')`) |
| 110 | |
| 111 | ### 5. Match Project Conventions |
| 112 | |
| 113 | If project uses TypeScript → generate `.spec.ts` |
| 114 | If project uses JavaScript → generate `.spec.js` with `require()` imports |
| 115 | If project has page objects → use them instead of inline locators |
| 116 | If project has custom fixtures → import and use them |
| 117 | If project has a test data directory → create test data files there |
| 118 | |
| 119 | ### 6. Generate Supporting Files (If Needed) |
| 120 | |
| 121 | **Page object**: If the test touches 5+ unique locators on one page, create a page object |
| 122 | **Fixture**: If the test needs shared setup (auth, data), create or extend a fixture |
| 123 | **Test data**: If the test uses structured data, create a JSON file in `test-data/` |
| 124 | |
| 125 | ### 7. Verify |
| 126 | |
| 127 | Run the generated test: |
| 128 | |
| 129 | |
| 130 | npx playwright test <generated-file> --reporter=list |
| 131 | |
| 132 | |
| 133 | If it fails: |
| 134 | Read the error |
| 135 | Fix the test (not the app) |
| 136 | Run again |
| 137 | If it's an app issue, report it to the user |
| 138 | |
| 139 | ## Output |
| 140 | |
| 141 | Generated test file(s) with path |
| 142 | Any supporting files created (page objects, fixtures, data) |
| 143 | Test run result |
| 144 | Coverage note: what behaviors are now tested |
| 145 |
Discussion
Act as a product managerGuides the AI to act as a product manager, assisting in writing product requirement documents and addressing product-related queries.Incremental implementationDelivers changes incrementally in thin, verifiable slices. Use when implementing any feature or change that touches more than one file, or when picking up the next task from a plan. Use when rolling a change out behind a feature flag, when you're about to write a large amount of code at once, or when a task feels too big to land in one step.Spec driven developmentCreates specs before coding. Use when starting a new project, feature, or significant change and no specification exists yet. Use when drafting a PRD or requirements document with objectives and scope, or when requirements are unclear, ambiguous, or only exist as a vague idea. Use when a single requirement spans several independently testable capabilities and needs decomposing into a capability map of modules before specifying.Openapi spec generationGenerate and maintain OpenAPI 3.1 specifications from code, design-first specs, and validation patterns. Use when creating API documentation, generating SDKs, or ensuring API contract compliance.
Browse more free Claude skills or everything in Product.