# How to Set Up E2E Testing with Playwright in ECC: A Complete Guide

> Learn how to set up E2E testing with Playwright in ECC. This guide offers a turnkey solution with Page-Object-Model patterns and CI/CD workflows for immediate web app testing.

- Repository: [Affaan Mustafa/ECC](https://github.com/affaan-m/ECC)
- Tags: how-to-guide
- Published: 2026-05-26

---

**ECC (Everything Claude Code) provides a turnkey Playwright configuration with a conventional `tests/e2e/` structure, Page-Object-Model patterns, and CI/CD workflows that enable immediate end-to-end testing for any web application.**

ECC (Everything Claude Code) ships with a comprehensive Playwright testing workflow designed for immediate productivity. Setting up E2E testing with Playwright in ECC requires no boilerplate configuration—the framework provides a ready-made [`playwright.config.ts`](https://github.com/affaan-m/ECC/blob/main/playwright.config.ts), organized test directories, and established patterns for handling flaky tests and CI integration. According to the `affaan-m/ECC` source code, the entire configuration is documented in [`skills/e2e-testing/SKILL.md`](https://github.com/affaan-m/ECC/blob/main/skills/e2e-testing/SKILL.md).

## Project Structure and Conventions

ECC follows a conventional **tests/e2e** layout that separates concerns by feature and domain. The directory structure demonstrated in the E2E Testing skill file organizes tests into functional groups:

```text
tests/
├── e2e/
│   ├── auth/                # Authentication flows (login, logout, register)

│   ├── features/            # Core user journeys (browse, search, create)

│   └── api/                 # API-level end-to-end specs

├── fixtures/                # Shared test data and helper functions

└── playwright.config.ts     # Central Playwright configuration

```

This layout keeps test files maintainable and allows parallel execution across different domains. The `fixtures/` directory houses reusable test data, while the `e2e/` directory contains the actual specifications organized by business capability.

## Configuring Playwright in ECC

The framework provides a production-ready [`playwright.config.ts`](https://github.com/affaan-m/ECC/blob/main/playwright.config.ts) inline within [`skills/e2e-testing/SKILL.md`](https://github.com/affaan-m/ECC/blob/main/skills/e2e-testing/SKILL.md). Key configuration parameters include:

- **`testDir: './tests/e2e'`** — Defines the root directory for test discovery.
- **`fullyParallel: true`** — Enables parallel test execution for faster feedback loops.
- **`retries` and `workers`** — Configures CI-specific retry logic and single-worker mode for deterministic builds.
- **`reporter`** — Generates HTML, JUnit, and JSON reports in the `playwright-report/` directory.
- **`use.baseURL`** — Defaults to `http://localhost:3000` but accepts override via the `BASE_URL` environment variable.
- **`projects`** — Executes suites across Chromium, Firefox, WebKit, and optional mobile Chrome devices.
- **`webServer`** — Automatically starts the development server (`npm run dev`) before tests execute, reusing existing servers in CI environments.

The configuration also enables diagnostic capture through `trace`, `screenshot`, and `video` settings that activate on first retry or test failures.

## Implementing the Page Object Model

ECC encourages encapsulating UI interactions in reusable Page Object Model (POM) classes. This pattern, illustrated in the skill file's `ItemsPage` example, centralizes selectors and actions to keep test specifications concise.

A typical POM class holds Playwright `Locator` objects for important elements and exposes high-level action methods:

```typescript
import { Page, Locator } from '@playwright/test'

export class MarketsPage {
  readonly page: Page
  readonly searchInput: Locator
  readonly marketCards: Locator

  constructor(page: Page) {
    this.page = page
    this.searchInput = page.locator('[data-testid="search-input"]')
    this.marketCards = page.locator('[data-testid="market-card"]')
  }

  async goto() {
    await this.page.goto('/markets')
    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 count() {
    return await this.marketCards.count()
  }
}

```

This abstraction separates test logic from implementation details, making tests resilient to UI changes.

## Writing Test Specifications

Test files import POM classes and instantiate them in `beforeEach` hooks. The legacy command documentation in [`legacy-command-shims/commands/e2e.md`](https://github.com/affaan-m/ECC/blob/main/legacy-command-shims/commands/e2e.md) and the skill file provide examples of the "Item Search" flow implementation:

```typescript
import { test, expect } from '@playwright/test'
import { MarketsPage } from '../../pages/MarketsPage'

test.describe('Market Search', () => {
  let pageObj: MarketsPage

  test.beforeEach(async ({ page }) => {
    pageObj = new MarketsPage(page)
    await pageObj.goto()
  })

  test('finds results for a valid query', async () => {
    await pageObj.search('election')
    const count = await pageObj.count()
    expect(count).toBeGreaterThan(0)
    await expect(pageObj.marketCards.first()).toContainText(/election/i)
  })

  test('shows empty state for unknown query', async () => {
    await pageObj.search('nonexistent-xyz')
    await expect(pageObj.page.locator('[data-testid="no-results"]')).toBeVisible()
    expect(await pageObj.count()).toBe(0)
  })
})

```

Tests utilize Playwright's `expect` API for assertions and can capture screenshots on demand using `page.screenshot()`.

## Running Tests Locally

The legacy `/e2e` command shim in [`legacy-command-shims/commands/e2e.md`](https://github.com/affaan-m/ECC/blob/main/legacy-command-shims/commands/e2e.md) documents the standard Playwright CLI workflow:

```bash

# Install Playwright browsers (run once)

npx playwright install --with-deps

# Execute the full test suite

npx playwright test

# Run a specific spec file

npx playwright test tests/e2e/markets/search.spec.ts

# Debug with visible browser window

npx playwright test --headed

# Step-through debugging mode

npx playwright test --debug

# Generate new tests via codegen

npx playwright codegen http://localhost:3000

```

These commands support filtering by file, project, or grep pattern, providing flexible local development workflows.

## Integrating with CI/CD

ECC provides a ready-made GitHub Actions workflow snippet in [`skills/e2e-testing/SKILL.md`](https://github.com/affaan-m/ECC/blob/main/skills/e2e-testing/SKILL.md) that installs dependencies, configures Playwright, executes tests, and uploads artifacts:

```yaml
name: E2E Tests
on: [push, pull_request]

jobs:
  e2e:
    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 sets `BASE_URL` from repository variables, allowing the same test suite to run against staging or production environments without code changes.

## Managing Test Flakiness

ECC recommends two specific patterns for handling unstable tests, documented in the **Flaky Test Patterns** section of the skill file:

1. **Quarantine** — Temporarily disable flaky specs using `test.fixme()` or `test.skip()` while investigating root causes.
2. **Identification** — Surface instability by running specs repeatedly with `--repeat-each=10` or configuring `--retries=3` to distinguish genuine failures from timing issues.

These approaches prevent flaky tests from blocking deployment pipelines while providing data to diagnose underlying synchronization or race condition issues.

## Debugging with Artifacts

When tests fail, ECC's Playwright configuration automatically captures diagnostic artifacts:

- **Screenshots** — Saved to `artifacts/*.png` showing the UI state at failure.
- **Video recordings** — Retained in `artifacts/videos/` only for failed tests.
- **Trace files** — JSON traces in [`artifacts/trace.json`](https://github.com/affaan-m/ECC/blob/main/artifacts/trace.json) enable step-by-step replay via Playwright's Trace Viewer.

The HTML reporter aggregates these artifacts in [`playwright-report/index.html`](https://github.com/affaan-m/ECC/blob/main/playwright-report/index.html), providing a browsable interface for failure analysis. This configuration is defined in the `reporter` section of [`playwright.config.ts`](https://github.com/affaan-m/ECC/blob/main/playwright.config.ts) as implemented in `affaan-m/ECC`.

## Summary

- **ECC provides a complete Playwright setup** in [`skills/e2e-testing/SKILL.md`](https://github.com/affaan-m/ECC/blob/main/skills/e2e-testing/SKILL.md) with conventional directory structures and ready-made configuration.
- **Use the Page Object Model** pattern to encapsulate selectors and actions, keeping test code maintainable and readable.
- **Execute tests locally** using standard Playwright CLI commands documented in [`legacy-command-shims/commands/e2e.md`](https://github.com/affaan-m/ECC/blob/main/legacy-command-shims/commands/e2e.md).
- **Integrate with CI/CD** using the provided GitHub Actions template that supports environment-specific `BASE_URL` configuration.
- **Handle flakiness** through quarantine patterns (`test.fixme`) and identification strategies (`--repeat-each`, `--retries`).
- **Leverage automatic artifacts** including screenshots, videos, and traces for efficient debugging of test failures.

## Frequently Asked Questions

### Does ECC require manual Playwright installation?

No. While you must run `npx playwright install --with-deps` once to download browsers, ECC provides the complete configuration file and directory structure out-of-the-box. The [`playwright.config.ts`](https://github.com/affaan-m/ECC/blob/main/playwright.config.ts) is included in the skill documentation and requires no additional setup beyond installing dependencies.

### How does ECC handle test data isolation?

ECC utilizes Playwright's built-in fixture system through the `tests/fixtures/` directory. The configuration in [`skills/e2e-testing/SKILL.md`](https://github.com/affaan-m/ECC/blob/main/skills/e2e-testing/SKILL.md) demonstrates patterns for sharing authenticated state and test data across specs while maintaining test isolation through the `fullyParallel` setting and independent browser contexts.

### Can I run ECC Playwright tests against staging environments?

Yes. The [`playwright.config.ts`](https://github.com/affaan-m/ECC/blob/main/playwright.config.ts) accepts a `BASE_URL` environment variable that overrides the default `http://localhost:3000` setting. In CI pipelines, you can set this to `${{ vars.STAGING_URL }}` or any target environment, allowing the same test suite to validate production-like deployments without code changes.

### What browsers does ECC support out of the box?

According to the `projects` configuration in [`skills/e2e-testing/SKILL.md`](https://github.com/affaan-m/ECC/blob/main/skills/e2e-testing/SKILL.md), ECC runs tests across **Chromium**, **Firefox**, and **WebKit** by default, with an optional configuration for **mobile Chrome** emulation. This cross-browser matrix ensures compatibility across major rendering engines without additional configuration.