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

Sharding 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