Jenkins bloquea JavaScript en los reportes HTML por defecto: el header de Content Security Policy impide que el reporte de Playwright se renderice a menos que lo relaxes explícitamente desde la Consola de Scripts de Jenkins o la configuración del plugin HTML Publisher. El otro fallo común son las librerías de sistema que faltan en el agente, que la imagen Docker oficial de Playwright soluciona al incluir todas las dependencias de los navegadores. Esta guía cubre el Jenkinsfile completo, desde el ejemplo mínimo funcional hasta un pipeline multi-stage con ejecución paralela de navegadores, sharding entre agentes, manejo de secretos y ejecuciones nocturnas programadas.
Por qué Jenkins sigue siendo relevante
- Muchas empresas tienen años de inversión en infraestructura Jenkins
- Hosting on-premise para requisitos de seguridad y compliance
- Altamente configurable, con plugins para casi todo
- Algunos setups de CI/CD usan Jenkins junto con Kubernetes a escala
Si tu empresa usa Jenkins, no puedes simplemente cambiarte a GitHub Actions. Trabajas con lo que hay.
Requisitos previos
Necesitas Jenkins instalado (on-premise o Jenkins en Docker), un proyecto de Playwright en Git (GitHub, GitLab, Bitbucket, etc.) y los plugins Pipeline, Git, HTML Publisher y JUnit.
Jenkinsfile básico
Los pipelines de Jenkins se definen en un Jenkinsfile en la raíz del repositorio. Hay dos sintaxis: Declarativa (estructurada) y Scripted (Groovy). Usa Declarativa a menos que necesites lógica avanzada.
// Jenkinsfile
pipeline {
agent {
docker {
image 'mcr.microsoft.com/playwright:v1.44.0-jammy'
args '-u root' // Ejecutar como root para evitar problemas de permisos
}
}
environment {
BASE_URL = credentials('staging-base-url') // Desde las credenciales de Jenkins
CI = 'true'
}
stages {
stage('Instalar') {
steps {
sh 'npm ci'
}
}
stage('Ejecutar Tests') {
steps {
sh 'npx playwright test --reporter=list,junit'
}
post {
always {
// Publicar resultados JUnit
junit 'test-results/results.xml'
// Publicar reporte HTML
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'playwright-report',
reportFiles: 'index.html',
reportName: 'Reporte Playwright'
])
}
}
}
}
post {
failure {
// Notificar ante fallo
emailext(
subject: "FALLÓ: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: "Los tests fallaron. Ver: ${env.BUILD_URL}",
to: 'qa-team@miempresa.com'
)
}
}
}Pipeline multi-stage
Un pipeline realista tiene más etapas: linting, tests unitarios y luego 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('Instalar dependencias') {
steps {
sh 'npm ci'
}
}
stage('Lint') {
steps {
sh 'npm run lint'
}
}
stage('Tests unitarios') {
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('Regresión completa') {
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: 'Reporte de regresión completa',
keepAll: true
])
}
}
}
}
}Ejecución paralela de tests
Ejecuta tests en múltiples navegadores en paralelo usando el bloque parallel de Jenkins:
stage('Tests cross-browser') {
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 que esto funcione, tu playwright.config.ts debe escribir en archivos separados por proyecto:
reporter: [
['junit', {
outputFile: `test-results/${process.env.BROWSER || 'all'}-results.xml`
}],
],Y ejecutar con:
BROWSER=chromium npx playwright test --project=chromiumSharding entre múltiples agentes
Para suites grandes, puedes dividir la ejecución entre varios agentes de Jenkins:
pipeline {
agent none // Cada stage elige su propio 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('Combinar reportes') {
agent { docker { image 'mcr.microsoft.com/playwright:v1.44.0-jammy' } }
steps {
// Descargar artefactos de todos los 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: 'Reporte combinado'
])
}
}
}
}
}Credenciales y secretos
Nunca pongas credenciales en el Jenkinsfile. Usa el Credentials Manager de Jenkins:
environment {
// Credencial de tipo string
BASE_URL = credentials('staging-base-url')
// Credencial de usuario + contraseña (crea dos variables de entorno)
ADMIN = credentials('admin-credentials')
// Crea: ADMIN_USR (usuario) y ADMIN_PSW (contraseña)
}
steps {
withCredentials([
string(credentialsId: 'stripe-test-key', variable: 'STRIPE_KEY'),
usernamePassword(
credentialsId: 'db-credentials',
usernameVariable: 'DB_USER',
passwordVariable: 'DB_PASS'
)
]) {
sh 'npx playwright test'
}
}Disparar los tests
En cada push
triggers {
// Revisar SCM cada 5 minutos (menos ideal que webhooks)
pollSCM('H/5 * * * *')
}Mejor opción: configurar un webhook en GitHub o GitLab para que dispare builds de Jenkins automáticamente.
Ejecuciones programadas (nightly)
triggers {
// Ejecutar a las 2 AM cada noche
cron('0 2 * * *')
}En la creación de un PR
Usa el plugin GitHub Branch Source o Multibranch Pipeline. Jenkins ejecuta los tests automáticamente en cada PR y reporta el estado de vuelta a GitHub.
Problemas comunes en Jenkins con Playwright
"No such file or directory: /home/pwuser/..."
Playwright corre como usuario no-root dentro de su imagen Docker. Agrega args '-u root' al agente Docker o ajusta las rutas de archivos.
"Failed to launch chromium: error while loading shared libraries"
Faltan dependencias del sistema. Usa la imagen Docker oficial de Playwright: tiene todo preinstalado.
El reporte HTML no se muestra en Jenkins
El Content Security Policy de Jenkins bloquea JavaScript en los reportes HTML. Ejecuta esto en la Consola de Scripts de Jenkins:
System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "")O configura el plugin HTML Publisher para relajar el CSP.
Los tests pasan en local pero fallan en Jenkins
Revisa: variables de entorno, base URL, configuración del sandbox del navegador. Agrega el flag --no-sandbox si es necesario (los contenedores Docker frecuentemente lo necesitan para Chromium).
Jenkinsfile mínimo funcional
Si lo que quieres es 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'
}
}
}
}
}Este es el mínimo. Empieza aquí y agrega stages, ejecución paralela y notificaciones según lo necesites.
Resumen
| Concepto | Implementación |
|----------|---------------|
| Agente | Imagen Docker oficial de Playwright |
| Secretos | Credentials Manager de Jenkins |
| Resultados | Plugin JUnit + publishHTML |
| Paralelo | Bloque parallel {} o múltiples agentes |
| Sharding | --shard=X/Y + merge-reports |
| Programación | Trigger cron() |
| En PR | Plugin GitHub Branch Source + webhook |
→ See also: CI/CD para QA: GitHub Actions, Jenkins y GitLab Comparados | GitHub Actions para Tests de Playwright: La Configuración Completa (2026) | Ejecución Paralela en Playwright: Workers, Fragmentos y Fragmentación para Mayor Velocidad