O Jenkins bloqueia JavaScript em relatórios HTML por padrão. O header de Content Security Policy impede o relatório do Playwright de renderizar. Relaxe-o explicitamente no Script Console do Jenkins ou nas configurações do plugin HTML Publisher. A outra falha comum é a ausência de bibliotecas de sistema no agente, problema que a imagem Docker oficial do Playwright resolve ao empacotar todas as dependências dos navegadores.
Por que o Jenkins ainda é relevante
- Muitas empresas têm décadas de investimento em infraestrutura Jenkins
- Hospedagem on-premise para requisitos de segurança e compliance
- Altamente customizável: plugins para praticamente tudo
- Alguns setups de CI/CD usam Jenkins + Kubernetes em escala
Se sua empresa usa Jenkins, não dá para simplesmente migrar para GitHub Actions. Você trabalha com o que tem.
Pré-requisitos
- Jenkins instalado (on-premise ou via Jenkins no Docker)
- Projeto Playwright no Git (GitHub, GitLab, Bitbucket, etc.)
- Plugins do Jenkins: Pipeline, Git, HTML Publisher, JUnit
Jenkinsfile básico
Pipelines Jenkins são definidos em um Jenkinsfile na raiz do repositório. As sintaxes disponíveis são Declarativa (estruturada) e Scripted (Groovy). Use Declarativa a menos que precise de lógica avançada.
// Jenkinsfile
pipeline {
agent {
docker {
image 'mcr.microsoft.com/playwright:v1.44.0-jammy'
args '-u root' // Rodar como root para evitar problemas de permissão
}
}
environment {
BASE_URL = credentials('staging-base-url') // Das credenciais do Jenkins
CI = 'true'
}
stages {
stage('Install') {
steps {
sh 'npm ci'
}
}
stage('Run Tests') {
steps {
sh 'npx playwright test --reporter=list,junit'
}
post {
always {
// Publicar resultados JUnit
junit 'test-results/results.xml'
// Publicar relatório HTML
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'playwright-report',
reportFiles: 'index.html',
reportName: 'Playwright Report'
])
}
}
}
}
post {
failure {
// Notificar em caso de falha
emailext(
subject: "FALHOU: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: "Testes falharam. Veja: ${env.BUILD_URL}",
to: 'time-qa@minhaempresa.com'
)
}
}
}Pipeline multi-estágio
Um pipeline realista tem mais estágios: lint, testes unitários e depois 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
])
}
}
}
}
}Execução paralela de testes
Rode testes em múltiplos navegadores em paralelo usando o step parallel do Jenkins:
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'
}
}
}
}
}Para isso funcionar, seu playwright.config.ts deve gerar arquivos separados por projeto:
reporter: [
['junit', {
outputFile: `test-results/${process.env.BROWSER || 'all'}-results.xml`
}],
],E rodar com:
BROWSER=chromium npx playwright test --project=chromiumSharding entre múltiplos agentes
Para suites grandes, divida entre múltiplos agentes Jenkins:
pipeline {
agent none // Cada stage escolhe seu próprio agente
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 {
// Baixar artefatos de todos os shards
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'
])
}
}
}
}
}Credenciais e segredos
Nunca coloque credenciais diretamente no Jenkinsfile. Use o Credentials Manager do Jenkins:
environment {
// Credencial de string
BASE_URL = credentials('staging-base-url')
// Credencial de usuário + senha (cria duas variáveis de ambiente)
ADMIN = credentials('admin-credentials')
// Cria: ADMIN_USR (usuário) e ADMIN_PSW (senha)
}
steps {
withCredentials([
string(credentialsId: 'stripe-test-key', variable: 'STRIPE_KEY'),
usernamePassword(
credentialsId: 'db-credentials',
usernameVariable: 'DB_USER',
passwordVariable: 'DB_PASS'
)
]) {
sh 'npx playwright test'
}
}Disparando testes
A cada push
triggers {
// Verificar SCM a cada 5 minutos (menos ideal que webhooks)
pollSCM('H/5 * * * *')
}O ideal é configurar webhook no GitHub/GitLab para disparar builds Jenkins automaticamente.
Execuções agendadas (noturnas)
triggers {
// Rodar às 2h da manhã todo dia
cron('0 2 * * *')
}Em criação de PR
Use o plugin GitHub Branch Source ou Multibranch Pipeline. O Jenkins roda os testes automaticamente em cada PR e reporta o status de volta ao GitHub.
Problemas comuns com Jenkins e Playwright
"No such file or directory: /home/pwuser/..."O Playwright roda como usuário não-root dentro da imagem Docker. Adicione args '-u root' ao agente docker ou ajuste os caminhos de arquivo.
Dependências de sistema ausentes. Use a imagem Docker oficial do Playwright: ela tem tudo pré-instalado.
Relatório HTML não aparece no JenkinsA Content Security Policy do Jenkins bloqueia JavaScript em relatórios HTML. Rode isso no Script Console do Jenkins:
System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "")Ou ajuste as configurações do plugin HTML Publisher para relaxar a CSP.
Testes passam localmente, falham no JenkinsVerifique: variáveis de ambiente, base URL, configurações de sandbox do navegador. Adicione a flag --no-sandbox se necessário (containers Docker frequentemente precisam disso para o Chromium).
Jenkinsfile mínimo funcional
Se você só quer algo que funcione:
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'
}
}
}
}
}Esse é o mínimo. Comece aqui, depois adicione estágios, execução paralela e notificações conforme precisar.
Resumo
| Conceito | Implementação |
|---------|--------------|
| Agente | Imagem Docker oficial do Playwright |
| Segredos | Jenkins Credentials Manager |
| Resultados | Plugin JUnit + publishHTML |
| Paralelo | Bloco parallel {} ou múltiplos agentes |
| Sharding | --shard=X/Y + merge-reports |
| Agendamento | Trigger cron() |
| Em PR | Plugin GitHub Branch Source + webhook |
O Jenkins dá mais trabalho que o GitHub Actions, mas uma vez configurado é estável e poderoso. A abordagem Jenkinsfile (pipeline-as-code) significa que sua configuração de CI fica no Git junto com os testes: versionada, revisável e reproduzível.
→ Veja também: CI/CD para QA: GitHub Actions, Jenkins e GitLab Comparados | GitHub Actions para Testes Playwright: A Configuração Completa (2026) | Execução Paralela no Playwright: Workers, Shards e Sharding para Velocidade