Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
To run Playwright reliably in CI/CD, install your Node dependencies and the exact Playwright browser binaries (including Linux system packages), run with a CI-safe timeout, and publish reports and failure diagnostics as artifacts. A stable first implementation uses one Playwright worker, an explicit globalTimeout, and a trusted artifact store. GitHub Actions provides a straightforward push and pull-request workflow; Harness maps the same commands into a CI Build stage and can add browser, platform, or shard matrices through looping strategies.
Start with a single reproducible job, then add sharding or matrices only after reports, traces, and retention are working. This guide shows the concrete configuration for both platforms, explains when each scaling method is appropriate, and covers the failure modes that most often make browser tests unreliable.
As an Amazon Associate I earn from qualifying purchases.
Recommended Free Tools
What must a Playwright CI pipeline do?
A production-ready pipeline has five responsibilities: create a reproducible operating environment, install project packages and browser binaries, execute tests with bounded time and controlled concurrency, preserve useful diagnostics, and prevent secrets or customer data from entering artifacts. Omitting any one of these can produce failures that are difficult to reproduce locally or leave the team without a report when a job is killed.
- Environment: use a Linux runner with the Playwright Docker image, or install the required operating-system packages with
npx playwright install --with-deps. - Dependencies: run
npm cifrom the lockfile, then install browsers. Installing only the npm package does not install browser executables. - Execution: begin with one worker in CI for stability and reproducibility. Add sharding or a matrix when the suite and diagnostics are already dependable.
- Time limits: set Playwright’s
globalTimeoutand keep the CI job timeout comfortably higher so the runner can finish and publish results. - Evidence: publish the HTML report, and retain traces, screenshots, videos, and JUnit XML when your workflow or test-results system needs them.
The official Playwright CI guidance recommends setting workers to 1 in CI environments. This is a baseline, not a claim that one worker is always fastest: parallelism belongs at the shard or matrix level once the pipeline is stable.
How should I make the execution environment reproducible?
Choose either a Playwright-provided Docker image or a runner on which you install browser and operating-system dependencies. Pin the Playwright package and browser image versions together where practical; a mismatch can change browser behavior between jobs.
Option 1: install dependencies on the runner
The portable sequence on a Linux runner is:
- Check out the repository.
- Run
npm ciso the lockfile, rather than a floating dependency range, controls the install. - Run
npx playwright install --with-depsto install Playwright browsers and the Linux packages they require. - Run
npx playwright test.
This approach works well on GitHub-hosted runners and Harness infrastructure where you control the base image. It is also easy to update, because the package version determines which browser revision is installed.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Option 2: use a Playwright Docker image
A Playwright image packages browsers and their system dependencies in advance. Use the image tag that corresponds to the Playwright version in your project, rather than relying on an unpinned latest tag. Docker improves repeatability and startup consistency, but your CI service must support the image and your team must maintain the image-version policy.
Which environment choice is better?
| Choice | Reproducibility | Operational trade-off | Good fit |
|---|---|---|---|
Runner plus install --with-deps |
Controlled by lockfile, Playwright version, and runner image | Downloads browsers and packages during the job | GitHub-hosted runners or teams wanting a simple pipeline |
| Playwright Docker image | High when the image tag is pinned with the package version | Requires container support and image-version governance | Harness, Kubernetes, or self-managed infrastructure with a standard image |
What Playwright configuration is safe for CI?
Put the suite-wide ceiling in playwright.config.ts, select reporters based on whether the job is single or sharded, and retain traces only when they help diagnose failures.
import { defineConfig } from '@playwright/test';
export default defineConfig({
globalTimeout: 15 * 60 * 1000,
workers: process.env.CI ? 1 : undefined,
reporter: process.env.CI ? 'blob' : 'html',
use: {
trace: 'retain-on-failure'
}
});
The timeout value above is an example policy; choose a ceiling that fits your suite and keep the provider’s job timeout higher. Without a Playwright-level upper bound, a CI provider may terminate the process before Playwright writes a report. For a single, non-sharded job, use the HTML reporter directly. Add JUnit output when another CI view consumes XML. For sharded jobs, use the blob reporter so each shard’s results and attachments can be merged.
Do not treat the sample timeout as a universal performance target. Measure normal and worst-case suite duration in your environment, then leave enough provider time for browser startup, artifact collection, and report upload.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
How do I run Playwright in GitHub Actions?
Create a workflow that runs on pushes and pull requests, installs Node dependencies and browsers, executes the suite, and uploads the HTML report even when tests fail.
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@v5
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
retention-days: 30
The action major versions and retention setting in this example are configuration details that can change, so verify them against the current GitHub Actions documentation when you adopt or update the workflow. The important behavior is the order: checkout, Node setup, npm ci, browser installation, test execution, and conditional report upload.
What should the repository contain?
- A committed lockfile that
npm cican consume. - The Playwright configuration file and test files.
- No downloaded browser binaries checked into source control.
- A documented policy for report retention and access.
What happens when a test fails?
The test step returns a failure status, but the upload step still runs because its condition excludes only cancelled jobs. Review playwright-report/ first; if traces, screenshots, or videos are enabled, ensure those directories are also inside an uploaded artifact path.
How do I add JUnit, traces, screenshots, and videos?
Choose diagnostics according to how the report is consumed. HTML is best for interactive Playwright details, JUnit is useful to a CI test-results view, and traces provide a replayable explanation of a failed test.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problems| Output | Use it for | Pipeline consideration |
|---|---|---|
| HTML report | Interactive failure, step, and attachment review | Upload the generated playwright-report/ directory |
| JUnit XML | External CI test-results dashboards | Write XML to a known path and publish it separately or alongside HTML |
| Blob report | Results from multiple shards | Give each shard a unique artifact name, then merge before publishing HTML |
| Trace | Time-travel debugging of failed tests | Use trace: 'retain-on-failure' to limit volume |
| Screenshots and videos | Visual evidence for intermittent or browser-specific failures | Set retention based on storage, privacy, and debugging needs |
Upload reports and traces only to trusted artifact stores, or encrypt them before upload. A trace can contain page text, URLs, screenshots, cookies, tokens, and authenticated content. Redact test data, avoid real customer accounts, and limit artifact permissions to the people who need to debug failures.
How do I shard Playwright tests in GitHub Actions?
Sharding divides the test suite across independent jobs. Pass each job a shard index and total, write a blob report, upload it under a unique name, and merge all blobs in a dependent job.
name: Playwright Shards
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
jobs:
test:
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: lts/*
- run: npm ci
- run: npx playwright install --with-deps
- name: Run shard
run: npx playwright test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
- uses: actions/upload-artifact@v5
if: ${{ !cancelled() }}
with:
name: blob-report-${{ matrix.shardIndex }}
path: blob-report/
merge-reports:
if: ${{ !cancelled() }}
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: lts/*
- run: npm ci
- name: Download shard reports
uses: actions/download-artifact@v5
with:
pattern: blob-report-*
path: all-blob-reports
merge-multiple: true
- name: Merge reports
run: npx playwright merge-reports --reporter html ./all-blob-reports
- uses: actions/upload-artifact@v5
with:
name: playwright-report
path: playwright-report/
Set fail-fast: false when the merge job must collect reports from every shard, including shards that fail. The merge job needs the same Playwright package version as the shards. A four-shard example is not a performance promise; choose the shard count from queue time, suite duration, runner capacity, and artifact volume.
When should I shard instead of increasing workers?
Use sharding when you need independent jobs, separate failure isolation, or a natural way to spread work across runners. Raising workers inside one job can reduce wall-clock time, but it also increases resource contention and can expose tests that share state. Keep one worker per shard until the suite is demonstrably safe under higher concurrency.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →How do I configure Playwright in a Harness CI pipeline?
In Harness, create a CI Build stage, select the build infrastructure, and place the same three commands in Run steps: npm ci, browser installation, and the Playwright command. Harness supports Cloud, Kubernetes, and other supported infrastructure targets; the correct choice depends on your organization’s runner ownership, network access, and security controls.
Basic stage design
- Create or open a pipeline and add a CI Build stage.
- Select the required build infrastructure, such as Harness Cloud or a Kubernetes-based target.
- Check out the repository using the pipeline’s source settings.
- Add a Run step for
npm ci. - Add a Run step for
npx playwright install --with-deps, unless the selected image already contains the matching browsers and system packages. - Add a Run step for
npx playwright test, or the shard command described below. - Publish the report and diagnostic directories using the artifact mechanism configured for your Harness environment.
How do shared paths work?
Harness Shared Paths keep files available between steps for the lifetime of the stage. Put report, blob, trace, screenshot, and video directories on a shared path when one Run step produces them and a later step uploads or transforms them. Without a shared path, a later step may start with a clean filesystem and have nothing to publish.
How should I use Harness looping strategies?
Harness looping strategies can create browser and platform matrices or split a test suite across multiple jobs. Keep the Playwright command in one Run step and pass browser name, shard index, and shard count as stage or matrix variables. This keeps environment-specific orchestration in the pipeline while test behavior remains in version-controlled Playwright configuration.
Harness offers Visual and YAML editors. Use YAML stored in Git when review, branching, and rollback are priorities; use the Visual editor for inspection or for teams that manage pipeline changes there. Whichever editor you choose, keep the command sequence and artifact paths explicit.
How can I build browser and platform matrices?
A matrix runs the same test contract against several browser or platform variables. It is useful for compatibility coverage, while sharding is primarily a throughput technique; combining both multiplies the number of jobs and artifacts.
| Dimension | Typical variable | What the job changes | Main cost |
|---|---|---|---|
| Browser | browser |
Playwright project or browser selection | More execution and report volume |
| Operating platform | os or infrastructure target |
Runner image, system packages, or Harness infrastructure | Different environment maintenance |
| Shard | shardIndex and shardTotal |
--shard=x/y arguments |
More jobs and a required merge step |
For GitHub Actions, define a matrix under strategy and reference values through matrix expressions. For Harness, use a looping strategy and pass equivalent variables to the Run step. Give every matrix or shard job a unique report path or artifact name so one job cannot overwrite another.
How do I choose between GitHub Actions and Harness?
Both can execute the same Playwright commands. The practical difference is where infrastructure, pipeline governance, matrix orchestration, and cross-tool reporting are managed.
Rank #4
| Decision area | GitHub Actions | Harness CI |
|---|---|---|
| Pipeline definition | Workflow YAML in the repository | Visual or YAML pipeline; Git-managed YAML favors review and versioning |
| Infrastructure | GitHub-hosted or self-hosted runners | Harness Cloud, Kubernetes, or another supported target |
| Scaling | Job matrices and dependent merge jobs | Looping strategies for browser, platform, or suite splits |
| File handoff | Artifacts and workspace paths between jobs | Shared Paths within a stage, plus configured artifact publishing |
| Reporting | Upload artifacts and optionally feed JUnit to a test-results view | Publish artifacts and optionally connect metadata to engineering-insight reporting |
Choose the platform that already governs your source control, runner security, secrets, and retention policy. Do not duplicate orchestration in both systems unless there is a clear ownership boundary; two pipelines for the same suite often create divergent browser versions and confusing status signals.
Free tools Windows power users keep installed
One-click scans. No signup required.
How do I connect GitHub Actions artifacts to Harness engineering insights?
Harness documents a GitHub Actions step that posts artifact metadata to its SEI endpoint using an API key stored in GitHub secrets. Use this only when the organization needs cross-tool artifact or engineering-insight reporting; it is not required to run Playwright or view the HTML report.
- Create a narrowly scoped API key according to your organization’s Harness policy.
- Store it as a repository or organization secret in GitHub, never in workflow YAML or test source.
- Add the documented metadata-posting step after artifact creation.
- Restrict the secret’s permissions and review which artifact names and paths are transmitted.
Keep ordinary Playwright report uploads separate from metadata delivery so a reporting integration failure does not hide the test report itself.
What are the most common CI failures and fixes?
“Executable doesn’t exist” or browser launch errors
The npm package is installed but browser binaries are missing or incompatible. Run npx playwright install --with-deps, or use a Playwright image pinned to the package version; then confirm that the job is not using a different Node project or cache than expected.
Tests pass locally but fail on Linux
Check OS packages, fonts, viewport assumptions, time zones, and case-sensitive paths. Reproduce with the same Playwright Docker image or Linux runner, and avoid relying on developer-machine browser installations.
The job is killed before a report appears
Set globalTimeout in Playwright and make the provider job timeout longer. Leave headroom for dependency installation and artifact upload; otherwise the provider can terminate the process before the reporter flushes files.
The merge job has an empty or incomplete report
Verify that every shard uses the blob reporter, writes to the expected blob-report/ directory, and uploads a unique artifact. Ensure the merge job downloads all artifacts, runs with the same Playwright version, and is not skipped because a dependency failed or was cancelled.
Best Value
Artifacts contain secrets
Inspect trace, video, and screenshot contents in a test branch. Replace real credentials and customer records with synthetic data, restrict artifact access, shorten retention where appropriate, and encrypt uploads when the artifact store is not fully trusted.
Parallel jobs make failures flaky
Return to one worker, isolate test data, and check for shared accounts, fixed ports, or files written to common locations. Add sharding only after each test can run independently and each shard has isolated resources.
What should a rollout checklist include?
- Playwright package and browser image versions are pinned or deliberately updated together.
npm cisucceeds from a clean checkout.- Browsers and Linux dependencies install with
npx playwright install --with-deps, or are present in the selected image. - CI starts with one worker and a documented
globalTimeout. - The provider timeout exceeds Playwright’s global timeout.
- HTML reports upload on success and failure; JUnit is enabled only when consumed.
- Shards use blob reports, unique artifact names,
fail-fast: falsewhen required, and a dependent merge job. - Harness steps use Shared Paths for files consumed later in the same stage.
- Browser, platform, and shard variables are visible in job names and report metadata.
- Traces and other diagnostics follow a retention and access policy.
- Secrets are stored in CI secret managers, not in test code or artifacts.
- Any optional engineering-insight integration uses a restricted API key.
Frequently Asked Questions
Can I cache Playwright browsers in CI?
You can cache downloaded browser directories to reduce repeated downloads, but the cache key must include the operating system and Playwright version. Treat a cache miss as normal and keep an explicit install step so a restored or evicted cache never determines whether the job can run.
Should Playwright tests run against a deployed preview or a local web server?
Either model works if the pipeline waits for the application to become ready and the URL is explicit. A local server reduces dependence on shared environments, while a deployed preview exercises the delivery path; choose one deliberately and record the target URL as job metadata.
How do I rerun only the failed shard?
Use the shard index and total from the failed job and rerun that matrix combination with the same commit, Playwright version, and environment variables. Preserve the original blob artifact if you need the complete run, because a rerun alone represents only the replacement shard.
Do retries make CI reliable?
Retries can preserve signal for intermittent infrastructure failures, but they can also conceal deterministic test defects. Keep retry counts conservative, inspect traces from every failed attempt, and track repeated retries as a maintenance issue rather than treating a green retry as proof of stability.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

