Playwright CI/CD with GitHub Actions Guide
Learn to build automated test pipelines. Configure GitHub Actions workflows, cache browser binaries, and publish test report artifacts.
playwright-v1-49-matrix
Playwright CI/CD with GitHub Actions Guide
Automated pipelines guarantee that visual and functional regressions are caught before shipping to production. Exposing tests to GitHub Actions speeds up feedback. This guide explains how to build a reliable continuous integration workflow.
Introduction
Manually running test suites before deployment introduces human error and slows down delivery. Continuous Integration (CI) automates this check. Every time developers open a pull request, CI containers spin up, install browsers, and run tests.
Using the official Playwright Docker image or GitHub Actions cache system minimizes container initialization durations.
Pipeline Architecture
The workflow starts on code push events, running parallel browser jobs, and saving reports in storage storage blocks:
graph TD
CodePush["Git: Code Push / Pull Request"] --> TriggerCI["GitHub Actions: Trigger Workflow"]
TriggerCI --> SpinContainer["Spin Up Container: ubuntu-latest"]
SpinContainer --> CacheCheck{"Cache Hit on Browsers?"}
CacheCheck -->Yes
InstallDeps["Install Node & OS dependencies"]
CacheCheck -->No
InstallPW["Install Node, Browsers, & deps"]
InstallDeps --> RunTests["Execute: npx playwright test"]
InstallPW --> RunTests
RunTests --> SaveReports["Save Artifacts: HTML Reports & Trace Logs"]
SaveReports --> FinalStatus["Pipeline Complete (Success/Failure)"]This setup ensures isolated environments for every code verification run.
CI Execution Flow Sequence
The interaction between GitHub runner systems, package managers, and Playwright servers matches this lifecycle sequence:
sequenceDiagram
participant Git as GitHub Repository
participant Runner as Actions Runner (Host)
participant Cache as GitHub Cache API
participant Test as Playwright Runner
Git->>Runner: Pull Request trigger event
Runner->>Runner: Checkout codebase code
Runner->>Cache: Request cached browser binaries
Cache-->>Runner: Cache restored / missed
Runner->>Runner: Install npm dependencies
Note over Runner: Fetch OS libraries if cache missed
Runner->>Test: Run test suite
Test-->>Runner: Test execution results
Runner->>Git: Upload HTML reports (Artifacts)
Runner->>Git: Update commit status check (Pass/Fail)Step-by-Step Workflow Setup
Follow this setup guide to establish a workflow file in your project.
1. Create the YAML Settings File
Write the workflow rules inside .github/workflows/playwright.yml:
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
# 1. Checkout codebase
uses: actions/checkout@v4
# 2. Setup Node.js runtime
uses: actions/setup-node@v4
with:
node-version: lts/*
cache: 'npm'
# 3. Install packages
name: Install dependencies
run: npm ci
# 4. Cache Playwright browser binaries
name: Get Playwright Version
id: playwright-version
run: echo "version=$(npm ls @playwright/test grep @playwright/test
awk -F@ '{print $3}')" >> $GITHUB_OUTPUT
name: Cache Playwright browsers
uses: actions/cache@v4
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }}
# 5. Install browser binaries & dependencies
name: Install Playwright Browsers and system dependencies
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: npx playwright install --with-deps
name: Install system dependencies only
if: steps.playwright-cache.outputs.cache-hit == 'true'
run: npx playwright install-deps
# 6. Execute automation tests
name: Run Playwright tests
run: npx playwright test
# 7. Upload report artifacts on failure
uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 302. Configure Project Sharding
If your test suite takes longer than 15 minutes, configure parallel shards to split execution:
# Parallel runner configuration summary
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
steps:
name: Run Playwright tests
run: npx playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}Configuration and Optimization
Update playwright.config.ts options to support CI environments:
import { defineConfig } from '@playwright/test';
export default defineConfig({
// Limit worker count on single container hosts
workers: process.env.CI ? 1 : undefined,
// Retry failing tests on CI to check for flakiness
retries: process.env.CI ? 2 : 0,
// Configure HTML and blob reporters
reporter: process.env.CI ? 'blob' : 'html',
use: {
// Record traces on retries to save resource sizes
trace: 'on-first-retry',
video: 'on-first-retry',
},
});Pipeline Execution Matrix
The table below contrasts different caching strategies for Playwright CI pipelines.
| Caching Strategy | Pipeline Spin-up Time | Storage Overhead | Configuration Complexity |
|---|---|---|---|
| No Cache (Standard Setup) | 4.8 minutes | 0MB (Fresh fetch) | Minimal |
| Actions Cache (Binary Paths) | 1.8 minutes | ~800MB (Cached zip files) | Medium (Version checks) |
| Docker Base Image Runs | 1.2 minutes | High (Image pull sizes) | High (Dockerfile configurations) |
| Parallel Shards Setup | 0.6 minutes | ~800MB per container thread | High (Matrix configurations) |
Best Practices for Stable Runs
timeout-minutes value inside your workflow job declarations to avoid pricing charges on hung browser processes.Here are a few key practices:
1 on CI.retention-days: 30) to minimize workspace space usages.Common Mistakes to Avoid
| Bad Pattern | Recommended Alternative |
| Running pipelines without timeouts | Add timeout-minutes: 60 in the YAML job |
| Fetching browser binaries on every container build | Implement the actions/cache workflow settings |
| Committing secret API keys inside workflows | Load sensitive items using GitHub Secrets parameters |
Frequently Asked Questions
How do I configure GitHub Secrets in Playwright?
Go to your repository Settings > Secrets and Variables > Actions. Define parameters and reference them in your workflow using ${{ secrets.MY_SECRET }}.
What is the default retention period for artifacts?
GitHub holds upload files for 90 days by default. You can override this using the retention-days parameter in your upload step.
Why do WebKit tests fail on Linux containers?
Linux environments lack Safari dependencies. Ensure your setup step executes npx playwright install-deps or use the official runner.
How do I merge blob reports from parallel shards?
Use the merge-reports CLI command npx playwright merge-reports --reporter=html ./blob-reports in a dependent job step.
Can I run tests against local app servers on CI?
Yes. Use the webServer configuration key inside playwright.config.ts to spin up local apps before tests trigger.
What is the purpose of fail-fast matrix options?
Setting fail-fast: false ensures that other matrix shards continue executing even if one of the jobs fails.
How do I trigger pipelines only on specific branches?
Modify the on configuration parameter inside the workflow YAML structure to target specific path branches (e.g. branches: [main]).
Can I run visual comparison tests on CI?
Yes. Use the --update-snapshots flag locally to generate target baseline screenshots and commit them to the repository for CI comparisons.
Does the official Docker image include browsers?
Yes. The official Playwright Docker images come pre-installed with Node.js and all browser engine dependencies.
How do I run tests on a schedule?
Configure the cron parameter under the on trigger block in the workflow file (e.g. cron: '0 0 * * *').
Summary
Exposing automation suites to GitHub Actions ensures that regressions are resolved before merge actions. Configuring browser caches increases pipeline execution speed.
Related Articles
About The Author
PlaywrightPad Editorial reports on Chromium engines, E2E test optimizations, and AI integration specifications.
Newsletter
Get weekly browser reports sent directly to your inbox.