info
What you'll learn
- An overview of Continuous Integration
- How to run Cypress tests in Continuous Integration
- How to configure Cypress in various CI Providers
- How to record tests to Cypress Cloud
- How to run tests in parallel on CI
What is Continuous Integration?
Setting up CI
Basics
Running Cypress in Continuous Integration is almost the same as running itlocally in your terminal. You generally only need to do two things:
- Install Cypress
npm install cypress --save-dev
- Run Cypress
cypress run
Depending on which CI provider you use, you may need a config file. You'll wantto refer to your CI provider's documentation to know where to add the commandsto install and run Cypress. For more configuration examples check out ourexamples.
Boot your server
Challenges
Typically you will need to boot a local server prior to running Cypress. Whenyou boot your web server, it runs as a long running process that will neverexit. Because of this, you'll need it to run in the background - else yourCI provider will never move onto the next command.
Backgrounding your server process means that your CI provider will continue toexecute the next command after executing the signal to start your server.
Many people approach this situation by running a command like the following:
npm start & cypress run // Do not do this
The problem is - what happens if your server takes time to boot? There is noguarantee that when the next command runs (cypress run
) that your web serveris up and available. So your Cypress test may start and try to visit your localserver before it is ready to be visited.
Solutions
Luckily, there are some solutions for this. Instead of introducing arbitrarywaits (like sleep 20
) you can use a better option.
wait-on
module
Using the wait-on module, you can blockthe cypress run
command from executing until your server has booted.
npm start & wait-on http://localhost:8080
cypress run
info
Most CI providers will automatically kill background processes so you don't haveto worry about cleaning up your server process once Cypress finishes.
However, if you're running this script locally you'll have to do a bit more workto collect the backgrounded PID and then kill it after cypress run
.
start-server-and-test
module
If the server takes a very long time to start, we recommend trying thestart-server-and-testmodule.
npm install start-server-and-test --save-dev
In your package.json
scripts, pass the command to boot your server, the urlyour server is hosted on and your Cypress test command.
{
...
"scripts": {
"start": "my-server -p 3030",
"cy:run": "cypress run",
"test": "start-server-and-test start http://localhost:3030 cy:run"
}
}
In the example above, the cy:run
command will only be executed when the URLhttp://localhost:3030
responds with an HTTP status code of 200. The serverwill also shut down when the tests complete.
Gotchas
Whenworking with webpack-dev-server
that does not respond to HEAD
requests, use an explicit GET
method to pingthe server like this:
{
"scripts": {
"test": "start-server-and-test start http-get://localhost:3030 cy:run"
}
}
When working with local https
in webpack, set an environment variable to allowlocal certificate:
{
"scripts": {
"start": "my-server -p 3030 --https",
"cy:run": "cypress run",
"cy:ci": "START_SERVER_AND_TEST_INSECURE=1 start-server-and-test start https-get://localhost:3030 cy:run"
}
}
Record tests
Cypress can record your tests and make the results available inCypress Cloud. Cloud gives you access to recordedtests - typically when running Cypress tests from yourCI provider - and provides youinsight into what happened when your tests ran.
Recording tests allow you to:
- See the number of failed, pending and passing tests.
- Get the entire stack trace of failed tests.
- View screenshots taken when tests fail and when usingcy.screenshot().
- Watch a video of your entire test run or a clip at the point of test failurewhen the
video
configuration is enabled. - See which machines ran each test whenparallelized.
To record tests:
- Set up your project to record
- Pass the --record flag to cypress runwithin CI.
cypress run --record --key=abc123
Read the full guide on the Cypress Cloud.
Run tests in parallel
Cypress can run tests in parallel across multiple machines.
You'll want to refer to your CI provider's documentation on how to set upmultiple machines to run in your CI environment.
Once multiple machines are available within your CI environment, you can passthe --parallel flag to haveyour tests run in parallel.
cypress run --record --key=abc123 --parallel
Read the full guide on parallelization.
Official Cypress Docker Images
We have created anofficial cypress/base container withall of the required dependencies installed. You can add Cypress and go! We arealso adding images with browsers pre-installed undercypress/browsers name. A typicalDockerfile would look like this:
FROM cypress/base
RUN npm install
RUN npx cypress run
caution
Mounting a project directory with an existing node_modules
into acypress/base
docker image will not work:
docker run -it -v /app:/app cypress/base:20.9.0 bash -c 'cypress run'
Error: the cypress binary is not installed
Instead, you should build a docker container for your project's version ofcypress.
Docker images & CI examples
See our examples for additional information on ourmaintained images and configurations on several CI providers.
Advanced setup
Machine requirements
Hardware requirements to run Cypress depend how much memory the browser, theapplication under test, and the server (if running it locally) need to run thetests without crashing. Visit ourSystem Requirementsguide for minimum hardware recommendations.
Some signs that your machine may not have enough CPU or memory to runCypress:
- The recorded video artifacts have random pauses or dropped frames.
- Debug logs of the CPU and memoryfrequently show CPU percent above 100%.
- The browser crashes.
You can see the total available machine memory and the current free memory byrunning the cypress infocommand.
npx cypress info
...
Cypress Version: 13.6.6 (stable)
System Platform: linux (Debian - 11.6)
System Memory: 73.6 GB free 48.6 GB
You can see the CPU parameters on the CI machines by executing the commandbelow.
node -p 'os.cpus()'
[
{
model: 'Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz',
speed: 3399,
times: { user: 760580, nice: 1010, sys: 158130, idle: 1638340, irq: 0 }
}
...
]
Example projects and the machine configurations used to run them on CI:
- The Real World Appproject runs tests on a CircleCI machine using theDocker executor with
resource_class: large
providing 4 vCPUs and 8 GB of RAM.cypress info
reportsSystem Memory: 73.6 GB free 48.6 GB
. - The Real World App project alsoexecutes its tests onGitHub Actions using theCypress GitHub Action with thestandard Ubuntu GitHub-hosted runner for Public repositoriesproviding 4 vCPUs and 16 GB of RAM.
cypress info
reportsSystem Memory: 16.8 GB free 15.5 GB
with CPUs reported asAMD EPYC 7763 64-Core Processor
.
Tip: if there are problems with longer specs, try splitting them intoshorter ones, followingthis example.
Dependencies
Cypress runs on many CI providers' virtual machine environments out-of-the-box without needing additional dependencies installed.
Linux
If you see a message about a missing dependency when you run Cypress in a Linux CI environment, then refer to the Linux Prerequisites lists for guidance.
Caching
As of Cypress version 3.0, Cypressdownloads its binary to the global system cache - on linux that is~/.cache/Cypress
. By ensuring this cache persists across builds you can saveminutes off install time by preventing a large binary download.
We recommend users:
Cache the
~/.cache
folder after runningnpm install
,yarn
,npm ci
or equivalents as demonstrated inthe configs below.Do not cache
node_modules
across builds. This bypasses more intelligentcaching packaged withnpm
oryarn
, and can cause issues with Cypress notdownloading the Cypress binary onnpm install
.If you are using
npm install
in your build process, considerswitching tonpm ci
and caching the~/.npm
directory for a faster and more reliable build.If you are using
yarn
, caching~/.cache
will include both theyarn
andCypress caches. Consider usingyarn install --frozen-lockfile
as annpm ci
equivalent.If you need to override the binary location for some reason, useCYPRESS_CACHE_FOLDERenvironment variable.
Make sure you are not restoring the previous cache using lax keys; then theCypress binaries can "snowball", readDo Not Let Cypress Cache Snowball on CI.
Tip: you can find lots of CI examples with configured caching in ourcypress-example-kitchensinkrepository.
Environment variables
You can set various environment variables to modify how Cypress runs.
Configuration Values
You can set any configuration value as an environment variable. This overridesvalues in the Cypress configuration.
Typical use cases would be modifying things like:
CYPRESS_BASE_URL
CYPRESS_VIDEO
CYPRESS_VIDEO_COMPRESSION
CYPRESS_REPORTER
CYPRESS_INSTALL_BINARY
Refer to theEnvironment Variables recipefor more examples.
Record Key
If you are recording your runs on a public project, you'll wantto protect your Record Key.Learn why.
Instead of hard coding it into your run command like this:
cypress run --record --key abc-key-123
You can set the record key as the environment variable, CYPRESS_RECORD_KEY
,and we'll automatically use that value. You can now omit the --key
flag whenrecording.
cypress run --record
Typically you'd set this inside of your CI provider.
CircleCI Environment Variable
TravisCI Environment Variable
Git information
Cypress uses the@cypress/commit-info package toextract git information to associate with the run (e.g. branch, commit message,author).
It assumes there is a .git
folder and uses Git commands to get each property,like git show -s --pretty=%B
to get commit message, seesrc/git-api.js.
Under some environment setups (e.g. docker
/docker-compose
) if the .git
directory is not available or mounted, you can pass all git related informationunder custom environment variables.
- Branch:
COMMIT_INFO_BRANCH
- Message:
COMMIT_INFO_MESSAGE
- Author email:
COMMIT_INFO_EMAIL
- Author:
COMMIT_INFO_AUTHOR
- SHA:
COMMIT_INFO_SHA
- Remote:
COMMIT_INFO_REMOTE
If the commit information is missing in the Cypress Cloud run thenGitHub Integration or othertasks might not work correctly. To see the relevant Cypress debug logs, set theenvironment variable DEBUG
on your CI machine and inspect the terminal outputto see why the commit information is unavailable.
DEBUG=commit-info,cypress:server:record
CI Build Information
In some newer CI providers, Cypress can't map the environment variables requiredto link back to builds or pull requests. In this case we provided users someenvironment variables to help pass that information along.
- Pull Request Id:
CYPRESS_PULL_REQUEST_ID
- Pull Request URL:
CYPRESS_PULL_REQUEST_URL
- Build URL:
CYPRESS_CI_BUILD_URL
Setting these will allow links within the Cloud run to take you to theappropriate place.
Custom Environment Variables
You can also set custom environment variables for use in your tests. Theseenable your code to reference dynamic values.
export "EXTERNAL_API_SERVER=https://corp.acme.co"
And then in your tests:
cy.request({
method: 'POST',
url: Cypress.env('EXTERNAL_API_SERVER') + '/users/1',
body: {
foo: 'bar',
baz: 'quux',
},
})
Refer to the dedicatedEnvironment Variables Guide for moreexamples.
Module API
Oftentimes it can be less complex to programmatically control and boot yourservers with a Node script.
If you're using our Module API then you can write ascript that boots and then shuts down the server later. As a bonus, you can workwith the results and do other things.
// scripts/run-cypress-tests.js
const cypress = require('cypress')
const server = require('./lib/my-server')
// start your server
return server.start().then(() => {
// kick off a cypress run
return cypress.run().then((results) => {
// stop your server when it's complete
return server.stop()
})
})
node scripts/run-cypress-tests.js
Common problems and solutions
Missing binary
When npm or yarn install the cypress
package, a postinstall
hook is executedthat downloads the platform-specific Cypress binary. If the hook is skipped forany reason the Cypress binary will be missing (unless it was already cached).
To better diagnose the error, addcommands to get information about the Cypress cacheto your CI setup. This will print where the binary is located and what versionsare already present.
npx cypress cache path
npx cypress cache list
If the required binary version is not found in the cache, you can try thefollowing:
- Clean your CI's cache using your CI's settings to force a clean
npm install
on the next build. - Run the binary install yourself by adding the command
npx cypress install
to your CI script. If there is a binary already present, it should finishquickly.
Seebahmutov/yarn-cypress-cachefor an example that runs the npx cypress install
command to ensure the Cypressbinary is always present before the tests begin.
In Docker
If you are running long runs on Docker, you need to set the ipc
to host
mode. This issue describesexactly what to do.
Xvfb
When running on Linux, Cypress needs an X11 server; otherwise it spawns its ownX11 server during the test run. When running several Cypress instances inparallel, the spawning of multiple X11 servers at once can cause problems forsome of them. In this case, you can separately start a single X11 server andpass the server's address to each Cypress instance using DISPLAY
variable.
First, spawn the X11 server in the background at some port, for example :99
.If you have installed xvfb
on Linux or if you are using one of our Dockerimages fromcypress-docker-images,the tools below should be available.
Xvfb :99 &
Second, set the X11 address in an environment variable
export DISPLAY=:99
Start Cypress as usual
npx cypress run
After all tests across all Cypress instances finish, kill the Xvfb backgroundprocess using pkill
pkill Xvfb
caution
In certain Linux environments, you may experience connection errors with yourX11 server. In this case, you may need to start Xvfb with the following command:
Xvfb -screen 0 1024x768x24 :99 &
Cypress internally passes these Xvfb arguments, but if you are spawning your ownXvfb, you would need to pass these arguments. This is necessary to avoid using8-bit color depth with Xvfb, which will prevent Chrome or Electron fromcrashing.
Colors
If you want colors to be disabled, you can pass the NO_COLOR
environmentvariable to disable colors. You may want to do this if ASCII characters orcolors are not properly formatted in your CI.
NO_COLOR=1 cypress run
See also
- Cypress Real World Appruns parallelized CI jobs across multiple operating systems, browsers, andviewport sizes.
- cypress-example-kitchensinkis set up to run on multiple CI providers.
- Test Replay
- Cross Browser Testing Guide
- Blog: Setting up Bitbucket Pipelines with proper caching of npm and Cypress
- Blog: Record Test Artifacts from any Docker CI
- Continuous Integration with Cypresswebinar covering TeamCity, Travis and CircleCI setups.