Playwright Test Builder
Generates robust Playwright end-to-end tests for web pages and user flows.
Best use case
Playwright Test Builder is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Generates robust Playwright end-to-end tests for web pages and user flows.
Teams using Playwright Test Builder should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/playwright-test-builder/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How Playwright Test Builder Compares
| Feature / Agent | Playwright Test Builder | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Generates robust Playwright end-to-end tests for web pages and user flows.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Playwright Test Builder
## What this skill does
This skill directs the agent to write well-structured Playwright end-to-end tests for a given user flow or page. It produces tests with proper locator strategies (preferring accessible selectors over brittle CSS), meaningful assertions at every step, correct async/await handling, and solid setup/teardown. The output is ready to drop into a `tests/` folder and run immediately.
Use this when you want reliable E2E coverage for critical user journeys — login, checkout, form submission, navigation flows — without writing boilerplate from scratch.
## How to use
### Claude Code / Cline
Copy this file to `.agents/skills/playwright-test-builder/SKILL.md` in your project root.
Then describe the flow you want tested and ask:
- *"Use the Playwright Test Builder skill to write E2E tests for the login flow."*
- *"Write Playwright tests for the checkout process using the Playwright Test Builder skill."*
Provide the page URL (or a description of the UI), the steps in the flow, and any known selectors or data-testid values if you have them.
### Cursor
Add the "Prompt / Instructions" section below to your `.cursorrules` file. Then describe the flow to test in the chat.
### Codex
Paste the relevant HTML or React component code alongside the flow description and the instructions below. Seeing the actual markup helps Codex pick the most stable locators.
## The Prompt / Instructions for the Agent
When asked to write Playwright tests, follow these steps:
1. **Understand the flow.** Ask for (or infer from context):
- The URL or page being tested
- The steps a user takes (click X, fill Y, expect Z)
- Any test data needed (usernames, passwords, form values)
- Whether authentication is required before the test
2. **Choose locators in this priority order** (most stable first):
- `getByRole()` with accessible name — best for buttons, links, inputs, headings
- `getByLabel()` — for form fields with associated labels
- `getByText()` — for elements identified by their visible text
- `getByPlaceholder()` — for inputs with placeholder text
- `getByTestId()` — when `data-testid` attributes are present
- CSS selectors — only as a last resort; avoid if any stable alternative exists
- Never use XPath unless absolutely necessary
3. **Add assertions at every meaningful step.** After each action, assert:
- A visible UI change (new element appears, text changes, URL changes)
- Not just "click and hope" — every interaction must have a follow-up assertion
- Use `expect(locator).toBeVisible()`, `toHaveText()`, `toHaveURL()`, `toBeEnabled()`, etc.
4. **Structure the test file properly:**
- Use `test.describe` to group related tests
- Use `test.beforeEach` for shared setup (navigation, login)
- Use `test.afterEach` or `test.afterAll` for cleanup if needed
- Give each `test()` a descriptive name starting with a verb: "shows...", "allows...", "prevents..."
- Keep each test focused on one behavior
5. **Handle async correctly.** Every `page.click`, `page.fill`, `page.goto`, and `expect` must be awaited. Never use `setTimeout` for waiting — use `page.waitForSelector`, `page.waitForURL`, or rely on Playwright's auto-waiting.
6. **Add resilience where appropriate:**
- For flaky elements (animations, lazy-loaded content), use `expect(locator).toBeVisible({ timeout: 5000 })`
- For network-dependent tests, consider `page.waitForResponse()` or mock the network with `page.route()`
- Avoid hard-coded `page.waitForTimeout()` sleeps — use condition-based waits
7. **Include a Page Object Model class** if the flow spans multiple pages or the test is complex. Keep it in a separate `pages/` subfolder.
8. **Output the complete, runnable test file** with all imports. Include a comment block at the top describing what the test suite covers.
## Example
**Input to Agent:**
> "Use the Playwright Test Builder skill to write tests for our sign-up flow. The user goes to `/register`, fills in their name, email, and password, clicks 'Create Account', and should land on `/dashboard` with a welcome message."
**Output from Agent:**
> ```typescript
> import { test, expect } from '@playwright/test';
>
> /**
> * Tests for the user registration flow.
> * Covers: form validation, successful account creation, post-signup redirect.
> */
>
> test.describe('Registration flow', () => {
> test.beforeEach(async ({ page }) => {
> await page.goto('/register');
> await expect(page).toHaveURL('/register');
> });
>
> test('shows the registration form', async ({ page }) => {
> await expect(page.getByRole('heading', { name: 'Create your account' })).toBeVisible();
> await expect(page.getByLabel('Full name')).toBeVisible();
> await expect(page.getByLabel('Email')).toBeVisible();
> await expect(page.getByLabel('Password')).toBeVisible();
> await expect(page.getByRole('button', { name: 'Create Account' })).toBeEnabled();
> });
>
> test('allows a new user to register and redirects to dashboard', async ({ page }) => {
> await page.getByLabel('Full name').fill('Jane Smith');
> await page.getByLabel('Email').fill('jane@example.com');
> await page.getByLabel('Password').fill('SecurePass123!');
>
> await page.getByRole('button', { name: 'Create Account' }).click();
>
> await expect(page).toHaveURL('/dashboard');
> await expect(page.getByText('Welcome, Jane')).toBeVisible();
> });
>
> test('shows a validation error when email is already taken', async ({ page }) => {
> await page.getByLabel('Full name').fill('Existing User');
> await page.getByLabel('Email').fill('existing@example.com');
> await page.getByLabel('Password').fill('SecurePass123!');
>
> await page.getByRole('button', { name: 'Create Account' }).click();
>
> await expect(page.getByRole('alert')).toContainText('already in use');
> await expect(page).toHaveURL('/register');
> });
>
> test('prevents submission when required fields are empty', async ({ page }) => {
> await page.getByRole('button', { name: 'Create Account' }).click();
>
> // Form should not navigate away
> await expect(page).toHaveURL('/register');
> await expect(page.getByLabel('Email')).toBeFocused();
> });
> });
> ```Related Skills
Unit Test Writer
Generates comprehensive unit tests for any function or module with edge cases.
Unit Test Improver
Reviews existing unit tests for gaps, weak assertions, and missing edge cases, then rewrites them to be more robust.
Troubleshooting Guide Builder
Builds a structured troubleshooting guide with symptom → cause → fix format for any tool or system.
MCP Server Builder
Step-by-step guidance for creating a new MCP server with FastMCP or the TypeScript SDK — tool definitions, resource handlers, error responses, and usage examples.
Flaky Test Analyzer
Diagnoses why tests pass inconsistently and suggests fixes for timing, ordering, and state isolation issues.
Agent Evaluation Framework Builder
Designs an eval suite for an LLM agent or pipeline including success metrics, trajectory scoring, LLM-as-judge setup, and regression test cases.
Tech Debt Auditor
Identifies and prioritizes technical debt in a codebase with an effort/impact matrix.
Technical Blog Post Writer
Writes engaging, accurate technical blog posts targeted at developer audiences.
Stack Trace Analyzer
Interprets error stack traces to pinpoint root cause, explain what went wrong, and suggest fixes.
SQL Query Optimizer
Reviews SQL queries for performance issues and rewrites them with optimized execution plans.
Sprint Summary Generator
Converts a list of completed tickets or commits into a clear sprint summary for stakeholders.
Social Post Thread Writer
Converts a blog post, idea, or document into an engaging Twitter/X or LinkedIn thread with hooks and CTAs.