From playwright
Write, debug, and maintain Playwright tests and scrapers with resilient selectors, flaky test fixes, and CI/CD integration.
How this skill is triggered — by the user, by Claude, or both
Slash command
/playwright:playwrightThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use when writing Playwright tests, debugging failures, scraping with Playwright, or setting up CI/CD pipelines.
Use when writing Playwright tests, debugging failures, scraping with Playwright, or setting up CI/CD pipelines.
getByRole() — accessible, resilientgetByTestId() — explicit, stablegetByLabel(), getByPlaceholder() — form elementsgetByText() — visible content (exact match preferred)page.waitForTimeout() — use waitFor* methods or expect with pollingbrowser.close() or context.close() to prevent memory leaksnetworkidle with caution — SPAs may never reach idle; use DOM-based waits insteadtest.describe.configure({ mode: 'parallel' }) — for independent teststrace: 'on-first-retry' in config, not always-on| Symptom | Fix |
|---|---|
| Element not found | Use waitFor() before interaction, check frame context |
| Flaky clicks | Use click({ force: true }) or waitFor({ state: 'visible' }) first |
| Timeout in CI | Increase timeout, add expect.poll(), check viewport size |
| Stale element | Re-query the locator, avoid storing element references |
| Auth lost between tests | Use storageState to persist cookies/localStorage |
// Basic scrape with Playwright
const { chromium } = require('playwright');
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
userAgent: 'Mozilla/5.0 (compatible; bot/1.0)'
});
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
// Wait for specific element
await page.waitForSelector('.article-content');
// Extract data
const data = await page.$$eval('.article', articles =>
articles.map(a => ({
title: a.querySelector('h2')?.textContent?.trim(),
url: a.querySelector('a')?.href,
date: a.querySelector('time')?.getAttribute('datetime')
}))
);
await browser.close();
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests/e2e',
timeout: 30_000,
retries: process.env.CI ? 2 : 0,
use: {
baseURL: 'http://localhost',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
});
// Basic test
import { test, expect } from '@playwright/test';
test('login flow', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('[email protected]');
await page.getByLabel('Password').fill('password');
await page.getByRole('button', { name: 'Login' }).click();
await expect(page).toHaveURL('/dashboard');
});
// Save auth state
await page.goto('/login');
await page.getByLabel('Email').fill('[email protected]');
await page.getByLabel('Password').fill('secret');
await page.getByRole('button', { name: 'Login' }).click();
await page.context().storageState({ path: 'auth.json' });
// Reuse in other tests
const context = await browser.newContext({ storageState: 'auth.json' });
await page.screenshot({ path: 'screenshot.png', fullPage: true });
await page.pdf({ path: 'page.pdf', format: 'A4' });
npx playwright test # Run all tests
npx playwright test --headed # With browser visible
npx playwright test --debug # Debug mode (step-by-step)
npx playwright test --grep "login" # Filter by test name
npx playwright show-report # Open HTML report
npx playwright codegen https://example.com # Record interactions → code
npx claudepluginhub billyfranklim1/claude-skills --plugin playwrightProvides Playwright patterns for resilient selectors, locator chaining, filtering, and waiting strategies to minimize flakiness in E2E tests and web scrapers.
Writes maintainable Playwright E2E tests using page objects, accessible locators, fixtures, and parallel execution. Helps debug flaky tests and manage complex user flows.
Writes and debugs E2E tests with Playwright using Page Object Model, API mocking, and visual regression. Configures test infrastructure and CI integration.