Test 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
webServerconfig — Playwright starts and waits for the server automatically.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.
webServer configuration: Playwright can start your dev/preview server automatically before running tests. Set 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
webServerauto-start is convenient — but can mask server startup issues- 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.