Skip to content

Cypress with Jenkins

Jenkins remains a widely used CI platform in many enterprise environments. This lesson covers configuring a Jenkins pipeline to run Cypress reliably, including caching and artifact archiving.

A Basic Jenkinsfile for Cypress

Unlike GitHub Actions, Jenkins has no official first-party Cypress integration, so a typical setup runs plain shell commands (npm ci, npx cypress run) within a declarative or scripted Jenkinsfile pipeline.

// Jenkinsfile
pipeline {
  agent any
  stages {
    stage('Install') {
      steps { sh 'npm ci' }
    }
    stage('Build') {
      steps { sh 'npm run build' }
    }
    stage('E2E Tests') {
      steps {
        sh 'npm start &'
        sh 'npx wait-on http://localhost:3000'
        sh 'npx cypress run'
      }
    }
  }
}

Each stage represents a distinct pipeline step, visible individually in the Jenkins UI for easier diagnosis of where a failure occurred.

Common Jenkins Pipeline Additions

post {
  always {
    archiveArtifacts artifacts: 'cypress/screenshots/**', allowEmptyArchive: true
    archiveArtifacts artifacts: 'cypress/videos/**', allowEmptyArchive: true
  }
}
  • archiveArtifacts preserves files (like screenshots/videos) beyond the build's lifetime.
  • allowEmptyArchive: true prevents the pipeline from failing when there's nothing to archive (a passing run).
  • A dedicated Docker agent image (covered in the next lesson) avoids installing browsers manually on Jenkins agents.
  • Environment variables (like CYPRESS_baseUrl) can be injected via Jenkins credentials/parameters.

Jenkins + Cypress Cheat Sheet

Key pipeline elements for a reliable Jenkins-based Cypress setup.

Need Jenkins Feature
Run shell commands sh 'command' inside a steps block
Archive screenshots/videos archiveArtifacts in a post { always { ... } } block
Cache dependencies between builds Workspace persistence or a dedicated cache plugin
Inject secrets safely Jenkins Credentials Binding plugin
Run in a consistent environment A Cypress-ready Docker agent image
Publish test results JUnit reporter output + junit step

Caching Dependencies in Jenkins

Jenkins does not have universal built-in dependency caching like some hosted CI providers, teams typically rely on persistent workspace directories, a shared cache plugin, or a pre-built Docker image containing dependencies already installed to avoid slow, repeated installs.

Publishing JUnit-Style Test Results

Configuring Cypress with a JUnit reporter lets Jenkins parse and display individual test results natively in its UI, rather than only showing overall pipeline success/failure.

// cypress.config.js
export default defineConfig({
  reporter: 'junit',
  reporterOptions: {
    mochaFile: 'results/cypress-[hash].xml',
  },
});

// Jenkinsfile
post {
  always {
    junit 'results/*.xml'
  }
}

Common Mistakes

  • Installing browsers manually on Jenkins agents instead of using a maintained Cypress Docker image.
  • Not archiving screenshots/videos, losing debugging context once the build workspace is cleaned.
  • Injecting secrets as plain environment variables in the Jenkinsfile instead of using Credentials Binding.
  • Skipping JUnit reporting, leaving only a pass/fail signal with no per-test visibility in the Jenkins UI.

Key Takeaways

  • Jenkins pipelines run Cypress via plain shell commands inside declarative pipeline stages.
  • archiveArtifacts preserves screenshots and videos beyond the build's own lifetime.
  • A Cypress-ready Docker image avoids manual browser installation on Jenkins agents.
  • JUnit reporting gives Jenkins native, per-test visibility instead of only overall pass/fail.

Pro Tip

If your organization already runs Jenkins with Docker agents, standardize on the official Cypress Docker image (covered next) as your agent image rather than maintaining a custom one, it stays up to date with browser versions that are already verified to work with each Cypress release.