Parallel Execution and Reporting
Fast feedback is the difference between tests that developers run and tests they skip. Playwright's built-in parallelism, sharding, and CI integration get a 60-minute suite down to minutes — without external infrastructure like Selenium Grid.
Parallel Execution
Playwright runs tests in parallel by default using worker processes. Each worker gets its own browser instance with isolated contexts.
How Workers Work
Worker 1: login.spec.ts → runs all tests in file sequentially
Worker 2: checkout.spec.ts → runs all tests in file sequentially
Worker 3: search.spec.ts → runs all tests in file sequentially
Worker 4: admin.spec.ts → runs all tests in file sequentially
By default, tests in the same file run sequentially; tests in different files run in parallel across workers.
// playwright.config.ts
export default defineConfig({
workers: process.env.CI ? 4 : undefined, // undefined = half CPU cores
fullyParallel: true, // Also parallelize tests within a file
});
Controlling Parallelism
// Run specific tests sequentially (e.g., tests that share external state)
test.describe.serial('payment flow', () => {
test('add to cart', async ({ page }) => { /* ... */ });
test('enter shipping', async ({ page }) => { /* ... */ });
test('complete payment', async ({ page }) => { /* ... */ });
});
// Configure workers per project
export default defineConfig({
projects: [
{ name: 'chromium', use: { browserName: 'chromium' } },
{ name: 'api-tests', testMatch: /.*\.api\.ts/, workers: 8 }, // More workers for API tests
],
});
Sharding Across CI Machines
For large suites, split execution across multiple CI machines:
# Machine 1: runs first quarter of tests
npx playwright test --shard=1/4
# Machine 2: runs second quarter
npx playwright test --shard=2/4
# Machine 3: runs third quarter
npx playwright test --shard=3/4
# Machine 4: runs last quarter
npx playwright test --shard=4/4
GitHub Actions Example
# .github/workflows/e2e.yml
jobs:
test:
strategy:
matrix:
shard: [1/4, 2/4, 3/4, 4/4]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test --shard=${{ matrix.shard }}
- uses: actions/upload-artifact@v4
if: always()
with:
name: test-results-${{ matrix.shard }}
path: test-results/
CI/CD Integration
Docker
Playwright provides official Docker images with all browsers pre-installed:
FROM mcr.microsoft.com/playwright:v1.50.0-noble
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npx playwright test
Common CI Patterns
| Pattern | Purpose |
|---|---|
| Run on PR | Catch regressions before merge |
| Smoke tests on deploy | Verify deployment health |
| Full suite nightly | Comprehensive regression check |
| Shard across machines | Reduce wall-clock time |
| Upload artifacts | Preserve traces and screenshots for debugging |
Trace Viewer
Playwright's Trace Viewer is the most powerful debugging tool for CI failures. It records a complete timeline of every action, network request, DOM snapshot, and console message.
Enabling Traces
// playwright.config.ts
export default defineConfig({
use: {
trace: 'on-first-retry', // Record traces only when tests retry
// Other options: 'on', 'off', 'retain-on-failure'
},
});
Viewing Traces
# Open trace viewer locally
npx playwright show-trace test-results/login-test/trace.zip
# Or open the online viewer and drag-drop the trace file
# https://trace.playwright.dev
The Trace Viewer shows:
- Timeline: Every action with screenshots before and after
- Network: All HTTP requests and responses
- Console: Browser console output
- Source: The test code with the failing line highlighted
- DOM snapshot: Inspect the page state at any point in time
HTML Report
# Generate and open the report
npx playwright show-report
# The report includes:
# - Pass/fail summary per browser
# - Individual test results with duration
# - Screenshots and traces for failed tests
# - Retry history
Merging Shard Reports
When sharding across machines, merge the individual reports:
npx playwright merge-reports ./shard-results --reporter=html
Test Retry Strategy
export default defineConfig({
retries: process.env.CI ? 2 : 0, // Retry twice in CI, never locally
});
// Per-test retry override
test('flaky external service', async ({ page }) => {
test.fixme(); // Mark as known-flaky, skip until fixed
});
Investigating Flaky Tests
- Check Trace Viewer for timing issues
- Look for missing
awaitstatements - Check for shared state between tests
- Look for dependency on external services
- Verify locators are stable (not position-dependent)
Key Takeaways
- Playwright parallelizes tests across worker processes — no external grid infrastructure needed
- Shard across CI machines for linear speed-up of large suites
- Trace Viewer is the primary debugging tool for CI failures — enable
trace: 'on-first-retry' - Use Docker with official Playwright images for reproducible CI environments
- Upload test artifacts (traces, screenshots) in CI for post-failure investigation
- Retry in CI but not locally — local failures should be investigated immediately