Skip to main content

Cross-Browser & CI

Your users do not all use the same browser. Playwright makes it straightforward to test on Chromium, Firefox, and WebKit from a single test suite. Combining this with CI automation ensures every pull request is tested before it merges.

Configuring Browser Projects

Playwright uses the concept of "projects" to run the same tests across different browsers. Each project is a named configuration:

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  retries: 2,
  workers: 4,
  reporter: 'html',
  use: {
    baseURL: 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
  },
  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'] },
    },
    {
      name: 'mobile-safari',
      use: { ...devices['iPhone 13'] },
    },
  ],
});

The devices object includes viewport sizes, user agent strings, and device-specific settings. This means your mobile tests will run at the correct resolution with touch event simulation.

Run a specific project:

npx playwright test --project=firefox

Or run all projects:

npx playwright test

Parallelism

Playwright runs tests in parallel by default. The workers setting controls how many test files execute simultaneously:

export default defineConfig({
  workers: process.env.CI ? 2 : 4,
});

On your local machine, use more workers for faster feedback. In CI, limit workers based on available CPU and memory. Each worker launches its own browser instance, so resource usage scales linearly.

You can also shard tests across multiple CI machines:

# Machine 1
npx playwright test --shard=1/3

# Machine 2
npx playwright test --shard=2/3

# Machine 3
npx playwright test --shard=3/3

Sharding splits your test suite evenly, so three machines finish roughly three times faster than one.

GitHub Actions Workflow

Here is a complete workflow that runs Playwright tests on every pull request:

# .github/workflows/playwright.yml
name: Playwright Tests

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 15

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Install Playwright browsers
        run: npx playwright install --with-deps

      - name: Build application
        run: npm run build

      - name: Run Playwright tests
        run: npx playwright test

      - name: Upload test report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 14

The if: always() condition on the upload step ensures the HTML report is uploaded even when tests fail. This lets you download and inspect the report directly from the GitHub Actions run.

Reporting

Playwright supports multiple reporters. Configure them in playwright.config.ts:

export default defineConfig({
  reporter: [
    ['html', { open: 'never' }],
    ['junit', { outputFile: 'results.xml' }],
    ['list'],
  ],
});
  • html: Interactive report you can open in a browser.
  • junit: XML format that CI tools like GitHub Actions can parse and display.
  • list: Simple console output showing each test result.

Open the HTML report locally after a test run:

npx playwright show-report

Handling Flaky Tests

Flaky tests pass sometimes and fail other times. Playwright helps manage them:

export default defineConfig({
  retries: process.env.CI ? 2 : 0,
});

Setting retries in CI means a test gets up to two more attempts before being marked as failed. Playwright marks retried tests as "flaky" in the report, making them easy to identify and fix.

Key Takeaways

  • Use projects to test across Chromium, Firefox, WebKit, and mobile devices.
  • Control parallelism with workers and distribute across machines with --shard.
  • Always upload test reports as artifacts in CI for easy debugging.
  • Set retries in CI to handle occasional flakiness without blocking merges.
  • Use npx playwright install --with-deps in CI to install browsers with system dependencies.