Running Playwright tests locally is easy. Running them reliably in CI (fast, with good reporting, and without breaking the bank) takes some setup. Here's what I've learned running Playwright in CI for dozens of projects.
GitHub Actions
GitHub Actions is the most common CI for Playwright. Here's a production-ready config:
# .github/workflows/e2e.yml
name: E2E Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
shard: [1/4, 2/4, 3/4, 4/4]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test --shard=${{ matrix.shard }}
- uses: actions/upload-artifact@v4
if: failure()
with:
name: traces-${{ matrix.shard }}
path: test-results/Key optimizations
- Sharding: Split tests across multiple runners with
--shard. 4 shards typically cuts CI time by 60-75%. - Caching: Cache
node_modulesand Playwright browsers to save 1-2 minutes per run. - Artifacts on failure: Upload traces and screenshots only when tests fail to save storage costs.
- Container image: Use
mcr.microsoft.com/playwrightDocker image for consistent browser versions.
GitLab CI
GitLab CI uses a similar approach but with .gitlab-ci.yml syntax. The key difference is using GitLab's parallel keyword for sharding.
Azure DevOps
Azure Pipelines supports Playwright well. Use matrix strategy for sharding, and publish test results with the JUnit reporter for the built-in test tab.
Cost tips
- Run the full suite on PRs to main, but only affected tests on feature branches.
- Use spot/preemptible instances for test runners when available.
- Set aggressive timeouts (30s per test max) to catch hangs early.
Need CI/CD setup for your test suite? We build test infrastructure for teams who want fast, reliable CI.