Advanced Chapter 16 · 13 min read

CI/CD Integration

Run Playwright tests automatically in GitHub Actions and Jenkins, and publish HTML reports as CI artifacts.

Running Playwright in CI

Playwright runs headlessly out of the box, making it ideal for CI environments. The only additional requirement is that the browser dependencies (system libraries) are installed. The official Docker image mcr.microsoft.com/playwright includes everything needed. If you use bare-metal runners, run npx playwright install --with-deps or playwright install --with-deps to install both browsers and their system dependencies in one command.

Tip: Cache the Playwright browser binaries between CI runs using the runner's cache action keyed on the Playwright version. This can cut pipeline setup time from 60 seconds to under 5 seconds.

GitHub Actions

GitHub Actions has first-class support for Playwright. Use the actions/upload-artifact action to publish the HTML report so it is available for download from the workflow run summary. For pull request workflows, use path filtering so tests only run when application code changes, not on documentation-only commits.

Jenkins Pipeline

In Jenkins, run Playwright inside the official Docker agent to guarantee a clean, reproducible environment. Archive the playwright-report/ directory as a post-build artifact and publish the HTML report using the Jenkins HTML Publisher plugin. Use the retry directive in the pipeline to automatically re-run flaky test stages.

.github/workflows/playwright.yml
# .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: Cache Playwright browsers
        uses: actions/cache@v4
        with:
          path: ~/.cache/ms-playwright
          key: playwright-${{ hashFiles('package-lock.json') }}

      - name: Install Playwright browsers
        run: npx playwright install --with-deps

      - name: Run Playwright tests
        run: npx playwright test
        env:
          BASE_URL: http://localhost:3000
          CI: 'true'

      - name: Upload HTML report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30
Jenkinsfile
// Jenkinsfile — Playwright Java tests in Docker
pipeline {
  agent {
    docker {
      image 'mcr.microsoft.com/playwright/java:v1.44.0-jammy'
      args '--ipc=host'
    }
  }

  stages {
    stage('Install') {
      steps {
        sh 'mvn dependency:resolve'
      }
    }

    stage('Test') {
      steps {
        sh 'mvn test -Dheadless=true'
      }
      post {
        always {
          junit 'target/surefire-reports/*.xml'
          archiveArtifacts artifacts: 'target/playwright-report/**'
        }
      }
    }
  }

  post {
    failure {
      slackSend message: "Playwright tests failed on ${env.BRANCH_NAME}"
    }
  }
}
.github/workflows/playwright-python.yml
# .github/workflows/playwright-python.yml
name: Playwright Python Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.11', '3.12']
      fail-fast: false

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install Python dependencies
        run: |
          pip install -r requirements.txt
          pip install pytest-playwright pytest-html

      - name: Cache Playwright browsers
        uses: actions/cache@v4
        with:
          path: ~/.cache/ms-playwright
          key: pw-py-${{ hashFiles('requirements.txt') }}

      - name: Install browsers
        run: playwright install --with-deps chromium

      - name: Run tests
        run: pytest --browser chromium --html=report.html

      - name: Upload report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: report-py${{ matrix.python-version }}
          path: report.html

Playwright Advanced CI/CD Integration

Written by PV

© 2026 All Rights Reserved