level 07 / jenkins-gitlab-azure

Jenkins, GitLab CI & Azure DevOps

Configure Playwright test pipelines across Jenkins, GitLab CI, and Azure DevOps.

CI Platform Comparison

PlatformConfig fileRunnersBest for
GitHub Actions.github/workflows/*.ymlGitHub-hosted or self-hostedOpen source, GitHub repos
GitLab CI.gitlab-ci.ymlGitLab runnersGitLab repos, on-prem
JenkinsJenkinsfileJenkins agentsLegacy enterprise, flexible
Azure DevOpsazure-pipelines.ymlMicrosoft-hosted or self-hostedMicrosoft stack, enterprise
CircleCI.circleci/config.ymlCircleCI cloud or self-hostedOrbs ecosystem

Jenkins Pipeline

// Jenkinsfile (Declarative Pipeline)
pipeline {
  agent {
    docker {
      image 'mcr.microsoft.com/playwright:v1.45.0-jammy'
      args '-u root'
    }
  }

  environment {
    BASE_URL = credentials('staging-base-url')
    API_KEY  = credentials('api-key-secret')
  }

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

    stage('Test') {
      steps {
        sh 'npx playwright test --reporter=junit'
      }
      post {
        always {
          junit 'test-results/*.xml'
          publishHTML(target: [
            reportDir: 'playwright-report',
            reportFiles: 'index.html',
            reportName: 'Playwright Report',
          ])
        }
      }
    }
  }
}

GitLab CI

# .gitlab-ci.yml
image: mcr.microsoft.com/playwright:v1.45.0-jammy

stages:
  - test

variables:
  BASE_URL: $STAGING_URL    # set in GitLab CI/CD → Variables

playwright:
  stage: test
  script:
    - npm ci
    - npx playwright test
  artifacts:
    when: always
    paths:
      - playwright-report/
    expire_in: 7 days
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH == "main"'

GitLab-specific tips:

  • when: always uploads artifacts even on failure
  • rules: replaces only:/except: (modern syntax)
  • Variables set in Settings → CI/CD → Variables (masked/protected)

Azure DevOps

# azure-pipelines.yml
trigger:
  branches:
    include:
      - main
      - 'feature/*'

pool:
  vmImage: ubuntu-latest

variables:
  BASE_URL: $(StagingBaseUrl)    # set in Pipeline → Variables

steps:
  - task: NodeTool@0
    inputs:
      versionSpec: '20.x'

  - script: npm ci
    displayName: Install dependencies

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

  - script: npx playwright test --reporter=junit
    displayName: Run Playwright tests
    env:
      BASE_URL: $(BASE_URL)
      API_KEY: $(ApiKeySecret)   # secret variable

  - task: PublishTestResults@2
    condition: always()
    inputs:
      testResultsFormat: JUnit
      testResultsFiles: 'test-results/*.xml'

  - task: PublishPipelineArtifact@1
    condition: always()
    inputs:
      targetPath: playwright-report
      artifact: playwright-report

CircleCI

# .circleci/config.yml
version: 2.1

orbs:
  node: circleci/node@5

jobs:
  playwright:
    docker:
      - image: mcr.microsoft.com/playwright:v1.45.0-jammy
    steps:
      - checkout
      - node/install-packages:
          pkg-manager: npm
      - run:
          name: Run Playwright tests
          command: npx playwright test
      - store_artifacts:
          path: playwright-report
      - store_test_results:
          path: test-results

workflows:
  test:
    jobs:
      - playwright

Cross-Platform Essentials

# All platforms: use the official Playwright Docker image
image: mcr.microsoft.com/playwright:v1.45.0-jammy

# Never install browsers without --with-deps on Linux
npx playwright install --with-deps chromium

# JUnit reporter for native test result integration
npx playwright test --reporter=junit,html

# Environment variables — never hardcode
# Jenkins: credentials()
# GitLab: $VARIABLE_NAME
# Azure: $(VariableName)
# GitHub: ${{ secrets.SECRET_NAME }}