Learn Playwright - CI/CD Integration
Episode 14 of 23

Learn Playwright - CI/CD Integration

This episode covers integrating Playwright into GitHub Actions, GitLab CI, Jenkins, and Azure Pipelines, the difference between headless and headed runs in CI, managing test artifacts, as well as parallel execution and matrix runs for faster feedback.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Tests that only run on a laptop are tests that can be ignored. This episode 14 brings your suite to CI/CD — running tests automatically on every commit, producing artifacts that can be reviewed, and giving the team fast feedback.

CI is a different environment from local: headless, no human input, and often running in parallel. This episode covers proven integration patterns for GitHub Actions, GitLab CI, Jenkins, and Azure Pipelines, including how to capture test artifacts and run matrices for many browsers at once.

Integration into GitHub Actions

Basic Workflow

GitHub Actions is the easiest option because Playwright provides an official action:

.github/workflows/e2e.yml
name: End-to-End Tests
 
on:
  push:
    branches: [main, staging]
  pull_request:
 
jobs:
  test:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - uses: actions/install-playwright@v1
        with:
          browsers: chromium,firefox,webkit
      - run: npm ci
      - run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-artifacts
          path: test-results/
          retention-days: 7

actions/install-playwright@v1 installs the browser binaries with automatic caching. upload-artifact only runs on failure (if: failure()) to store test-results — traces and screenshots are available for review after the pipeline goes red.

Deploying a Service in GitHub Actions

For tests that need the application running, use webServer in the Playwright configuration — CI will wait for the server to be ready before running tests:

JSwebServer in the configuration
export default defineConfig({
  webServer: {
    command: 'npm run start',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
  },
});

webServer automatically launches the application, waits for the URL to be ready, then closes it after the suite finishes. With this, CI doesn't need to manage the server process manually.

GitLab CI, Jenkins, and Azure Pipelines

GitLab CI

GitLab CI uses the official Playwright Docker image, which already contains all browser dependencies:

.gitlab-ci.yml
stages:
  - test
 
e2e:
  stage: test
  image: mcr.microsoft.com/playwright:v1.53.0
  script:
    - npm ci
    - npx playwright test
  artifacts:
    when: always
    paths:
      - playwright-report/
      - test-results/
    expire_in: 7 days

mcr.microsoft.com/playwright:v1.53.0 is the official image containing Node.js, browsers, and system dependencies. GitLab stores artifacts with artifacts.when: always so the report is available even when tests succeed.

Jenkins and Azure Pipelines

In Jenkins, the same pattern is written as a pipeline file: npx playwright install --with-deps then npx playwright test, with artifacts archived via archiveArtifacts. Azure Pipelines uses similar steps with the PublishTestResults task or its built-in artifact publishing mechanism.

Headless vs Headed Runs in CI

Always Headless in CI

CI has no display, so tests must run headless. This is already Playwright's default:

Run headless in CI
npx playwright test

By default Playwright runs headless in CI and headed locally when using --headed. To ensure consistency, set headless: true explicitly in the CI configuration, or just leave the correct default.

When Headed Is Needed

Headed mode in CI is useful for temporary debugging — for example, when checking behavior that only appears with a GPU. But for normal flows, headless is faster and uses fewer resources.

Test Artifacts: Traces, Videos, Screenshots

Artifact Configuration for CI

Enable artifacts selectively in CI so storage stays efficient:

JSArtifact config for CI
export default defineConfig({
  retries: process.env.CI ? 2 : 0,
  use: {
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
    trace: 'on-first-retry',
  },
});

trace: 'on-first-retry' produces a trace when a test fails on the first attempt and passes on a retry — capturing flakiness that's usually hard to reproduce. Videos and screenshots are only kept for failed tests.

Reviewing Artifacts from CI

After the pipeline finishes, download the artifacts and open the report with:

Open the report from CI
npx playwright show-report playwright-report/

npx playwright show-report playwright-report/ displays the report downloaded from CI. This report contains the trace viewer, screenshots, and videos for every failed test — complete information for debugging without re-running anything.

Parallel Test Execution and Matrix Runs

Built-in Parallelism

Playwright runs tests in parallel by default — multiple workers use multiple processes at once. Set the worker count in the configuration or CI:

Run with 4 workers
npx playwright test --workers=4

--workers=4 limits execution to 4 parallel processes. In CI, adjust it to the runner's resources — too many workers actually slows things down because they compete for CPU and memory.

Matrix Runs for Many Browsers

With GitHub Actions matrices, each browser combination becomes a separate job that can run on a different runner:

Browser matrix run
strategy:
  matrix:
    browser: [chromium, firefox, webkit]
steps:
  - run: npx playwright test --project=${{ matrix.browser }}

--project=${{ matrix.browser }} filters execution to one project per job. A matrix gives resource isolation between browsers and enables clearer per-browser reports.

Closing

Episode 14 sent your suite into the production pipeline: GitHub Actions with the official action and artifact upload, GitLab CI with the official Docker image, Jenkins with archiving, and Azure Pipelines — all with the same principles: headless runs, selective failure artifacts, and matrix runs to broaden browser coverage.

Key takeaways:

  • Use the official Playwright action or image so browsers are installed in CI.
  • webServer makes CI launch and wait for the application automatically.
  • Screenshot, video, and trace artifacts are captured only for failed tests.
  • Headless is the default and the right choice for CI.
  • Matrix runs execute per-browser in separate jobs for clear feedback.

In the next episode we'll discuss speed and reliability optimization — optimizing runtime and parallelism, reusing contexts and fixtures with selective retries, reducing flaky tests with stable locators, and using test.fixme and test.skip strategically.

Learn Playwright - CI/CD Integration | Learn Playwright