How to Set Up Playwright E2E Tests Using the e2e-runner Agent in Claude Code
The e2e-runner agent in Claude Code automates Playwright E2E testing by orchestrating the Agent Browser (an AI-augmented Playwright driver) alongside fallback Playwright execution, generating Page-Object Model tests, and managing flaky test quarantine.
The e2e-runner agent serves as the built-in end-to-end testing specialist for the Everything-Claude-Code (ECC) platform. It drives UI verification by preferring the Agent Browser—a Playwright-based, AI-augmented driver—and falling back to raw Playwright when the browser agent is unavailable. This guide walks you through configuring the e2e-runner agent to create, execute, and maintain reliable Playwright E2E tests.
Understanding the e2e-runner Agent Architecture
The e2e-runner agent operates through a dual-mode execution model defined in agents/e2e-runner.md.
Agent Browser (Preferred Mode): An AI-augmented wrapper around Playwright that understands natural language instructions and can generate selectors interactively.
Raw Playwright (Fallback Mode): Standard Playwright execution when the Agent Browser is not installed or explicitly bypassed.
When invoked, the agent plans critical user journeys, creates test files using the Page-Object Model (POM) pattern from the skills/e2e-testing/SKILL.md, executes tests with full artifact capture (screenshots, videos, traces), and automatically quarantines flaky tests using test.fixme() or test.skip().
Prerequisites and Installation
Install the Agent Browser
The e2e-runner prefers the Agent Browser for AI-augmented test generation. Install it globally:
npm install -g agent-browser && agent-browser install
This provides the interactive agent-browser CLI used for generating selectors and driving tests with natural language.
Install Playwright Dependencies
Install the core Playwright test runner and system dependencies as the fallback mechanism:
npm i -D @playwright/test
npx playwright install --with-deps
The --with-deps flag ensures OS-level browser dependencies (Chromium, Firefox, WebKit) are installed.
Configuring Playwright for the e2e-runner
The e2e-runner expects a playwright.config.ts at the repository root. This configuration, referenced in the agent's execution plan, enables parallel execution, multiple reporters, and automatic trace capture:
import { defineConfig, devices } from '@playwright/test'
export default defineConfig({
testDir: './tests/e2e',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: [
['html', { outputFolder: 'playwright-report' }],
['junit', { outputFile: 'playwright-results.xml' }],
['json', { outputFile: 'playwright-results.json' }],
],
use: {
baseURL: process.env.BASE_URL || 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
actionTimeout: 10000,
navigationTimeout: 30000,
},
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: 120000,
},
})
Key configuration aspects for the e2e-runner:
- testDir: Points to
./tests/e2ewhere the agent generates specs - trace: Captures detailed execution traces on first retry for AI analysis
- webServer: Automatically starts the dev server before test execution
- reporter: Outputs HTML, JUnit XML, and JSON formats for comprehensive reporting
Writing Tests with the Page-Object Model
The e2e-runner agent generates tests following the Page-Object Model (POM) pattern defined in skills/e2e-testing/SKILL.md. This separates page structure from test logic.
Page Object Example (tests/pages/ItemsPage.ts)
import { Page, Locator } from '@playwright/test'
export class ItemsPage {
readonly page: Page
readonly searchInput: Locator
readonly itemCards: Locator
readonly createButton: Locator
constructor(page: Page) {
this.page = page
this.searchInput = page.locator('[data-testid="search-input"]')
this.itemCards = page.locator('[data-testid="item-card"]')
this.createButton = page.locator('[data-testid="create-btn"]')
}
async goto() {
await this.page.goto('/items')
await this.page.waitForLoadState('networkidle')
}
async search(query: string) {
await this.searchInput.fill(query)
await this.page.waitForResponse(r => r.url().includes('/api/search'))
await this.page.waitForLoadState('networkidle')
}
async getItemCount() {
return await this.itemCards.count()
}
}
Test Specification (tests/e2e/features/search.spec.ts)
import { test, expect } from '@playwright/test'
import { ItemsPage } from '../../pages/ItemsPage'
test.describe('Item Search', () => {
let itemsPage: ItemsPage
test.beforeEach(async ({ page }) => {
itemsPage = new ItemsPage(page)
await itemsPage.goto()
})
test('should return results for a valid query', async ({ page }) => {
await itemsPage.search('test')
const count = await itemsPage.getItemCount()
expect(count).toBeGreaterThan(0)
await expect(itemsPage.itemCards.first()).toContainText(/test/i)
await page.screenshot({ path: 'artifacts/search-results.png' })
})
test('should handle no‑result queries', async ({ page }) => {
await itemsPage.search('nonexistent‑123')
await expect(page.locator('[data-testid="no-results"]')).toBeVisible()
expect(await itemsPage.getItemCount()).toBe(0)
})
})
Executing Tests Locally
The e2e-runner agent can suggest execution commands based on your environment. You have two execution paths:
Agent Browser Workflow (Preferred):
# Open interactive browser for AI-assisted selector generation
agent-browser open http://localhost:3000
# Capture page snapshots for test generation
agent-browser snapshot -i
# Execute tests if agent-browser provides a wrapper
agent-browser test
Standard Playwright Fallback:
# Run all E2E tests
npx playwright test
# Run specific test file with headed browser for debugging
npx playwright test tests/e2e/features/search.spec.ts --headed
# View HTML report
npx playwright show-report
CI/CD Integration
The e2e-runner agent generates GitHub Actions workflows based on the pattern in .github/workflows/e2e.yml. This configuration installs dependencies, starts the dev server, executes tests, and uploads artifacts:
name: E2E Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test
env:
BASE_URL: ${{ vars.STAGING_URL }}
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
The workflow captures screenshots, videos, and traces on failure, storing them as artifacts for 30 days.
Handling Flaky Tests
The e2e-runner agent automatically identifies and quarantines unstable tests. When a test exhibits inconsistent behavior, the agent suggests marking it with test.fixme() or test.skip():
test('flaky: complex search', async ({ page }) => {
test.fixme(true, 'Flaky - Issue #123')
// Test implementation...
})
This prevents flaky tests from blocking CI pipelines while preserving the test code for future stabilization.
Summary
- The e2e-runner agent in Claude Code orchestrates Playwright E2E testing through the AI-augmented Agent Browser with fallback to standard Playwright.
- Configuration centers on
playwright.config.tswith parallel execution, multi-reporter output, and automatic dev server management. - Test architecture follows the Page-Object Model pattern defined in
skills/e2e-testing/SKILL.md, separating page selectors from test logic. - Execution supports both interactive Agent Browser workflows (
agent-browser open) and standard CLI commands (npx playwright test). - CI integration uses the GitHub Actions template in
.github/workflows/e2e.ymlto install dependencies, run tests against staging URLs, and upload artifact reports. - Flaky test management utilizes
test.fixme()quarantine patterns to maintain pipeline stability.
Frequently Asked Questions
What is the difference between the Agent Browser and standard Playwright?
The Agent Browser is an AI-augmented wrapper around Playwright that understands natural language instructions and can interactively generate selectors by observing user interactions. According to the source code in agents/e2e-runner.md, the e2e-runner prefers this mode for intelligent test generation but falls back to raw Playwright when the Agent Browser is unavailable or when running in standard CI environments.
Where does the e2e-runner agent store its configuration patterns?
The e2e-runner agent references canonical patterns from skills/e2e-testing/SKILL.md, which defines the Page-Object Model structure, recommended directory layout (tests/e2e/ for specs, tests/pages/ for POMs), and configuration standards. The actual Playwright configuration resides in playwright.config.ts at the repository root, while CI workflows are templated in .github/workflows/e2e.yml.
How does the e2e-runner handle test failures in CI?
When tests fail in CI, the e2e-runner leverages Playwright's configured reporters to generate HTML, JUnit XML, and JSON output files. The GitHub Actions workflow in .github/workflows/e2e.yml automatically uploads the playwright-report/ directory as an artifact with a 30-day retention period. Additionally, the configuration captures screenshots, videos, and traces on failure, providing comprehensive debugging material for AI analysis or manual review.
Can I use the e2e-runner without installing the Agent Browser?
Yes, the e2e-runner explicitly supports fallback to standard Playwright when the Agent Browser is not installed. As documented in agents/e2e-runner.md, the agent will suggest standard Playwright CLI commands (npx playwright test) and utilize the playwright.config.ts configuration directly. While you lose the AI-augmented selector generation capabilities, all core E2E functionality—including parallel execution, reporting, and flaky test management—remains fully functional through the standard Playwright runtime.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →