Back to blog
    Playwright
    CI/CD
    GitHub Actions

    Playwright in GitHub Actions: Parallel, Fast, Production-Ready CI

    Run Playwright tests in GitHub Actions with parallel workers, sharding, environment variables, and HTML reports. Includes a full working workflow file.

    · 8 min read

    Playwright in GitHub Actions is the default CI setup for most teams in 2026. Done right, your suite finishes in minutes with parallel workers and produces an HTML report you can browse on every PR. Here is the workflow that works.

    The minimum viable workflow

    `name: Playwright Tests on: [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 - run: npx playwright install --with-deps - run: npx playwright test - uses: actions/upload-artifact@v4 if: always() with: { name: playwright-report, path: playwright-report/ }`

    That is it for a small project. Pin Node to your local version, cache `~/.cache/ms-playwright` to skip the browser install, and you have a 5-minute green build.

    Sharding for parallel execution

    Playwright supports test sharding natively. Use a matrix strategy: `strategy: matrix: { shard: [1/4, 2/4, 3/4, 4/4] }` and pass `--shard=${{ matrix.shard }}` to the test command. Four parallel runners, roughly a quarter of the total time.

    Combine with Playwright's per-worker parallelism (`workers: 4` in config) for true parallel-of-parallel execution.

    Environment variables and secrets

    Store `BASE_URL`, `TEST_EMAIL`, `TEST_PASSWORD`, and any API keys in repository secrets. Reference them in the workflow with `env:`. Never echo secrets directly in workflow steps — they can surface in logs and break the masking on edge cases.

    For test data that rotates often, pull it at runtime from TestAssets via the REST API — your suite reads the same staging credentials your QA team uses, and rotation does not require a workflow file change.

    Caching browsers and dependencies

    Playwright downloads ~300MB of browsers on every fresh install. Cache them: `- uses: actions/cache@v4 with: { path: ~/.cache/ms-playwright, key: playwright-${{ hashFiles('package-lock.json') }} }`. Combined with npm cache, your green path is under 90 seconds.

    HTML reports on every PR

    The default Playwright HTML reporter is great. Upload it as an artifact (always, including on failure) and reviewers can download and browse it locally. For richer integration, use a hosted reporter like Currents or Allure.

    Common gotchas

    Forget `--with-deps` and your CI will work locally but fail with missing system libraries. Forget `if: always()` on the report upload and you will never see the report when you most need it (on failure). Forget to set `workers: 4` in config and your sharded matrix runs serially within each shard.

    Frequently asked questions

    We use essential cookies for core functionality and optional cookies to improve your experience. Learn more about our privacy policy