Running Cypress Tests in Parallel on Multiple GitHub Actions Containers

| 2 min read

This post walks through configuring your existing Cypress tests to execute in parallel on multiple GitHub Actions containers using the Cypress cypress-split plugin.

The cypress-split plugin will handle running the tests in parallel for you similar to how Cypress Cloud does but is a free solution without the extra features of Cypress Cloud.

TL;DR

See this repo for an example solution using the cypress-split Cypress plugin to run tests in parallel on multiple GitHub Actions containers.

If you wish to use a different CI for your tests you can refer to the official documentation here.

For these steps I will be referencing this example Cypress repo which runs tests from 3 files.

Install cypress-split Package

In your existing Cypress test framework install the cypress-split package as a dev dependency.

npm i -D cypress-split

Call Cypress Split from Cypress Config

In your cypress.config.js file add the require to import function cypressSplit form cypress-split.

Call the cypressSplit function with on and config arguments within the setupNodeEvents object and be sure to return config

const { defineConfig } = require('cypress')
const cypressSplit = require('cypress-split')

module.exports = defineConfig({
  e2e: {
    baseUrl: 'https://www.testingnotebook.com',
    setupNodeEvents(on, config) {
      cypressSplit(on, config)
      return config
    },
  },
})

Create your GitHub Workflow

Below is an example of a GitHub Action Workflow which is using this plugin to run the tests in quiet mode.

You can see the strategy is set as 3 contains and the plugin read environment variables strategy.job-total & strategy.job-index to split the test specs per machine, uncomment these values to use.

If any tests fail then a screenshot of the failing test will be published to the job artifacts.

If you don't have a workflow created yet save the below snippet in .github/workflows/main.yml.

name: Cypress Tests
on:
  push:
    branches:
      - main
  schedule:
    - cron: '0 13 * * 0'
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        containers: [1, 2, 3]
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
      - name: Run Cypress tests
        uses: cypress-io/github-action@v5
        with:
          quiet: true
        env:
          SPLIT: # environment variable called strategy.job-total see https://github.com/testingnotebook/cypress-split-example/blob/main/.github/workflows/main.yml#L21
          SPLIT_INDEX: # environment variable called strategy.job-index see https://github.com/testingnotebook/cypress-split-example/blob/main/.github/workflows/main.yml#L22

      - name: Upload screenshots
        uses: actions/upload-artifact@v3.1.3
        if: failure()
        with:
          name: cypress-screenshots
          path: cypress/screenshots

If you are working with GitHub Actions on VSCode you can install an extension like GitHub Actions by Mathieu Dutour to help with the validation. Or you can edit the workflow file directly from GitHubs online editer.

Test Your Workflow

In the e2e directory there are 3 spec files called about.cy.ts, homepage.cy.ts and post.cy.ts so each agent should one of the 3 files.

Below is the output from each agent showing the 3 files were successfully split as expected. You can see the output of these builds on this repo

Agent 1

cypress-split: there are 3 found specs
cypress-split: chunk 1 of 3
cypress-split: specs from the current directory /home/runner/work/cypress-split-example/cypress-split-example
k  spec                   
-  -----------------------
1  cypress/e2e/about.cy.js



  about
    ✓ should avatar and author (2260ms)


  1 passing (2s)

Agent 2

cypress-split: there are 3 found specs
cypress-split: chunk 2 of 3
cypress-split: specs from the current directory /home/runner/work/cypress-split-example/cypress-split-example
k  spec                      
-  --------------------------
1  cypress/e2e/homepage.cy.js



  home page - recent posts
    ✓ should contain recent posts elements (1588ms)


  1 passing (2s)

Agent 3

cypress-split: there are 3 found specs
cypress-split: chunk 3 of 3
cypress-split: specs from the current directory /home/runner/work/cypress-split-example/cypress-split-example
k  spec                  
-  ----------------------
1  cypress/e2e/post.cy.js



  post
    ✓ should contain recent posts elements (1817ms)


  1 passing (2s)

For more information on this package see the official readme.

The code used for this post can be found here.