level 07 / github-actions
GitHub Actions for Playwright
Configure GitHub Actions to run Playwright tests on every push and pull request.
CI Pipeline Flow
Basic Playwright Workflow
# .github/workflows/playwright.yml
name: Playwright Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- 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 chromium
- name: Run Playwright tests
run: npx playwright test
- name: Upload report
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
Sharded CI (Parallel Across Machines)
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4] # 4 machines in parallel
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 chromium
- name: Run shard
run: npx playwright test --shard=${{ matrix.shard }}/4
- uses: actions/upload-artifact@v4
if: always()
with:
name: blob-report-${{ matrix.shard }}
path: blob-report/
merge-reports:
needs: test
runs-on: ubuntu-latest
if: always()
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20, cache: 'npm' }
- run: npm ci
- uses: actions/download-artifact@v4
with:
path: all-blob-reports
pattern: blob-report-*
merge-multiple: true
- name: Merge reports
run: npx playwright merge-reports --reporter html ./all-blob-reports
- uses: actions/upload-artifact@v4
with:
name: html-report
path: playwright-report/
Environment Variables and Secrets
env:
CI: true # Playwright detects CI — disables video by default
steps:
- name: Run tests
run: npx playwright test
env:
BASE_URL: ${{ vars.STAGING_URL }} # GitHub Variable (non-secret)
API_KEY: ${{ secrets.API_KEY }} # GitHub Secret (masked in logs)
DATABASE_URL: ${{ secrets.DATABASE_URL }}
Store secrets: Repo → Settings → Secrets and variables → Actions
Caching Playwright Browsers
- name: Cache Playwright binaries
uses: actions/cache@v4
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: playwright-${{ hashFiles('package-lock.json') }}
- name: Install browsers (only on cache miss)
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: npx playwright install --with-deps chromium
Saves ~60 seconds per run once cached.
Playwright Config for CI
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
workers: process.env.CI ? 2 : undefined, // fewer workers in CI
retries: process.env.CI ? 2 : 0, // retry flaky tests in CI
reporter: process.env.CI
? [['blob'], ['github']] // github reporter adds PR annotations
: [['html', { open: 'on-failure' }]],
use: {
baseURL: process.env.BASE_URL ?? 'http://localhost:4321',
trace: 'on-first-retry',
video: 'on-first-retry',
screenshot: 'only-on-failure',
},
});
GitHub PR Annotations
With reporter: 'github', failed tests appear inline on the PR diff — no need to read logs:
❌ e2e/auth.spec.ts:42 — login with valid credentials
Error: expect(locator).toBeVisible() ...