Overview
The e2e-runner agent is an expert end-to-end testing specialist. Its mission is to ensure critical user journeys work correctly by creating, maintaining, and executing comprehensive E2E tests with proper artifact management and flaky test handling.
name
string
default: "e2e-runner"
Agent identifier
Uses Claude Sonnet for E2E test generation and maintenance
Available tools: Read, Write, Edit, Bash, Grep, Glob
When to Use
Testing critical user flows (auth, checkout, core features)
After implementing new user-facing features
Before production deployments
Maintaining existing E2E test suite
The e2e-runner agent activates PROACTIVELY for generating, maintaining, and running E2E tests.
Core Responsibilities
Test Journey Creation — Write tests for user flows (prefer Agent Browser, fallback to Playwright)
Test Maintenance — Keep tests up to date with UI changes
Flaky Test Management — Identify and quarantine unstable tests
Artifact Management — Capture screenshots, videos, traces
CI/CD Integration — Ensure tests run reliably in pipelines
Test Reporting — Generate HTML reports and JUnit XML
Prefer Agent Browser over raw Playwright — Semantic selectors, AI-optimized, auto-waiting, built on Playwright.
# Setup
npm install -g agent-browser && agent-browser install
# Core workflow
agent-browser open https://example.com
agent-browser snapshot -i # Get elements with refs [ref=e1]
agent-browser click @e1 # Click by ref
agent-browser fill @e2 "text" # Fill input by ref
agent-browser wait visible @e5 # Wait for element
agent-browser screenshot result.png
Fallback: Playwright
When Agent Browser isn’t available, use Playwright directly.
npx playwright test # Run all E2E tests
npx playwright test tests/auth.spec.ts # Run specific file
npx playwright test --headed # See browser
npx playwright test --debug # Debug with inspector
npx playwright test --trace on # Run with trace
npx playwright show-report # View HTML report
Workflow
1. Plan
Identify critical user journeys (auth, core features, payments, CRUD)
Define scenarios: happy path, edge cases, error cases
Prioritize by risk: HIGH (financial, auth), MEDIUM (search, nav), LOW (UI polish)
2. Create
Use Page Object Model (POM) pattern
Prefer data-testid locators over CSS/XPath
Add assertions at key steps
Capture screenshots at critical points
Use proper waits (never waitForTimeout)
3. Execute
Run locally 3-5 times to check for flakiness
Quarantine flaky tests with test.fixme() or test.skip()
Upload artifacts to CI
Example: User Authentication Flow
import { test , expect } from '@playwright/test' ;
test . describe ( 'User Authentication' , () => {
test ( 'user can sign up with email and password' , async ({ page }) => {
// Navigate to signup page
await page . goto ( '/signup' );
// Fill in form
await page . fill ( '[data-testid="email-input"]' , '[email protected] ' );
await page . fill ( '[data-testid="password-input"]' , 'SecurePass123!' );
await page . fill ( '[data-testid="confirm-password-input"]' , 'SecurePass123!' );
// Submit form
await page . click ( '[data-testid="signup-button"]' );
// Wait for redirect to dashboard
await expect ( page ). toHaveURL ( '/dashboard' );
// Verify welcome message
await expect ( page . locator ( '[data-testid="welcome-message"]' ))
. toContainText ( 'Welcome' );
// Take screenshot
await page . screenshot ({ path: 'signup-success.png' });
});
test ( 'shows error for invalid email' , async ({ page }) => {
await page . goto ( '/signup' );
await page . fill ( '[data-testid="email-input"]' , 'invalid-email' );
await page . fill ( '[data-testid="password-input"]' , 'SecurePass123!' );
await page . click ( '[data-testid="signup-button"]' );
// Verify error message
await expect ( page . locator ( '[data-testid="email-error"]' ))
. toBeVisible ();
await expect ( page . locator ( '[data-testid="email-error"]' ))
. toContainText ( 'Invalid email format' );
});
});
Page Object Model (POM)
// pages/LoginPage.ts
export class LoginPage {
constructor ( private page : Page ) {}
async goto () {
await this . page . goto ( '/login' );
}
async login ( email : string , password : string ) {
await this . page . fill ( '[data-testid="email-input"]' , email );
await this . page . fill ( '[data-testid="password-input"]' , password );
await this . page . click ( '[data-testid="login-button"]' );
}
async getErrorMessage () {
return this . page . locator ( '[data-testid="error-message"]' ). textContent ();
}
}
// tests/auth.spec.ts
import { test , expect } from '@playwright/test' ;
import { LoginPage } from '../pages/LoginPage' ;
test ( 'user can log in' , async ({ page }) => {
const loginPage = new LoginPage ( page );
await loginPage . goto ();
await loginPage . login ( '[email protected] ' , 'password123' );
await expect ( page ). toHaveURL ( '/dashboard' );
});
Key Principles
Use Semantic Locators [data-testid="..."] > CSS selectors > XPath
Wait for Conditions waitForResponse() > waitForTimeout()
Auto-Wait Built In page.locator().click() auto-waits; raw page.click() doesn’t
Isolate Tests Each test should be independent; no shared state
Fail Fast Use expect() assertions at every key step
Trace on Retry Configure trace: 'on-first-retry' for debugging failures
Flaky Test Handling
// Quarantine flaky test
test ( 'flaky: market search' , async ({ page }) => {
test . fixme ( true , 'Flaky - Issue #123' );
// Test implementation...
});
// Identify flakiness by running test multiple times
// npx playwright test --repeat-each=10
Common causes:
Race conditions (use auto-wait locators)
Network timing (wait for response)
Animation timing (wait for networkidle)
Configuration Example
// playwright.config.ts
import { defineConfig } from '@playwright/test' ;
export default defineConfig ({
testDir: './tests' ,
timeout: 30000 ,
retries: 2 ,
use: {
baseURL: 'http://localhost:3000' ,
trace: 'on-first-retry' ,
screenshot: 'only-on-failure' ,
video: 'retain-on-failure' ,
} ,
projects: [
{
name: 'chromium' ,
use: { browserName: 'chromium' },
},
{
name: 'firefox' ,
use: { browserName: 'firefox' },
},
] ,
}) ;
Artifact Management
// Capture screenshot
await page . screenshot ({ path: 'screenshot.png' });
// Capture full page screenshot
await page . screenshot ({ path: 'screenshot.png' , fullPage: true });
// Capture video (configured in playwright.config.ts)
// Videos automatically saved on failure
// Capture trace (configured in playwright.config.ts)
// View trace: npx playwright show-trace trace.zip
Success Metrics
All critical journeys passing (100%)
Test duration < 10 minutes
Artifacts uploaded and accessible
Usage Example
# Invoke e2e-runner directly
ask e2e-runner "Create E2E tests for checkout flow"
# Or let it activate automatically
ask "Test the new user registration feature"
# → e2e-runner activates and creates tests
For detailed Playwright patterns, Page Object Model examples, configuration templates, CI/CD workflows, and artifact management strategies, see skill: e2e-testing.
E2E tests are your last line of defense before production. They catch integration issues that unit tests miss. Invest in stability, speed, and coverage.