Jenkins по умолчанию блокирует JavaScript в HTML-отчётах: заголовок Content Security Policy не даёт отчёту Playwright рендериться, пока его явно не ослабишь в Jenkins Script Console или настройках плагина HTML Publisher. Вторая типичная проблема: отсутствие системных библиотек на агенте, которую решает официальный Docker-образ Playwright со всеми зависимостями браузеров. Гайд охватывает полный Jenkinsfile: от минимального рабочего примера до многоэтапного пайплайна с параллельным запуском браузеров, шардингом между агентами, управлением секретами и ночными запусками по расписанию.

Почему Jenkins всё ещё актуален

  • Многие Enterprise-компании годами вкладывались в инфраструктуру Jenkins
  • On-premise hosting для требований безопасности и комплаенса
  • Высокая гибкость настройки: плагины практически под всё
  • Часть CI/CD-стеков строится на Jenkins + Kubernetes в масштабе

Если компания использует Jenkins, просто перейти на GitHub Actions не получится. Работаешь с тем что есть.

Предварительные условия

Понадобятся установленный Jenkins (локально или через Jenkins в Docker), Playwright-проект в Git (GitHub, GitLab, Bitbucket и др.) и плагины Jenkins: Pipeline, Git, HTML Publisher, JUnit.

Базовый Jenkinsfile

Пайплайны Jenkins описываются в файле Jenkinsfile в корне репозитория. Есть два синтаксиса: Declarative (структурированный) и Scripted (Groovy). Используй Declarative, если нет потребности в сложной логике.

// Jenkinsfile
pipeline {
    agent {
        docker {
            image 'mcr.microsoft.com/playwright:v1.44.0-jammy'
            args '-u root'  // Запуск от root чтобы избежать проблем с правами
        }
    }
    
    environment {
        BASE_URL = credentials('staging-base-url')  // Из хранилища Jenkins credentials
        CI = 'true'
    }
    
    stages {
        stage('Install') {
            steps {
                sh 'npm ci'
            }
        }
        
        stage('Run Tests') {
            steps {
                sh 'npx playwright test --reporter=list,junit'
            }
            post {
                always {
                    // Публикуем JUnit-результаты
                    junit 'test-results/results.xml'
                    
                    // Публикуем HTML-отчёт
                    publishHTML([
                        allowMissing: false,
                        alwaysLinkToLastBuild: true,
                        keepAll: true,
                        reportDir: 'playwright-report',
                        reportFiles: 'index.html',
                        reportName: 'Playwright Report'
                    ])
                }
            }
        }
    }
    
    post {
        failure {
            // Уведомление при провале
            emailext(
                subject: "FAILED: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                body: "Tests failed. See: ${env.BUILD_URL}",
                to: 'qa-team@mycompany.com'
            )
        }
    }
}

Многоэтапный пайплайн

Реальный пайплайн включает несколько этапов: линтинг, юнит-тесты, затем E2E:

pipeline {
    agent {
        docker {
            image 'mcr.microsoft.com/playwright:v1.44.0-jammy'
            args '-u root'
        }
    }
    
    environment {
        BASE_URL = credentials('staging-url')
        NODE_ENV = 'test'
    }
    
    stages {
        stage('Install Dependencies') {
            steps {
                sh 'npm ci'
            }
        }
        
        stage('Lint') {
            steps {
                sh 'npm run lint'
            }
        }
        
        stage('Unit Tests') {
            steps {
                sh 'npm run test:unit -- --reporter=junit'
            }
            post {
                always {
                    junit 'unit-test-results/*.xml'
                }
            }
        }
        
        stage('Smoke Tests') {
            steps {
                sh '''
                    npx playwright test \
                        --grep @smoke \
                        --project=chromium \
                        --reporter=list,junit
                '''
            }
            post {
                always {
                    junit 'test-results/results.xml'
                }
            }
        }
        
        stage('Full Regression') {
            when {
                anyOf {
                    branch 'main'
                    branch 'release/*'
                }
            }
            steps {
                sh '''
                    npx playwright test \
                        --workers=4 \
                        --reporter=list,junit,html
                '''
            }
            post {
                always {
                    junit 'test-results/results.xml'
                    publishHTML([
                        reportDir: 'playwright-report',
                        reportFiles: 'index.html',
                        reportName: 'Full Regression Report',
                        keepAll: true
                    ])
                }
            }
        }
    }
}

Параллельный запуск тестов

Запуск тестов в нескольких браузерах параллельно через шаг parallel:

stage('Cross-Browser Tests') {
    parallel {
        stage('Chrome') {
            steps {
                sh 'npx playwright test --project=chromium --reporter=junit'
            }
            post {
                always {
                    junit 'test-results/chromium-results.xml'
                }
            }
        }
        
        stage('Firefox') {
            steps {
                sh 'npx playwright test --project=firefox --reporter=junit'
            }
            post {
                always {
                    junit 'test-results/firefox-results.xml'
                }
            }
        }
        
        stage('Safari') {
            steps {
                sh 'npx playwright test --project=webkit --reporter=junit'
            }
            post {
                always {
                    junit 'test-results/webkit-results.xml'
                }
            }
        }
    }
}

Для работы playwright.config.ts должен выводить результаты в отдельные файлы для каждого проекта:

reporter: [
  ['junit', { 
    outputFile: `test-results/${process.env.BROWSER || 'all'}-results.xml` 
  }],
],

И запускать так:

BROWSER=chromium npx playwright test --project=chromium

Шардинг между несколькими агентами

Для больших тест-сьютов разбивай работу между несколькими агентами Jenkins:

pipeline {
    agent none  // Каждый этап выбирает своего агента
    
    stages {
        stage('Test') {
            parallel {
                stage('Shard 1/3') {
                    agent { docker { image 'mcr.microsoft.com/playwright:v1.44.0-jammy' } }
                    steps {
                        sh 'npm ci'
                        sh 'npx playwright test --shard=1/3 --reporter=blob'
                    }
                    post {
                        always {
                            archiveArtifacts 'blob-report/**'
                        }
                    }
                }
                
                stage('Shard 2/3') {
                    agent { docker { image 'mcr.microsoft.com/playwright:v1.44.0-jammy' } }
                    steps {
                        sh 'npm ci'
                        sh 'npx playwright test --shard=2/3 --reporter=blob'
                    }
                    post {
                        always {
                            archiveArtifacts 'blob-report/**'
                        }
                    }
                }
                
                stage('Shard 3/3') {
                    agent { docker { image 'mcr.microsoft.com/playwright:v1.44.0-jammy' } }
                    steps {
                        sh 'npm ci'
                        sh 'npx playwright test --shard=3/3 --reporter=blob'
                    }
                    post {
                        always {
                            archiveArtifacts 'blob-report/**'
                        }
                    }
                }
            }
        }
        
        stage('Merge Reports') {
            agent { docker { image 'mcr.microsoft.com/playwright:v1.44.0-jammy' } }
            steps {
                // Скачиваем артефакты со всех шардов
                copyArtifacts(projectName: env.JOB_NAME, selector: specific(env.BUILD_NUMBER))
                sh 'npx playwright merge-reports --reporter html,junit ./blob-report'
            }
            post {
                always {
                    junit 'test-results/results.xml'
                    publishHTML([
                        reportDir: 'playwright-report',
                        reportFiles: 'index.html',
                        reportName: 'Merged Report'
                    ])
                }
            }
        }
    }
}

Credentials и секреты

Никогда не хардкоди учётные данные в Jenkinsfile. Используй Jenkins Credentials Manager:

environment {
    // String credential
    BASE_URL = credentials('staging-base-url')
    
    // Credential типа username + password (создаёт две переменные окружения)
    ADMIN = credentials('admin-credentials')
    // Создаёт: ADMIN_USR (username) и ADMIN_PSW (password)
}

steps {
    withCredentials([
        string(credentialsId: 'stripe-test-key', variable: 'STRIPE_KEY'),
        usernamePassword(
            credentialsId: 'db-credentials',
            usernameVariable: 'DB_USER',
            passwordVariable: 'DB_PASS'
        )
    ]) {
        sh 'npx playwright test'
    }
}

Триггеры запуска

При каждом пуше

triggers {
    // Опрос SCM каждые 5 минут (хуже чем webhook)
    pollSCM('H/5 * * * *')
}

Лучше: настрой webhook в GitHub/GitLab чтобы Jenkins получал триггер автоматически.

Запуск по расписанию (ночные прогоны)

triggers {
    // Запуск в 2:00 каждую ночь
    cron('0 2 * * *')
}

При создании PR

Используй плагин GitHub Branch Source или Multibranch Pipeline. Jenkins автоматически запускает тесты при каждом PR и отправляет статус обратно в GitHub.

Частые проблемы Jenkins + Playwright

"No such file or directory: /home/pwuser/..."

Playwright внутри Docker-образа работает не от root. Добавь args '-u root' к docker-агенту или скорректируй пути.

"Failed to launch chromium: error while loading shared libraries"

Отсутствуют системные зависимости. Используй официальный Docker-образ Playwright: там всё предустановлено.

HTML-отчёт не отображается в Jenkins

Content Security Policy Jenkins блокирует JavaScript в HTML-отчётах. Выполни в Jenkins Script Console:

System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "")

Или настрой плагин HTML Publisher для ослабления CSP.

Тесты проходят локально, падают в Jenkins

Проверь: переменные окружения, base URL, настройки sandbox браузера. При необходимости добавь флаг --no-sandbox (Docker-контейнерам часто нужен для Chromium).

Минимальный рабочий Jenkinsfile

Если нужно просто что-то работающее:

pipeline {
    agent {
        docker {
            image 'mcr.microsoft.com/playwright:v1.44.0-jammy'
            args '-u root'
        }
    }
    stages {
        stage('Test') {
            steps {
                sh 'npm ci'
                sh 'npx playwright test --reporter=junit'
            }
            post {
                always {
                    junit 'test-results/results.xml'
                }
            }
        }
    }
}

Это минимум. Начинай отсюда, затем добавляй этапы, параллельный запуск и уведомления по мере необходимости.

Краткая справка

| Концепция | Реализация |

|-----------|-----------|

| Агент | Официальный Docker-образ Playwright |

| Секреты | Jenkins Credentials Manager |

| Результаты | Плагин JUnit + publishHTML |

| Параллельность | Блок parallel {} или несколько агентов |

| Шардинг | --shard=X/Y + merge-reports |

| Расписание | Триггер cron() |

| При PR | Плагин GitHub Branch Source + webhook |

Jenkins требует больше настроек чем GitHub Actions, но после конфигурации работает стабильно и гибко. Подход с Jenkinsfile (pipeline-as-code) означает что конфигурация CI живёт в Git рядом с тестами: с версионированием, ревью и воспроизводимостью.

→ See also: CI/CD для QA: сравнение GitHub Actions, Jenkins и GitLab | GitHub Actions для тестов Playwright: полная настройка (2026) | Параллельное выполнение в Playwright: workers, шарды и шардирование для ускорения