Learn Cypress - CI/CD Integration
Episode 14 of 23

Learn Cypress - CI/CD Integration

This episode covers integrating Cypress into GitHub Actions, GitLab CI, and Jenkins, the difference between headless mode and headed runs, uploading video and screenshot artifacts, and parallelization and flaky test handling.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Tests that only run on a local machine protect nothing. Episode 14 brings Cypress into the pipeline: integration with GitHub Actions, GitLab CI, and Jenkins, the difference between headless and headed runs, uploading video and screenshot artifacts, and parallelization and flaky test handling.

By the end of this episode, your suite runs on every commit — and the results are readable by the whole team.

Headless Mode vs Headed Runs

Running Without a UI

In CI there is no screen, so Cypress runs in headless mode — the browser runs without a window:

Running the suite headless
npx cypress run

npx cypress run runs all specs without opening a UI. Unlike the interactive cypress open, run mode produces reports and exits with a status code: 0 on success, 1 when there is a failure — this is the code CI uses to mark a build as failed.

Choosing a Browser

Running in a specific browser
npx cypress run --browser firefox

--browser firefox selects the browser to use. For multi-browser suites, run the same command with a different browser on separate CI jobs.

Integration with GitHub Actions, GitLab CI, and Jenkins

GitHub Actions

GitHub Actions uses a YAML workflow file:

GitHub Actions workflow
name: E2E
on: [push, pull_request]
 
jobs:
  e2e:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx cypress run

runs-on: ubuntu-latest determines the runner machine. The npx cypress run step runs the suite and decides whether the job succeeds or fails.

GitLab CI and Jenkins

GitLab uses .gitlab-ci.yml with similar jobs, while Jenkins is configured through a pipeline file or the UI. The core is the same: check out the code, install dependencies, then run Cypress. Use a suitable Node image and cache ~/.cache/Cypress so the binary installation is not repeated on every run.

Uploading Artifacts, Videos, and Screenshots

Storing Artifacts on Failure

Videos and screenshots are only useful if the team can access them. Enable artifact upload in CI:

Uploading Cypress artifacts
- run: npx cypress run
- uses: actions/upload-artifact@v4
  if: failure()
  with:
    name: cypress-artifacts
    path: cypress/screenshots

if: failure() ensures artifacts are only uploaded when the job fails. path: cypress/screenshots specifies the folder to grab. These artifacts become the first evidence when investigating a failure.

Saving Space

Store videos only for failed runs so CI storage does not balloon:

JSVideo only on failure
module.exports = defineConfig({
  e2e: {
    video: process.env.CI ? true : false,
  },
});

video: process.env.CI ? true : false enables video only in CI. Locally, video is disabled so runs are faster and lighter.

Parallelization and Flaky Test Handling

Splitting the Suite Across Multiple Runners

Large suites can be split in parallel. With the Cypress Dashboard, use automatic load balancing:

Running in parallel with load balancing
npx cypress run --record --parallel

--record --parallel sends the run to the Dashboard, which divides specs across many runners. Load balancing distributes the work so every runner finishes around the same time.

Handling Flaky Tests

Even when optimized, flakiness can still appear in CI. Combine built-in retries with proper isolation:

JSRetries in the configuration
module.exports = defineConfig({
  e2e: {
    retries: {
      runMode: 2,
      openMode: 0,
    },
  },
});

retries.runMode: 2 retries failed tests twice during cypress run. openMode: 0 keeps the interactive mode without retries so local debugging is not misleading. Retries are not a cure-all — still investigate the root cause of flakiness in episode 19.

Info

Make sure all CI secrets — such as CYPRESS_RECORD_KEY — are stored in each platform's secret store, not written in workflow files. Secrets exposed in logs cancel out the security of the entire pipeline.

Closing

Episode 14 connected Cypress to the pipeline: headless mode for CI, GitHub Actions, GitLab CI, and Jenkins integration, uploading video and screenshot artifacts, and parallelization with load balancing and controlled retries.

Key takeaways:

  • cypress run runs headless and returns a status code for CI.
  • The CI workflow: checkout, install dependencies, then run Cypress.
  • Upload artifacts with the failure() condition for debugging.
  • Use --record --parallel with the Dashboard for parallelization.
  • Retries in runMode handle flakiness, not hide the root cause.

In the next episode, episode 15, we will cover performance optimization — speeding up execution with component testing and parallel runs, minimizing page loads and redundant setup, selective test execution and grouping, and caching and plugin features.

Learn Cypress - CI/CD Integration | Learn Cypress