Master Playwright GitHub Actions YAML for CI test runs
A Playwright GitHub Actions workflow read line by line: triggers, jobs, checkout, Node.js setup, npm ci, browser install, test runs and report artifacts.
This article is published in English.
After a Playwright suite lives in GitHub, the next step is making every push and pull request run that suite automatically. GitHub Actions supplies that CI surface, and the YAML workflow Playwright can generate is the contract that turns repository events into browser tests on cloud runners. Teams that skip this step often discover regressions only on a laptop, hours after a merge, when the failure is harder to bisect.
This walkthrough covers:
- how GitHub Actions fits Playwright projects
- what the
onblock decides - how the
jobsblock is organized - what each step in a typical Playwright workflow does
By the end, the structure of a Playwright CI file should be readable enough to edit when Node versions, browsers, or branches change. Treat the sample as a template, not a black box: once each key is clear, swapping runners or adding a smoke job is straightforward.
Introduction to GitHub Actions and YAML File in Playwright
GitHub Actions is CI/CD hosted inside GitHub. It can build, test, and deploy whenever the repository changes. For automation frameworks that value is immediate: the same Playwright commands run on a known runner image without someone opening a laptop and clicking run.
Fresh installs via npm init playwright@latest ask whether to add a GitHub Actions workflow. Accepting that prompt writes a YAML file under .github/workflows. That file names the Node version, installs dependencies, and runs Playwright on pushes and pull requests against GitHub-hosted machines.
If the prompt was declined, the same layout can be added later: create .github/workflows and drop in a workflow YAML by hand.
Playwright documentation ships a ready example in the CI intro guide at https://playwright.dev/docs/ci-intro. That file is the usual starting point for installing deps, preparing browsers, and executing tests on every relevant push or pull request.
Understanding the YAML File in GitHub Actions
The sample below is a typical Playwright workflow. Each section decides when the pipeline starts and what the runner must do before green or red appears on the PR.
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
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
On Section
The on key lists events that start the workflow. It is the entry gate: without a matching event, nothing runs.
In the sample, two event families are wired:
- Push events: A push to
mainormasterstarts the job so direct commits on the default branches are tested immediately. - Pull request events: Opening or updating a PR aimed at
mainormasteralso starts the job, so proposed merges are checked before they land.
Together those triggers cover both integrated commits and review traffic, which is the safety net automation frameworks rely on.
Overview of the Jobs Section
The jobs block is the work plan that runs after a trigger matches. Each job typically declares:
- Job name: A label such as
testthat identifies the unit of work. - Runner environment: The machine image, commonly
ubuntu-latest. - Timeouts and conditions: Guards like
timeout-minutesthat bound how long the job may run. - Steps: Ordered actions—checkout, install, prepare browsers, run tests, upload artifacts.
That section is the backbone of the workflow: environment prep, Playwright execution, and result storage all hang from it. If a job fails, GitHub surfaces the failing step name first, so clear labels here pay off during incident review.
Breakdown of Steps
Checkout Code
The runner must hold the repository files. Checkout is almost always first; without it later steps have nothing to install or execute. Most Playwright workflows use the official checkout action so the working tree matches the commit that triggered the run.
Setup Node.js
Playwright rides on Node. Pinning node-version: lts/* puts the latest long-term support release on the runner so installs and test scripts see a stable runtime. Pinning a major explicitly is also fine when the project already standardizes on one LTS line locally.
Install Dependencies
npm ci installs from package-lock.json into a clean tree. Prefer it over npm install in CI because the lockfile-driven install is reproducible across runs and fails loudly when the lockfile is out of date with package.json.
Install Playwright Browsers
Tests need Chromium, Firefox, and WebKit binaries plus related system packages. This step downloads those browsers so the runner can actually launch them. Skipping it is a common cause of local-green, CI-red failures when developers already have browsers cached on their machines.
Run Playwright Tests
This is the payload: Playwright executes the project tests across the configured browsers and reports pass or fail. Failures bubble as a non-zero exit so the GitHub check blocks merge when the branch protection rules require the workflow.
Upload Test Report
The workflow keeps the generated Playwright report with upload-artifact, often with retention-days: 30 so failures remain inspectable for a month. A guard such as if: ${{ !cancelled() }} skips upload when the run was cancelled instead of completed. Keeping the HTML report as an artifact is usually faster for debugging than re-running the suite solely to reproduce a flaky assertion.