I have been working with cypress recently, and every day I learn new stuff about it.
In the previous post I have shared how to configure continuous integration with Github actions and cypress.
Now I will share some tips and tricks that may help you to boost the performance and the maintainability of your cypress tests.
1 . Parallelize the execution of your tests
First things first: we all know that these e2e tests take a surprisingly long time to run take here as an example of my 169 spec tests:
Wait 57 minutes for your tests to run at the CI is simply unacceptable.
Fortunately, cypress provides great integration with the most popular CI tools to parallelize the execution of our tests. Here is how to do this with Github Actions: make sure you are using the official cypress GitHub action workflow, and add the matrix
strategy in your job configuration specifying the number of containers you want the CI to spin up to run all your tests:
Here on my workflow file I’m running 10 containers so my tests can run really fast. See the results after adding this simple configuration:
From 57 minutes to less than 7 minutes. Awesome!
2 . Wait for complete server startup
It’s important to guarantee that the application being tested is up and running before your cypress test starts to run. Otherwise you may face annoying and nondeterministic timeout errors:
This kind of error happens when we try to reach a URL cy.visit('http://localhost:8080');
, and the server localhost:8080
is still not ready.
To avoid this, use the wait-on npm module. Wait-on is a npm command line utility which will wait for files, ports, sockets, and http resources to become available. To add this at our cypress tests workflow at Github Actions CI is pretty simple:
At the build
step phase, we install the wait-on npm package. After that, we just ask wait-on to wait for the URL localhost:8080
and set 2 minutes as a timeout for waiting wait-on-timeout: 120
. This should be enough to fix all sorts of nondeterministic timeout failures.
3 . Change cypress default timeouts
All cypress commands have a default time, in milliseconds, to wait until most DOM-based commands to be considered timed out. If you have some components that may take a bit long to load, such as selects and menus, you should consider changing the default timeout. To do this, you simply need to add at the cypress.json
file the new timeout you want to set:
The defaultCommandTimeout
affects commands that manipulates DOM: cy.get()
, cy.click()
and such.
pageLoadTimeout
is the time, in milliseconds, to wait for page transition events
or cy.visit()
, cy.go()
, cy.reload()
commands to fire their page load
events.
4 . Use Cypress commands to avoid boilerplate code
Some of the code you write may repeat for all over your test code. Take as an example a autocomplete component that receives an input, and loads a list of filtered options above it. If this component is everywhere on your application, you may have to do this a lot:
To avoid typing all these, we can create a cypress command that will encapsulate this boilerplate code. To do so, let’s edit the /cypress/support/commands.js
file:
This allows us to write way simpler interations with the autocomplete component at our tests:
These commands may be pretty useful for DOM interactions that require too much code. So don’t be afraid of adding new custom commands.
Cypress offers us a ton of configurations and useful customizations, It is up to us to choose the ones that better fit our scenarios and make our tests more clean and fast.
If you liked this article, consider sharing it.