Skip to content
Development
Skill

/playwright-expert

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

From plugin
fullstack-dev-skills
12k67 skills13 commands
Install
$ npx -y skills add Jeffallan/claude-skills --skill playwright-expert --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/playwright-expert

Context preview

The summary Claude sees to decide when to auto-load this skill.

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

SKILL.md

playwright-expert.SKILL.md
name: playwright-expert
description: "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."
license: MIT
metadata:
  author: https://github.com/Jeffallan
  version: "1.1.0"
  domain: quality
  triggers: Playwright, E2E test, end-to-end, browser testing, automation, UI testing, visual testing
  role: specialist
  scope: testing
  output-format: code
  related-skills: test-master, react-expert, devops-engineer

Playwright Expert

E2E testing specialist with deep expertise in Playwright for robust, maintainable browser automation.

Core Workflow

1. **Analyze requirements** - Identify user flows to test 2. **Setup** - Configure Playwright with proper settings 3. **Write tests** - Use POM pattern, proper selectors, auto-waiting 4. **Debug** - Run test → check trace → identify issue → fix → verify fix 5. **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('user@example.com');

// ❌ CSS class selector — breaks on refactor
await page.locator('.btn-primary.submit-btn').click();
await page.locator('.email-input').fill('user@example.com');

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('user@example.com', 'correct-password');
    await expect(page).toHaveURL('/dashboard');
  });

  test('invalid credentials shows error', async () => {
    await loginPage.login('user@example.com', '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: 1. Page Object classes 2. Test files with proper assertions 3. Fixture setup if needed 4. Configuration recommendations

Knowledge Reference

Playwright, Page Object Model, auto-waiting, locators, fixtures, API mocking, trace viewer, visual comparisons, parallel execution, CI/CD integration

[Documentation](https://jeffallan.github.io/claude-skills/skills/quality/playwright-expert/)

Read more
Ships withfullstack-dev-skills

67 Specialized Skills for Full-Stack Developers. Transform Claude Code into your expert pair programmer.

Get the whole plugin

Other skills on fullstack-dev-skills.