Agent skill
setup-playwright
Configure Playwright for E2E testing. Use when setting up end-to-end tests, when no E2E framework is detected, or when the user asks to configure browser testing.
Install this agent skill to your Project
npx add-skill https://github.com/gruckion/marathon-ralph/tree/main/skills/setup-playwright
SKILL.md
Setup Playwright
Configure Playwright as the end-to-end testing framework with fixtures and best practices.
When to Use This Skill
- No E2E framework is configured in the project
- User requests to set up E2E testing
- Project is a web application needing browser testing
- Migrating from Cypress to Playwright
Installation
Use ni to auto-detect the package manager. Get the exec command from .claude/marathon-ralph.json under project.commands.exec:
# Install Playwright
ni -D @playwright/test
# Install browsers (use exec command from project state: bunx, pnpm exec, npx, etc.)
# Examples:
bunx playwright install --with-deps
# or: pnpm exec playwright install --with-deps
# or: npx playwright install --with-deps
# For CI optimization, install only needed browsers
bunx playwright install chromium --with-deps
Configuration
playwright.config.ts
Create playwright.config.ts at the project root:
import { defineConfig, devices } from '@playwright/test'
export default defineConfig({
// Test directory
testDir: './tests/e2e',
// Run tests in parallel
fullyParallel: true,
// Fail build on CI if test.only is left in code
forbidOnly: !!process.env.CI,
// Retry failed tests (more on CI)
retries: process.env.CI ? 2 : 0,
// Parallel workers
workers: process.env.CI ? 1 : undefined,
// Reporter configuration
reporter: process.env.CI
? [['github'], ['html', { open: 'never' }]]
: [['list'], ['html']],
// Timeouts
timeout: 30000,
expect: {
timeout: 5000,
},
// Shared settings for all projects
use: {
// Base URL for page.goto('/')
baseURL: process.env.BASE_URL || 'http://localhost:3000',
// Collect trace on first retry
trace: 'on-first-retry',
// Screenshot on failure
screenshot: 'only-on-failure',
// Video on first retry
video: 'on-first-retry',
},
// Browser projects
projects: [
// Setup project for authentication
{
name: 'setup',
testMatch: /.*\.setup\.ts/,
},
// Desktop Chrome
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
storageState: 'playwright/.auth/user.json',
},
dependencies: ['setup'],
},
// Desktop Firefox (optional)
{
name: 'firefox',
use: {
...devices['Desktop Firefox'],
storageState: 'playwright/.auth/user.json',
},
dependencies: ['setup'],
},
// Desktop Safari (optional)
{
name: 'webkit',
use: {
...devices['Desktop Safari'],
storageState: 'playwright/.auth/user.json',
},
dependencies: ['setup'],
},
// Mobile Chrome (optional)
{
name: 'Mobile Chrome',
use: {
...devices['Pixel 5'],
storageState: 'playwright/.auth/user.json',
},
dependencies: ['setup'],
},
],
// Run dev server before tests
// IMPORTANT: Use the dev command from your package manager
// Get from project state: project.commands.dev
webServer: {
command: process.env.DEV_COMMAND || 'bun run dev', // Adjust based on package manager
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
timeout: 120 * 1000,
},
})
Directory Structure
Create the recommended directory structure:
project/
├── tests/
│ └── e2e/
│ ├── fixtures/
│ │ └── test-fixtures.ts # Custom fixtures
│ ├── pages/
│ │ ├── login.page.ts # Page objects
│ │ └── home.page.ts
│ ├── auth.setup.ts # Authentication setup
│ ├── home.spec.ts # Test files
│ └── login.spec.ts
├── playwright/
│ └── .auth/
│ └── .gitkeep # Auth state storage
├── playwright.config.ts
└── package.json
Create the directories:
mkdir -p tests/e2e/fixtures tests/e2e/pages playwright/.auth
touch playwright/.auth/.gitkeep
.gitignore
Add to .gitignore:
# Playwright
playwright-report/
test-results/
playwright/.auth/
!playwright/.auth/.gitkeep
Package.json Scripts
Add test scripts:
{
"scripts": {
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:headed": "playwright test --headed",
"test:e2e:debug": "playwright test --debug",
"test:e2e:report": "playwright show-report"
}
}
Authentication Setup
Create tests/e2e/auth.setup.ts for shared authentication:
import { test as setup, expect } from '@playwright/test'
const authFile = 'playwright/.auth/user.json'
setup('authenticate', async ({ page }) => {
// Navigate to login
await page.goto('/login')
// Fill credentials
await page.getByLabel(/email/i).fill('test@example.com')
await page.getByLabel(/password/i).fill('password123')
await page.getByRole('button', { name: /sign in/i }).click()
// Wait for authentication to complete
await expect(page).toHaveURL('/dashboard')
// Save authentication state
await page.context().storageState({ path: authFile })
})
Custom Fixtures
Create tests/e2e/fixtures/test-fixtures.ts:
import { test as base, expect } from '@playwright/test'
import { LoginPage } from '../pages/login.page'
import { HomePage } from '../pages/home.page'
// Declare fixture types
type MyFixtures = {
loginPage: LoginPage
homePage: HomePage
}
// Extend base test with custom fixtures
export const test = base.extend<MyFixtures>({
loginPage: async ({ page }, use) => {
const loginPage = new LoginPage(page)
await use(loginPage)
},
homePage: async ({ page }, use) => {
const homePage = new HomePage(page)
await use(homePage)
},
})
export { expect }
Page Object Model
Create tests/e2e/pages/login.page.ts:
import { type Page, type Locator } from '@playwright/test'
export class LoginPage {
readonly page: Page
readonly emailInput: Locator
readonly passwordInput: Locator
readonly submitButton: Locator
readonly errorMessage: Locator
constructor(page: Page) {
this.page = page
this.emailInput = page.getByLabel(/email/i)
this.passwordInput = page.getByLabel(/password/i)
this.submitButton = page.getByRole('button', { name: /sign in/i })
this.errorMessage = page.getByRole('alert')
}
async goto() {
await this.page.goto('/login')
}
async login(email: string, password: string) {
await this.emailInput.fill(email)
await this.passwordInput.fill(password)
await this.submitButton.click()
}
}
GitHub Actions CI
Create .github/workflows/playwright.yml:
Adjust commands based on your package manager (get from project.commands):
name: Playwright Tests
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
# For bun projects
- uses: oven-sh/setup-bun@v2
# if using bun
# Install dependencies - adjust for your package manager
# bun: bun install
# pnpm: pnpm install
# yarn: yarn install
# npm: npm ci
- name: Install dependencies
run: bun install
# Install Playwright browsers - use your exec command
- name: Install Playwright Browsers
run: bunx playwright install chromium --with-deps
# Run tests - use your exec command
- name: Run Playwright tests
run: bunx playwright test
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 30
Verification
After setup, verify with:
# Run all tests
nr test:e2e
# Run in UI mode
nr test:e2e:ui
# Run headed (visible browser)
nr test:e2e:headed
# Debug mode
nr test:e2e:debug
# View report
nr test:e2e:report
Key Configuration Options
| Option | Description | Default |
|---|---|---|
testDir |
Directory containing tests | ./tests |
fullyParallel |
Run tests in parallel | true |
retries |
Retry failed tests | 0 |
workers |
Parallel workers | Auto |
timeout |
Test timeout (ms) | 30000 |
trace |
Trace collection | 'on-first-retry' |
screenshot |
Screenshot capture | 'only-on-failure' |
video |
Video recording | 'off' |
baseURL |
Base URL for navigation | Required |
CLI Commands Reference
Use your exec command from project state (bunx, pnpm exec, npx, etc.):
| Command | Description |
|---|---|
{exec} playwright test |
Run all tests |
{exec} playwright test --ui |
UI mode |
{exec} playwright test --headed |
Visible browser |
{exec} playwright test --debug |
Debug mode |
{exec} playwright test file.spec.ts |
Run specific file |
{exec} playwright test --project=chromium |
Run specific project |
{exec} playwright codegen |
Generate tests |
{exec} playwright show-report |
Open HTML report |
Replace {exec} with your package manager's exec command (e.g., bunx, pnpm exec, npx).
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
project-detection
Detects project type, package manager, and monorepo structure. Returns correct commands for test/build/lint/dev. Run at project initialization and cache results in state. Use before running any build/test commands.
update-state
Programmatically update marathon-ralph state file using deterministic jq commands. Use this instead of manually editing the JSON file.
setup-vitest
Configure Vitest for unit and integration testing. Use when setting up a test framework, when no test runner is detected, or when the user asks to configure testing.
write-playwright-test
Write Playwright E2E tests using fixtures and best practices. Use when creating E2E tests, writing browser automation tests, or testing user flows.
visual-verification
Visually verify implemented features work correctly before marking complete. Use when testing UI changes, verifying web features, or checking user flows work in the browser.
sqlite
Didn't find tool you were looking for?