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=chromium

Sharding 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.

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

Dependências de sistema ausentes. Use a imagem Docker oficial do Playwright: ela tem tudo pré-instalado.

Relatório HTML não aparece no Jenkins

A 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 Jenkins

Verifique: 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