Table of contents

How can I integrate Playwright with CI/CD pipelines?

Integrating Playwright with CI/CD pipelines is essential for automated testing, web scraping, and quality assurance workflows. This comprehensive guide covers setup, configuration, and best practices for popular CI/CD platforms including GitHub Actions, Jenkins, GitLab CI, and Azure DevOps.

Understanding Playwright in CI/CD Context

Playwright is particularly well-suited for CI/CD pipelines due to its: - Cross-browser support (Chromium, Firefox, WebKit) - Headless execution capabilities - Built-in waiting mechanisms - Comprehensive debugging tools - Docker support for containerized environments

GitHub Actions Integration

Basic GitHub Actions Workflow

Create a .github/workflows/playwright.yml file in your repository:

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: always()
      with:
        name: playwright-report
        path: playwright-report/
        retention-days: 30

Advanced GitHub Actions Configuration

For more complex scenarios with multiple environments and parallel execution:

name: Cross-Browser Testing
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        project: [chromium, firefox, webkit]
        shard: [1, 2, 3, 4]
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
      with:
        node-version: 18
    - name: Install dependencies
      run: npm ci
    - name: Install Playwright
      run: npx playwright install --with-deps ${{ matrix.project }}
    - name: Run Playwright tests
      run: npx playwright test --project=${{ matrix.project }} --shard=${{ matrix.shard }}/${{ strategy.job-total }}
    - name: Upload blob report to GitHub Actions Artifacts
      if: always()
      uses: actions/upload-artifact@v4
      with:
        name: blob-report-${{ matrix.project }}-${{ matrix.shard }}
        path: blob-report
        retention-days: 1

  merge-reports:
    if: always()
    needs: [test]
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
      with:
        node-version: 18
    - name: Install dependencies
      run: npm ci
    - name: Download blob reports from GitHub Actions Artifacts
      uses: actions/download-artifact@v4
      with:
        path: all-blob-reports
        pattern: blob-report-*
        merge-multiple: true
    - name: Merge into HTML Report
      run: npx playwright merge-reports --reporter html ./all-blob-reports
    - name: Upload HTML report
      uses: actions/upload-artifact@v4
      with:
        name: html-report--attempt-${{ github.run_attempt }}
        path: playwright-report
        retention-days: 14

Jenkins Integration

Jenkins Pipeline Configuration

Create a Jenkinsfile for Jenkins pipeline integration:

pipeline {
    agent any

    tools {
        nodejs "NodeJS-18"
    }

    environment {
        CI = 'true'
        PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = '1'
    }

    stages {
        stage('Install Dependencies') {
            steps {
                sh 'npm ci'
            }
        }

        stage('Install Playwright') {
            steps {
                sh 'npx playwright install --with-deps'
            }
        }

        stage('Run Tests') {
            steps {
                sh 'npx playwright test'
            }
            post {
                always {
                    publishHTML([
                        allowMissing: false,
                        alwaysLinkToLastBuild: true,
                        keepAll: true,
                        reportDir: 'playwright-report',
                        reportFiles: 'index.html',
                        reportName: 'Playwright Report'
                    ])
                }
            }
        }
    }

    post {
        always {
            archiveArtifacts artifacts: 'playwright-report/**/*', fingerprint: true
            junit 'test-results/junit.xml'
        }
    }
}

Jenkins with Docker

For containerized Jenkins builds:

pipeline {
    agent {
        docker {
            image 'mcr.microsoft.com/playwright:v1.40.0-focal'
            args '-u root:root'
        }
    }

    stages {
        stage('Install Dependencies') {
            steps {
                sh 'npm ci'
            }
        }

        stage('Run Playwright Tests') {
            steps {
                sh 'npx playwright test'
            }
        }
    }
}

GitLab CI Integration

GitLab CI Configuration

Create a .gitlab-ci.yml file:

image: node:18

stages:
  - test
  - report

variables:
  CI: "true"

cache:
  paths:
    - node_modules/

before_script:
  - npm ci
  - npx playwright install --with-deps

playwright-tests:
  stage: test
  script:
    - npx playwright test
  artifacts:
    when: always
    paths:
      - playwright-report/
      - test-results/
    reports:
      junit: test-results/junit.xml
    expire_in: 1 week

pages:
  stage: report
  dependencies:
    - playwright-tests
  script:
    - mkdir public
    - cp -r playwright-report/* public/
  artifacts:
    paths:
      - public
  only:
    - main

GitLab CI with Docker

Using the official Playwright Docker image:

image: mcr.microsoft.com/playwright:v1.40.0-focal

stages:
  - test

variables:
  CI: "true"

playwright-tests:
  stage: test
  before_script:
    - npm ci
  script:
    - npx playwright test
  artifacts:
    when: always
    paths:
      - playwright-report/
      - test-results/
    expire_in: 1 week

Azure DevOps Integration

Azure Pipelines Configuration

Create an azure-pipelines.yml file:

trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

variables:
  CI: true

steps:
- task: NodeTool@0
  inputs:
    versionSpec: '18.x'
  displayName: 'Install Node.js'

- script: |
    npm ci
  displayName: 'Install dependencies'

- script: |
    npx playwright install --with-deps
  displayName: 'Install Playwright browsers'

- script: |
    npx playwright test
  displayName: 'Run Playwright tests'

- task: PublishTestResults@2
  inputs:
    testResultsFormat: 'JUnit'
    testResultsFiles: 'test-results/junit.xml'
    failTaskOnFailedTests: true
  condition: succeededOrFailed()
  displayName: 'Publish test results'

- task: PublishHtmlReport@1
  inputs:
    reportDir: 'playwright-report'
    tabName: 'Playwright Report'
  condition: succeededOrFailed()
  displayName: 'Publish HTML report'

Docker Integration

Dockerfile for Playwright

Create a Dockerfile for containerized Playwright execution:

FROM mcr.microsoft.com/playwright:v1.40.0-focal

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .

CMD ["npx", "playwright", "test"]

Docker Compose for Development

version: '3.8'
services:
  playwright:
    build: .
    volumes:
      - ./playwright-report:/app/playwright-report
      - ./test-results:/app/test-results
    environment:
      - CI=true

Configuration Best Practices

Playwright Configuration for CI

Create a playwright.config.js optimized for CI environments:

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: [
    ['html'],
    ['junit', { outputFile: 'test-results/junit.xml' }],
    ['github'] // GitHub Actions integration
  ],
  use: {
    baseURL: process.env.BASE_URL || 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
  ],
  webServer: {
    command: 'npm run start',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
  },
});

Environment Variables

Set up environment-specific configurations:

// In your test files
const config = {
  baseURL: process.env.BASE_URL || 'http://localhost:3000',
  timeout: process.env.CI ? 30000 : 10000,
  retries: process.env.CI ? 2 : 0,
};

Advanced CI/CD Patterns

Conditional Test Execution

# GitHub Actions example
- name: Run smoke tests
  if: github.event_name == 'pull_request'
  run: npx playwright test --grep "@smoke"

- name: Run full test suite
  if: github.ref == 'refs/heads/main'
  run: npx playwright test

Parallel Execution with Sharding

// playwright.config.js
export default defineConfig({
  projects: [
    {
      name: 'setup',
      testMatch: /.*\.setup\.js/,
    },
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
      dependencies: ['setup'],
    },
  ],
  // Enable sharding
  shard: process.env.CI ? { current: 1, total: 4 } : undefined,
});

Test Result Notifications

# Slack notification example
- name: Notify Slack
  if: failure()
  uses: 8398a7/action-slack@v3
  with:
    status: failure
    text: "Playwright tests failed on ${{ github.ref }}"
  env:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

Performance Optimization

Caching Strategies

# Cache Playwright browsers
- name: Cache Playwright browsers
  uses: actions/cache@v3
  with:
    path: ~/.cache/ms-playwright
    key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}

Resource Management

// Optimize for CI environments
export default defineConfig({
  workers: process.env.CI ? 1 : undefined,
  use: {
    // Reduce resource usage
    launchOptions: {
      args: ['--no-sandbox', '--disable-dev-shm-usage'],
    },
  },
});

Troubleshooting Common Issues

Browser Installation Problems

# Install system dependencies
sudo apt-get update
sudo apt-get install -y libnss3 libnspr4 libdbus-1-3 libatk1.0-0 libdrm2 libxkbcommon0 libgtk-3-0 libatspi2.0-0

# Install Playwright browsers
npx playwright install --with-deps

Memory Issues

# Increase memory limit
- name: Run tests with increased memory
  run: NODE_OPTIONS="--max-old-space-size=4096" npx playwright test

Security Considerations

Secrets Management

# GitHub Actions secrets
env:
  API_KEY: ${{ secrets.API_KEY }}
  DATABASE_URL: ${{ secrets.DATABASE_URL }}

Network Security

// Restrict network access
export default defineConfig({
  use: {
    extraHTTPHeaders: {
      'Authorization': `Bearer ${process.env.API_TOKEN}`,
    },
  },
});

Monitoring and Reporting

Test Analytics

// Custom reporter for analytics
class CustomReporter {
  onTestEnd(test, result) {
    // Send metrics to monitoring service
    console.log(`Test ${test.title}: ${result.status}`);
  }
}

export default defineConfig({
  reporter: [['html'], [CustomReporter]],
});

Integrating Playwright with CI/CD pipelines enables automated testing, continuous quality assurance, and reliable web scraping workflows. By following these configurations and best practices, you can create robust, scalable automation pipelines that ensure your applications maintain high quality standards throughout the development lifecycle.

For more advanced automation scenarios, consider exploring how to handle authentication in Puppeteer for comparison with Playwright's authentication handling, or learn about using Puppeteer with Docker to understand containerization patterns that also apply to Playwright deployments.

Try WebScraping.AI for Your Web Scraping Needs

Looking for a powerful web scraping solution? WebScraping.AI provides an LLM-powered API that combines Chromium JavaScript rendering with rotating proxies for reliable data extraction.

Key Features:

  • AI-powered extraction: Ask questions about web pages or extract structured data fields
  • JavaScript rendering: Full Chromium browser support for dynamic content
  • Rotating proxies: Datacenter and residential proxies from multiple countries
  • Easy integration: Simple REST API with SDKs for Python, Ruby, PHP, and more
  • Reliable & scalable: Built for developers who need consistent results

Getting Started:

Get page content with AI analysis:

curl "https://api.webscraping.ai/ai/question?url=https://example.com&question=What is the main topic?&api_key=YOUR_API_KEY"

Extract structured data:

curl "https://api.webscraping.ai/ai/fields?url=https://example.com&fields[title]=Page title&fields[price]=Product price&api_key=YOUR_API_KEY"

Try in request builder

Related Questions

Get Started Now

WebScraping.AI provides rotating proxies, Chromium rendering and built-in HTML parser for web scraping
Icon