
Playwright E2e Testing
Set up cross-browser Playwright E2E tests with auto-wait, fixtures, and HTML reports before you ship web user flows.
Overview
Playwright E2E Testing is an agent skill for the Ship phase that guides cross-browser end-to-end test setup, execution, and reporting with Playwright’s built-in runner.
Install
npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill playwright-e2e-testingWhat is this skill?
- Cross-browser automation (Chromium, Firefox, WebKit) with a built-in test runner
- Auto-wait reduces flaky selectors versus manual sleep-based scripts
- Screenshot, video, and trace recording for debugging failed flows
- Quick start: npm init playwright@latest, npx playwright test, npx playwright show-report
- Covers user-flow testing when you need interaction-level confidence beyond unit tests
- Quick start: 4 CLI steps from init through show-report
Adoption & trust: 2.7k installs on skills.sh; 53 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are about to ship a web product but only have shallow unit coverage and no reliable way to replay critical user flows in real browsers.
Who is it for?
Solo builders shipping React, Next.js, or other web apps who want one command to verify checkout, auth, or onboarding across browsers.
Skip if: Teams that only need API contract tests, native mobile-only apps with no web UI, or projects with zero browser surface area.
When should I use this skill?
When writing tests, implementing playwright-e2e-testing, or ensuring code quality; when testing web applications end-to-end, cross-browser, user flows, or needing screenshot/video recording.
What do I get? / Deliverables
After using the skill, your agent can scaffold Playwright, author stable flow tests with auto-wait, and run npx playwright test with an HTML report you can inspect before release.
- Playwright test project and spec files
- HTML test report via playwright show-report
- Optional trace/screenshot artifacts on failure
Recommended Skills
Journey fit
End-to-end browser testing is a Ship-phase gate: it validates real user paths after Build and before Launch. Playwright fits the testing subphase because it automates UI flows, assertions, and trace/screenshot capture against staging or production-like environments.
How it compares
Use for full browser journeys instead of mocking the DOM in Jest alone or ad-hoc manual QA each release.
Common Questions / FAQ
Who is playwright-e2e-testing for?
Indie and solo developers building web apps who want agent-guided Playwright setup and patterns for stable E2E suites without hiring dedicated QA.
When should I use playwright-e2e-testing?
Use it in Ship (testing) when validating end-to-end user flows, needing cross-browser checks, or capturing screenshots and videos on failure; also when wiring CI smoke tests before Launch distribution.
Is playwright-e2e-testing safe to install?
Review the Security Audits panel on this Prism page and inspect the skill bundle in your repo before granting shell or network access in CI runners.
SKILL.md
READMESKILL.md - Playwright E2e Testing
# Playwright E2E Testing Skill --- progressive_disclosure: entry_point: summary: "Modern E2E testing framework with cross-browser automation and built-in test runner" when_to_use: - "When testing web applications end-to-end" - "When needing cross-browser testing" - "When testing user flows and interactions" - "When needing screenshot/video recording" quick_start: - "npm init playwright@latest" - "Choose TypeScript and test location" - "npx playwright test" - "npx playwright show-report" token_estimate: entry: 75-90 full: 4200-5200 --- <!-- ENTRY POINT - Load this section by default (75-90 tokens) --> ## Overview Playwright is a modern end-to-end testing framework that provides cross-browser automation with a built-in test runner, auto-wait mechanisms, and excellent developer experience. ### Key Features - **Auto-wait**: Automatically waits for elements to be ready - **Cross-browser**: Chromium, Firefox, WebKit support - **Built-in runner**: Parallel execution, retries, reporters - **Network control**: Mock and intercept network requests - **Debugging**: UI mode, trace viewer, inspector --- <!-- FULL CONTENT - Load on demand (4200-5200 tokens) --> ## Installation ```bash # Initialize new Playwright project npm init playwright@latest # Or add to existing project npm install -D @playwright/test # Install browsers npx playwright install ``` ### Configuration ```typescript // playwright.config.ts import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ testDir: './tests', 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'] }, }, { name: 'Mobile Chrome', use: { ...devices['Pixel 5'] }, }, ], webServer: { command: 'npm run start', url: 'http://localhost:3000', reuseExistingServer: !process.env.CI, }, }); ``` ## Fundamentals ### Basic Test Structure ```typescript import { test, expect } from '@playwright/test'; test('basic test', async ({ page }) => { await page.goto('https://example.com'); // Wait for element and check visibility const title = page.locator('h1'); await expect(title).toBeVisible(); await expect(title).toHaveText('Example Domain'); // Get page title await expect(page).toHaveTitle(/Example/); }); test.describe('User authentication', () => { test('should login successfully', async ({ page }) => { await page.goto('/login'); await page.fill('[name="username"]', 'testuser'); await page.fill('[name="password"]', 'password123'); await page.click('button[type="submit"]'); await expect(page).toHaveURL('/dashboard'); await expect(page.locator('.welcome-message')).toContainText('Welcome'); }); test('should show error for invalid credentials', async ({ page }) => { await page.goto('/login'); await page.fill('[name="username"]', 'invalid');