Running Cypress Tests in Parallel on Multiple GitHub Actions Containers
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-splitCall 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/screenshotsIf 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.