Skip to content

CI Browser Tests

Run browser tests in GitHub Actions using Playwright with headless Chromium.

When to use

Add this CI step when your project has Playwright or other browser-based tests that need to run on every push or before publishing to catch rendering and interaction regressions.

The Pattern

Install Playwright browsers as a CI step, then run tests normally. GitHub Actions runners include the system dependencies Playwright needs, so only the browser binary itself must be installed.

Minimal Workflow

yaml
name: Test

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
      
      - run: npm ci
      
      - name: Install Playwright browsers
        run: npx playwright install chromium
      
      - run: npm test

Combined with Publishing

Browser tests can gate a publish step in the same workflow. Tests run first; publishing only happens if they pass:

yaml
name: Publish Package

on:
  push:
    tags:
      - "v*.*.*"
  workflow_dispatch:

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4
      
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          registry-url: "https://npm.pkg.github.com"
          scope: "@your-org"
      
      - run: npm ci
      
      - name: Install Playwright browsers
        run: npx playwright install chromium
      
      - run: npm test
      
      - run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Installing only what you need

Install only the browsers your tests require to keep CI fast:

sh
# Single browser (fastest)
npx playwright install chromium

# Multiple browsers
npx playwright install chromium firefox

# All browsers (slowest)
npx playwright install

Chromium alone covers most test scenarios. Add Firefox or WebKit only if you test cross-browser behavior.

System dependencies

If the runner is missing system libraries (rare on ubuntu-latest), install them:

sh
npx playwright install --with-deps chromium

The --with-deps flag installs both the browser binary and its OS-level dependencies. Only use this when you see missing library errors.

Caching browsers

Browser downloads add 30–60 seconds to each run. Cache them to speed up repeated runs:

yaml
- name: Cache Playwright browsers
  uses: actions/cache@v4
  with:
    path: ~/.cache/ms-playwright
    key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}

- name: Install Playwright browsers
  run: npx playwright install chromium

The install step is still needed but becomes a no-op on cache hit.

Trade-offs

  • Chromium-only vs all browsers: Chromium-only is 2–3x faster to install. Use all browsers only if cross-browser testing is a project requirement.
  • --with-deps vs without: Adding --with-deps increases install time but avoids cryptic missing-library crashes. Use it if you hit those errors.
  • Caching: Adds workflow complexity but saves 30–60 seconds per run. Worth it for frequent CI pipelines.
  • Separate test job vs combined: A dedicated test job can run in parallel with other jobs. A combined test-and-publish job is simpler but serializes everything.