playwright-expert
Expertise in Playwright for creating maintainable browser automation, end-to-end tests, and debugging UI flows.
Install
mkdir -p .claude/skills/playwright-expert && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/3690" && unzip -o skill.zip -d .claude/skills/playwright-expert && rm skill.zipInstalls to .claude/skills/playwright-expert
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Use when writing E2E tests with Playwright, setting up test infrastructure, or debugging flaky browser tests. Invoke to write test scripts, create page objects, configure test fixtures, set up reporters, add CI integration, implement API mocking, or perform visual regression testing. Trigger terms: Playwright, E2E test, end-to-end, browser testing, automation, UI testing, visual testing, Page Object Model, test flakiness.Key capabilities
- →Implement Page Object Model patterns for test maintainability
- →Configure Playwright test fixtures and environment settings
- →Execute visual regression testing and API mocking
- →Analyze test failures using trace viewer and screenshot logs
- →Integrate test suites into CI/CD pipelines
How it works
The agent generates test code using role-based locators and auto-waiting mechanisms to ensure stability. It guides the user through a debugging workflow that utilizes trace viewer and retry logic to isolate and resolve flaky tests.
Inputs & outputs
When to use playwright-expert
- →Write E2E test scripts
- →Create page objects for test automation
- →Debug flaky browser tests
- →Configure API mocking in tests
About this skill
Playwright Expert
E2E testing specialist with deep expertise in Playwright for robust, maintainable browser automation.
Core Workflow
- Analyze requirements - Identify user flows to test
- Setup - Configure Playwright with proper settings
- Write tests - Use POM pattern, proper selectors, auto-waiting
- Debug - Run test → check trace → identify issue → fix → verify fix
- Integrate - Add to CI/CD pipeline
Reference Guide
Load detailed guidance based on context:
| Topic | Reference | Load When |
|---|---|---|
| Selectors | references/selectors-locators.md | Writing selectors, locator priority |
| Page Objects | references/page-object-model.md | POM patterns, fixtures |
| API Mocking | references/api-mocking.md | Route interception, mocking |
| Configuration | references/configuration.md | playwright.config.ts setup |
| Debugging | references/debugging-flaky.md | Flaky tests, trace viewer |
Constraints
MUST DO
- Use role-based selectors when possible
- Leverage auto-waiting (don't add arbitrary timeouts)
- Keep tests independent (no shared state)
- Use Page Object Model for maintainability
- Enable traces/screenshots for debugging
- Run tests in parallel
MUST NOT DO
- Use
waitForTimeout()(use proper waits) - Rely on CSS class selectors (brittle)
- Share state between tests
- Ignore flaky tests
- Use
first(),nth()without good reason
Code Examples
Selector: Role-based (correct) vs CSS class (brittle)
// ✅ Role-based selector — resilient to styling changes
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByLabel('Email address').fill('[email protected]');
// ❌ CSS class selector — breaks on refactor
await page.locator('.btn-primary.submit-btn').click();
await page.locator('.email-input').fill('[email protected]');
Page Object Model + Test File
// pages/LoginPage.ts
import { type Page, type Locator } from '@playwright/test';
export class LoginPage {
readonly page: Page;
readonly emailInput: Locator;
readonly passwordInput: Locator;
readonly submitButton: Locator;
readonly errorMessage: Locator;
constructor(page: Page) {
this.page = page;
this.emailInput = page.getByLabel('Email address');
this.passwordInput = page.getByLabel('Password');
this.submitButton = page.getByRole('button', { name: 'Sign in' });
this.errorMessage = page.getByRole('alert');
}
async goto() {
await this.page.goto('/login');
}
async login(email: string, password: string) {
await this.emailInput.fill(email);
await this.passwordInput.fill(password);
await this.submitButton.click();
}
}
// tests/login.spec.ts
import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';
test.describe('Login', () => {
let loginPage: LoginPage;
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
await loginPage.goto();
});
test('successful login redirects to dashboard', async ({ page }) => {
await loginPage.login('[email protected]', 'correct-password');
await expect(page).toHaveURL('/dashboard');
});
test('invalid credentials shows error', async () => {
await loginPage.login('[email protected]', 'wrong-password');
await expect(loginPage.errorMessage).toBeVisible();
await expect(loginPage.errorMessage).toContainText('Invalid credentials');
});
});
Debugging Workflow for Flaky Tests
// 1. Run failing test with trace enabled
// playwright.config.ts
use: {
trace: 'on-first-retry',
screenshot: 'only-on-failure',
}
// 2. Re-run with retries to capture trace
// npx playwright test --retries=2
// 3. Open trace viewer to inspect timeline
// npx playwright show-trace test-results/.../trace.zip
// 4. Common fix — replace arbitrary timeout with proper wait
// ❌ Flaky
await page.waitForTimeout(2000);
await page.getByRole('button', { name: 'Save' }).click();
// ✅ Reliable — waits for element state
await page.getByRole('button', { name: 'Save' }).waitFor({ state: 'visible' });
await page.getByRole('button', { name: 'Save' }).click();
// 5. Verify fix — run test 10x to confirm stability
// npx playwright test --repeat-each=10
Output Templates
When implementing Playwright tests, provide:
- Page Object classes
- Test files with proper assertions
- Fixture setup if needed
- Configuration recommendations
Knowledge Reference
Playwright, Page Object Model, auto-waiting, locators, fixtures, API mocking, trace viewer, visual comparisons, parallel execution, CI/CD integration
When not to use it
- →When using arbitrary timeouts like waitForTimeout
- →When relying on brittle CSS class selectors
- →When sharing state between independent test cases
Limitations
- →Requires tests to remain independent without shared state
- →Prohibits the use of arbitrary timeouts
How it compares
Unlike manual scripting, this approach enforces the Page Object Model and role-based selectors to prevent test breakage during UI refactors.
Compared to similar skills
playwright-expert side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| playwright-expert (this skill) | 7 | 3mo | No flags | Intermediate |
| dependency-upgrade | 26 | 5mo | Review | Intermediate |
| validate-typescript | 5 | 9mo | Review | Beginner |
| ts-testing | 6 | 8mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by Jeffallan
View all by Jeffallan →You might also like
dependency-upgrade
wshobson
Manage major dependency version upgrades with compatibility analysis, staged rollout, and comprehensive testing. Use when upgrading framework versions, updating major dependencies, or managing breaking changes in libraries.
validate-typescript
BerryKuipers
Run TypeScript compiler type-checking (tsc --noEmit) to validate type safety and catch type errors. Works with any TypeScript project. Returns structured output with error counts, categories (type/syntax/import errors), and affected files. Used for quality gates and pre-commit validation.
ts-testing
johnlindquist
Design, implement, and maintain high‑value TypeScript test suites using popular JS/TS testing libraries. Use this skill whenever the user is adding tests, debugging failing tests, or refactoring code that should be covered by tests.
react-best-practices
redpanda-data
Client-side React performance optimization patterns.
feature-flags
Use when feature flag tests fail, flags need updating, understanding @gate pragmas, debugging channel-specific test failures, or adding new flags to React.
typescript-code-review
anyproto
Perform comprehensive code reviews for TypeScript projects, analyzing type safety, best practices, performance, security, and code quality with actionable feedback