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/e2e where 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.ts with 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.yml to 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →