playwright-expert

Expert in Playwright for E2E testing, browser automation, and cross-browser testing.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "playwright-expert" with this command: npx skills add duck4nh/antigravity-kit/duck4nh-antigravity-kit-playwright-expert

Playwright Expert

Expert in Playwright for E2E testing, browser automation, and cross-browser testing.

When Invoked

Recommend Specialist

  • Unit/integration tests: recommend jest-expert or vitest-expert

  • React component testing: recommend testing-expert

  • API testing only: recommend rest-api-expert

Environment Detection

npx playwright --version 2>/dev/null ls playwright.config.* 2>/dev/null find . -name "*.spec.ts" -path "e2e" | head -5

Problem Playbooks

Project Setup

Initialize Playwright

npm init playwright@latest

Install browsers

npx playwright install

// playwright.config.ts import { defineConfig, devices } from '@playwright/test';

export default defineConfig({ testDir: './e2e', fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 1 : undefined, reporter: 'html', use: { baseURL: 'http://localhost:3000', trace: 'on-first-retry', screenshot: 'only-on-failure', }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] } }, { name: 'firefox', use: { ...devices['Desktop Firefox'] } }, { name: 'webkit', use: { ...devices['Desktop Safari'] } }, ], webServer: { command: 'npm run dev', url: 'http://localhost:3000', reuseExistingServer: !process.env.CI, }, });

Writing Tests

import { test, expect } from '@playwright/test';

test.describe('Authentication', () => { test('should login successfully', async ({ page }) => { await page.goto('/login');

await page.fill('[data-testid="email"]', 'user@example.com');
await page.fill('[data-testid="password"]', 'password123');
await page.click('[data-testid="submit"]');

await expect(page).toHaveURL('/dashboard');
await expect(page.locator('h1')).toContainText('Welcome');

});

test('should show error for invalid credentials', async ({ page }) => { await page.goto('/login');

await page.fill('[data-testid="email"]', 'wrong@example.com');
await page.fill('[data-testid="password"]', 'wrong');
await page.click('[data-testid="submit"]');

await expect(page.locator('.error-message')).toBeVisible();

}); });

Page Object Model

// pages/login.page.ts import { Page, Locator } from '@playwright/test';

export class LoginPage { readonly page: Page; readonly emailInput: Locator; readonly passwordInput: Locator; readonly submitButton: Locator;

constructor(page: Page) { this.page = page; this.emailInput = page.locator('[data-testid="email"]'); this.passwordInput = page.locator('[data-testid="password"]'); this.submitButton = page.locator('[data-testid="submit"]'); }

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(); } }

// Usage in test test('login test', async ({ page }) => { const loginPage = new LoginPage(page); await loginPage.goto(); await loginPage.login('user@example.com', 'password'); });

Network Interception

test('mock API response', async ({ page }) => { await page.route('**/api/users', async (route) => { await route.fulfill({ status: 200, body: JSON.stringify([{ id: 1, name: 'Mock User' }]), }); });

await page.goto('/users'); await expect(page.locator('.user-name')).toContainText('Mock User'); });

Visual Regression

test('visual comparison', async ({ page }) => { await page.goto('/'); await expect(page).toHaveScreenshot('homepage.png', { maxDiffPixelRatio: 0.1, }); });

Handling Flaky Tests

// Retry flaky tests test('flaky network test', async ({ page }) => { test.slow(); // Triple timeout

await page.goto('/'); await page.waitForLoadState('networkidle');

// Use polling assertions await expect(async () => { const response = await page.request.get('/api/status'); expect(response.ok()).toBeTruthy(); }).toPass({ timeout: 10000 }); });

Running Tests

Run all tests

npx playwright test

Run specific file

npx playwright test login.spec.ts

Run in headed mode

npx playwright test --headed

Run in UI mode

npx playwright test --ui

Debug mode

npx playwright test --debug

Generate report

npx playwright show-report

Code Review Checklist

  • data-testid attributes for selectors

  • Page Object Model for complex flows

  • Network requests mocked where needed

  • Proper wait strategies (no arbitrary waits)

  • Screenshots on failure configured

  • Parallel execution enabled

Anti-Patterns

  • Hardcoded waits - Use proper assertions

  • Fragile selectors - Use data-testid

  • Shared state between tests - Isolate tests

  • No retries in CI - Add retry for flakiness

  • Testing implementation details - Test user behavior

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

bash-automation

No summary provided by upstream source.

Repository SourceNeeds Review
General

linux-server-expert

No summary provided by upstream source.

Repository SourceNeeds Review
General

pentest-expert

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

exploit-dev-expert

No summary provided by upstream source.

Repository SourceNeeds Review