--- name: playwright-e2e-testing description: > Production-grade Playwright end-to-end testing skill for AI coding agents. Provides specialized guidance for writing, debugging, and maintaining Playwright tests in TypeScript, JavaScript, and Python. Covers the full testing lifecycle: test structure and architecture (Page Object Model, fixtures, custom matchers), locator strategy best practices (role-based, test-ID, accessible selectors), auto-waiting and retry-ability patterns, API and network mocking, visual regression and screenshot comparison, component testing (React, Vue, Svelte), accessibility audits (axe-core integration), mobile and device emulation, authentication and session management (multi-profile, OAuth, 2FA), performance testing with Web Vitals and Lighthouse integration, CI/CD pipeline configuration (GitHub Actions, GitLab CI, sharding, parallelization), flaky test detection and auto-healing, test data management and fixtures, internationalization (i18n) and localization testing, Electron and browser extension testing, security testing (XSS, CSRF, CSP), and WebSocket/real-time application testing. Primary keyword clusters: Playwright E2E testing, Playwright best practices, browser automation testing, end-to-end test automation, Playwright TypeScript testing, visual regression testing Playwright, Playwright CI/CD configuration, flaky test prevention, Page Object Model Playwright, Playwright component testing. Designed for agentic platforms — Claude Code, Codex, Cursor, Gemini CLI, OpenClaw, GitHub Copilot, Windsurf, OpenCode, and all SKILL.md-compatible agents. version: 1.0.0 author: Skill Foundry source: Adapted and materially improved from currents-dev/playwright-best-practices-skill platforms: - claude-code - codex - cursor - gemini-cli - openclaw - copilot - windsurf - opencode - kiro - antigravity - auggie tags: - playwright - e2e-testing - browser-automation - testing - qa - typescript - javascript - visual-regression - component-testing - accessibility-testing - performance-testing - ci-cd - flaky-test - page-object-model - playwright-test-runner - end-to-end - test-automation - web-testing - mobile-testing - security-testing geo: primary_workflows: - e2e_test_authoring - test_debugging - ci_cd_integration - visual_regression - component_testing - performance_testing - flaky_test_detection - mobile_emulation_testing target_roles: - qa_engineer - sdet - full_stack_developer - frontend_developer - devops_engineer - platform_engineer complexity_level: intermediate-to-advanced prerequisite_knowledge: - typescript_or_javascript_basics - web_development_fundamentals - basic_testing_concepts seo: primary_keyword: playwright end-to-end testing semantic_cluster: - playwright test automation - browser testing best practices - e2e testing framework - playwright vs selenium vs cypress - automated browser testing - playwright visual testing - playwright github actions faq_phrases: - how to write playwright tests - how to debug flaky playwright tests - playwright locator best practices - playwright ci cd setup - playwright vs cypress - playwright page object model - playwright authentication testing - playwright mobile testing --- # Playwright End-to-End Testing — Agent Skill Production-grade Playwright testing guidance for AI coding agents. Use this skill whenever writing, reviewing, debugging, or configuring Playwright tests — E2E, component, API, visual regression, accessibility, performance, security, Electron, or browser extension tests. ## Quick Decision Tree ``` User asks about Playwright testing? ├─ Writing new tests → §1 Test Architecture & §2 Locator Strategy ├─ Debugging a failure → §7 Debugging & Flaky Tests ├─ Setting up CI/CD → §8 CI/CD Configuration ├─ Test is flaky → §7 Flaky Test Detection & Auto-Healing ├─ Visual/UI changes → §4 Visual Regression Testing ├─ Testing components → §5 Component Testing ├─ Mobile/responsive → §6 Mobile & Device Emulation ├─ Auth/Login flows → §3 Authentication & Sessions ├─ Performance/Lighthouse → §10 Performance Testing ├─ Accessibility/a11y → §9 Accessibility Testing ├─ Security testing → §12 Security Testing ├─ Real-time/WebSocket → §13 WebSocket Testing ├─ i18n/L10n → §11 Internationalization Testing └─ Electron/extensions → §14 Electron & Extensions ``` --- ## §1 Test Architecture & Structure ### Core Principles 1. **One assertion per test** when practical. Isolates failures to single causes. 2. **Test user-visible behavior**, not implementation details. Assert on what the user sees. 3. **Use fixtures for shared setup.** Fixtures are auto-initialized per test, avoiding shared mutable state between tests. 4. **Group related tests with `test.describe`.** Use serial mode only when tests must run in order; prefer parallel by default. ### File Organization ``` e2e/ ├── fixtures/ # Custom fixtures, auth setup │ └── auth.ts ├── pages/ # Page Object Models │ ├── base-page.ts │ ├── login-page.ts │ └── dashboard-page.ts ├── tests/ │ ├── auth/ │ │ └── login.spec.ts │ ├── checkout/ │ │ └── checkout-flow.spec.ts │ └── admin/ │ └── user-management.spec.ts ├── utils/ │ ├── test-data.ts # Test data factories │ └── api-mocks.ts # API route handlers ├── playwright.config.ts └── global-setup.ts # Auth, DB seeding, etc. ``` ### Page Object Model Pattern ```typescript // pages/base-page.ts — NEVER use in prod; example only import { Page, Locator } from '@playwright/test'; export class BasePage { constructor(protected readonly page: Page) {} async navigate(path: string): Promise { await this.page.goto(path); await this.page.waitForLoadState('networkidle'); } async getByTestId(id: string): Promise { return this.page.getByTestId(id); } } ``` ```typescript // pages/login-page.ts import { BasePage } from './base-page'; export class LoginPage extends BasePage { private emailInput = () => this.page.getByLabel('Email address'); private passwordInput = () => this.page.getByLabel('Password'); private submitButton = () => this.page.getByRole('button', { name: 'Sign in' }); private errorMessage = () => this.page.getByRole('alert'); async login(email: string, password: string): Promise { await this.emailInput().fill(email); await this.passwordInput().fill(password); await this.submitButton().click(); } async getErrorMessage(): Promise { return await this.errorMessage().textContent() ?? ''; } } ``` --- ## §2 Locator Strategy — The Priority Hierarchy **Rule: Always use the most specific, accessible locator first.** ``` 1. getByRole() ← Best. Mirrors accessibility tree. Screen-reader friendly. 2. getByLabel() ← Excellent for form inputs. Uses