Skip to main content
Back to blog

Cypress Tests in Azure DevOps Pipeline: Step-by-Step Guide

How to run Cypress tests in Azure DevOps CI/CD pipelines. Covers Cypress installation on CI agents, YAML configuration, video and screenshot artifacts, parallel test execution with Cypress Cloud, and result publishing.

InnovateBits3 min read
Share

Cypress has first-class CI support and runs well on Azure DevOps with minimal configuration. This guide covers everything from basic setup to production-grade parallel execution.


Basic Cypress pipeline

trigger:
  branches:
    include: [main]
 
pool:
  vmImage: ubuntu-latest
 
steps:
  - task: NodeTool@0
    inputs:
      versionSpec: '20.x'
 
  - script: npm ci
    displayName: Install packages
 
  - script: npx cypress verify
    displayName: Verify Cypress install
 
  - script: |
      npx cypress run \
        --browser chrome \
        --reporter junit \
        --reporter-options "mochaFile=cypress/results/results-[hash].xml,toConsole=true"
    displayName: Run Cypress tests
    env:
      CYPRESS_BASE_URL: $(STAGING_URL)
      CYPRESS_TEST_EMAIL: $(TEST_EMAIL)
      CYPRESS_TEST_PASSWORD: $(TEST_PASSWORD)
 
  - task: PublishTestResults@2
    displayName: Publish results
    inputs:
      testResultsFormat: JUnit
      testResultsFiles: 'cypress/results/*.xml'
      mergeTestResults: true
      testRunTitle: Cypress — $(Build.BuildNumber)
    condition: always()
 
  - task: PublishPipelineArtifact@1
    displayName: Upload screenshots and videos
    inputs:
      targetPath: cypress/screenshots
      artifact: cypress-screenshots
    condition: failed()
 
  - task: PublishPipelineArtifact@1
    displayName: Upload videos
    inputs:
      targetPath: cypress/videos
      artifact: cypress-videos
    condition: always()

Cypress configuration for CI

// cypress.config.js
const { defineConfig } = require('cypress')
 
module.exports = defineConfig({
  e2e: {
    baseUrl: process.env.CYPRESS_BASE_URL || 'http://localhost:3000',
    video: true,
    videoCompression: 32,
    screenshotOnRunFailure: true,
    defaultCommandTimeout: process.env.CI ? 10000 : 4000,
    requestTimeout: process.env.CI ? 15000 : 5000,
    pageLoadTimeout: process.env.CI ? 30000 : 10000,
    retries: {
      runMode: 2,    // Retry twice in CI
      openMode: 0,
    },
  },
})

Using environment variables in tests

Cypress environment variables set with CYPRESS_ prefix are available as Cypress.env():

// In pipeline YAML
- script: npx cypress run
  env:
    CYPRESS_BASE_URL: $(STAGING_URL)
    CYPRESS_API_KEY: $(API_KEY)
 
// In test code
cy.request({
  url: `${Cypress.env('BASE_URL')}/api/health`,
  headers: { 'X-API-Key': Cypress.env('API_KEY') }
})

Parallel execution with Cypress Cloud

For large test suites, use Cypress Cloud (formerly Cypress Dashboard) to distribute tests across agents:

strategy:
  matrix:
    Agent1: { MACHINE_NUM: 1 }
    Agent2: { MACHINE_NUM: 2 }
    Agent3: { MACHINE_NUM: 3 }
  maxParallel: 3
 
steps:
  - script: npm ci
  - script: |
      npx cypress run \
        --record \
        --parallel \
        --ci-build-id $(Build.BuildId) \
        --group "Azure CI" \
        --key $(CYPRESS_RECORD_KEY)
    env:
      CYPRESS_RECORD_KEY: $(CYPRESS_RECORD_KEY)
      CYPRESS_BASE_URL: $(STAGING_URL)

Cypress Cloud distributes tests across the 3 agents automatically based on historical execution times.


Adding the junit reporter

npm install --save-dev cypress-multi-reporters mocha-junit-reporter
// reporter-config.json
{
  "reporterEnabled": "spec, mocha-junit-reporter",
  "mochaJunitReporterReporterOptions": {
    "mochaFile": "cypress/results/results-[hash].xml"
  }
}
- script: |
    npx cypress run \
      --reporter cypress-multi-reporters \
      --reporter-options configFile=reporter-config.json

Common errors and fixes

Error: Cypress failed to start: The Cypress App could not be started Fix: Add DISPLAY=:99 or use npx cypress run (not cypress open). On Linux CI agents without a display server, Cypress must run in headless mode — cypress run is headless by default.

Error: Videos are recorded but empty (0 bytes) Fix: Add ffmpeg to the agent or use Microsoft-hosted Ubuntu agents which have it pre-installed. Video recording requires ffmpeg.

Error: Timeout of 4000ms exceeded for page loads Fix: Increase pageLoadTimeout in cypress.config.js for CI runs. Staging environments on CI agents are often accessed over slower network connections.

Error: Tests fail with cy.intercept not intercepting requests Fix: cy.intercept() must be set up before the request is made. Move intercepts to beforeEach hooks that run before cy.visit().

Error: Cypress install hangs in pipeline Fix: Set CYPRESS_INSTALL_BINARY=0 if you don't need the GUI binary (CI-only runs). Or cache the Cypress binary: use Cache@2 task with key based on package-lock.json.

Free newsletter

Stay ahead in AI-driven QA

Get practical tutorials on test automation, AI testing, and quality engineering — straight to your inbox. No spam, unsubscribe any time.

Discussion

Sign in with GitHub to comment · powered by Giscus