Parallel Runs, Traces & CI
Projects, sharding and workers, the Trace Viewer for debugging failures, and Playwright in GitHub Actions.
Parallel execution
Playwright Test runs test files in parallel across worker processes by default. Each worker gets its own browser, and each test its own isolated browser context, so tests can't leak cookies or storage into each other.
npx playwright test --workers=4 # set the number of workers
npx playwright test --workers=1 # run serially (debugging)
// playwright.config.ts
export default defineConfig({
fullyParallel: true, // also parallelise tests within a file
workers: process.env.CI ? 2 : undefined, // undefined = half your CPU cores
});
When a group of tests genuinely must run in order (rare), mark them:
test.describe.configure({ mode: 'serial' });
Parallel tests must be independent: give each test its own data (unique emails, unique order numbers), never a shared account that one test modifies while another reads it.
Projects: browsers and devices
Projects run the same tests under different configurations:
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
{ name: 'Mobile Safari', use: { ...devices['iPhone 14'] } },
],
npx playwright test --project=webkit
Sharding across machines
For large suites, split the tests across several CI machines:
npx playwright test --shard=1/4
npx playwright test --shard=2/4
# ...and so on
The Trace Viewer
A trace records everything about a test run: every action, DOM snapshots before and after each step, console logs, network requests and the source line. It's the fastest way to understand a failure that only happens in CI.
// playwright.config.ts
use: {
trace: 'on-first-retry', // record when a failed test is retried
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
Open a trace locally:
npx playwright show-trace test-results/login-valid-user-chromium-retry1/trace.zip
or drag the trace.zip file onto https://trace.playwright.dev. You can step through the test like a recording and inspect the page at the exact moment it failed.
Other debugging tools:
npx playwright test --debug # step through with the Playwright Inspector
npx playwright test --ui # UI mode: watch, time-travel, pick locators
Running Playwright in GitHub Actions
npm init playwright@latest can generate this workflow for you:
# .github/workflows/playwright.yml
name: Playwright Tests
on:
pull_request:
push:
branches: [main]
jobs:
test:
timeout-minutes: 30
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test
env:
TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 30
Download the playwright-report artifact and run npx playwright show-report playwright-report — failed tests include their trace, screenshot and video.
Sharding in CI
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shard: [1/4, 2/4, 3/4, 4/4]
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 --shard=${{ matrix.shard }}
Retries and flaky detection
retries: process.env.CI ? 2 : 0,
Playwright marks a test that failed and then passed on retry as flaky in the report, separately from passed and failed. Treat that label as a bug to fix — usually a non-awaited assertion, shared data or a missing wait for a network response. See CI Integration & Flaky Tests.
Tagging and filtering
test('checkout with card @smoke', async ({ page }) => { /* ... */ });
test('export invoices as CSV @regression', async ({ page }) => { /* ... */ });
npx playwright test --grep @smoke # only smoke tests
npx playwright test --grep-invert @slow # everything except slow tests
Run @smoke on every pull request and the full suite on merge or nightly. Then review the Playwright interview questions.