git clone https://github.com/Intense-Visions/harness-engineering
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/codex/test-playwright-setup" ~/.claude/skills/intense-visions-harness-engineering-test-playwright-setup-086376 && rm -rf "$T"
agents/skills/codex/test-playwright-setup/SKILL.mdTest Playwright Setup
Configure Playwright test runner with fixtures, reporters, and browser contexts
When to Use
- Setting up Playwright for end-to-end testing in a web project
- Configuring multiple browsers, reporters, and test environments
- Setting up authentication state sharing across tests
- Configuring CI-specific Playwright settings
Instructions
- Install Playwright:
npm init playwright@latest # or npm install -D @playwright/test npx playwright install
- Configure
: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: process.env.CI ? 'github' : '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 dev', url: 'http://localhost:3000', reuseExistingServer: !process.env.CI, timeout: 120_000, }, });
-
Auto-start the dev server with
config — Playwright starts and waits for the server automatically.webServer -
Set up authenticated state with global setup:
// e2e/auth.setup.ts import { test as setup, expect } from '@playwright/test'; setup('authenticate', async ({ page }) => { await page.goto('/login'); await page.getByLabel('Email').fill('admin@test.com'); await page.getByLabel('Password').fill('password'); await page.getByRole('button', { name: 'Log in' }).click(); await expect(page.getByText('Dashboard')).toBeVisible(); await page.context().storageState({ path: 'e2e/.auth/user.json' }); });
// playwright.config.ts — add setup project projects: [ { name: 'setup', testMatch: /.*\.setup\.ts/ }, { name: 'chromium', use: { ...devices['Desktop Chrome'], storageState: 'e2e/.auth/user.json', }, dependencies: ['setup'], }, ],
- Custom fixtures for reusable test helpers:
// e2e/fixtures.ts import { test as base } from '@playwright/test'; type Fixtures = { todoPage: TodoPage; }; export const test = base.extend<Fixtures>({ todoPage: async ({ page }, use) => { const todoPage = new TodoPage(page); await todoPage.goto(); await use(todoPage); }, }); export { expect } from '@playwright/test';
- Configure reporters:
reporter: [ ['html', { open: 'never' }], ['junit', { outputFile: 'test-results/junit.xml' }], ['list'], ],
- Trace viewer for debugging failed tests:
use: { trace: 'on-first-retry', // Records trace on first retry of failed tests },
View with:
npx playwright show-trace test-results/trace.zip
- Add to
:.gitignore
test-results/ playwright-report/ e2e/.auth/
Details
Playwright runs tests across real browsers (Chromium, Firefox, WebKit) with full automation capabilities. Each test gets a fresh browser context by default, providing natural test isolation.
Browser contexts: Each test runs in an isolated browser context (like an incognito window). Cookies, localStorage, and session state do not leak between tests. This is more isolated than sharing a single browser instance.
configuration: Playwright can start your dev/preview server automatically before running tests. Set webServer
reuseExistingServer: true for development (uses an already-running server) and false for CI (starts a fresh server).
Storage state: Authentication state (cookies, localStorage) can be saved and reused across tests. This avoids logging in for every test, significantly speeding up the suite.
Parallelism:
fullyParallel: true runs tests in the same file in parallel. Each test gets its own worker process. Set workers: 1 in CI if your app cannot handle concurrent users.
Trade-offs:
- Multi-browser testing catches browser-specific bugs — but triples test execution time
auto-start is convenient — but can mask server startup issueswebServer- Storage state sharing speeds up tests — but tests may fail if the auth state expires
- Trace viewer is invaluable for debugging — but traces consume significant disk space
Source
https://playwright.dev/docs/intro
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.