How do I run Playwright tests in GitHub Actions?
Written by Jatin Thacker, Automation Architect · Updated
.github/workflows/ that checks out the code, sets up Node, runs npm ci, npx playwright install --with-deps and npx playwright test, then uploads the playwright-report folder as an artifact. GitHub runs it on every push and pull request you list under on:.This answer is one piece of Chapter 27: CI/CD.
- CI/CD with GitHub Actions
- CI with Jenkins
- CI with Azure DevOps
- CI with GitLab CI
- Practice and interview questions: Debugging, Tracing & CI/CD
A pipeline runs the same command you run locally, on a clean machine, every time someone pushes. The workflow below is the one in the Playwright CI guide.
Two steps are easy to get wrong. npx playwright install --with-deps downloads the browsers and the Linux libraries they need; without it the runner has no browser. The upload step has if: ${{ !cancelled() }}, so the report is uploaded even when tests fail, which is exactly when you need it. Without it, the step gets GitHub's default success() check and is skipped after a failing test step.
The config usually changes behaviour on CI through process.env.CI, which GitHub sets. The example config forbids test.only, allows two retries, runs one worker and writes the HTML report without trying to open it. trace: 'on-first-retry' records a trace for any test that needed a retry.
To read a failure, open the run's Artifacts section, download playwright-report, unzip it and run npx playwright show-report on the folder (see qa-083).
The workflow was not pushed for this page. The output is a local run of the same npx playwright test command with CI=true set.
# .github/workflows/playwright.yml
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: lts/*
- name: Install dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 30
// playwright.config.js
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: '.',
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: process.env.CI ? [['list'], ['html', { open: 'never' }]] : 'list',
use: {
baseURL: 'https://practice.learnplayforge.com',
trace: 'on-first-retry',
},
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
});$ CI=true npx playwright test Running 2 tests using 1 worker ok 1 [chromium] › cart.spec.js:3:1 › the cart starts empty (315ms) ok 2 [chromium] › cart.spec.js:8:1 › adding the grinder updates the total (1.2s) 2 passed (2.6s)
if: ${{ !cancelled() }} from the upload step, and a test fails on CI. What happens to the report?Practised in the full course: the drill Conditional artifact upload.
See the chapterRelated questions
AI can write the test now. The job is knowing whether it checks anything. That's what the course teaches, one chapter at a time.
163 lessons · 226 drills · start free