On a recent project, we started using Cypress.io to write our integration tests. Cypress is great as it allowed the frontend developers to write tests easily, however, we encountered an issue. When running the test suite, tests would fail randomly with timeout issues. These issues not only wasted time as developers had to retrigger the integration tests before they could test their work, but it also caused trust issues in the quality gates. In this tutorial, you will learn a few different ways to solve this problem. Sound good, then read on 😊
Increase The Timeout Size
If you have a test that fails due to a timeout, one quick way to try and solve the problem is to increase the length of the requests timeout period. You can do this by passing in a second optional parameter when you make a
.visit() request, like so:
Increasing the timeout size is a bit of a hack and it's not the approach I would recommend to fix the test, but it can help. A more strategic solution would be to diagnose what is causing the time out and attempt to fix the underlying issue. In my situation, most of the timeouts occurred because of third-party requests we had limited control over. Requests to third-party services, like Google analytics, made the response time breach the timed out period.
To prevent these request types from failing your tests, you can blacklist them in Cypress. When you blacklist a host, when the test runs, whenever a request to a blacklisted host is made, Cypress will return a status code of 503 instantly. This will then allow the test to continue rather than to timeout and fail. To blacklist a host within Cypress, within your
cypress.json file, add a 'blacklistHosts' option. This can be a single string, or, an array like this:
💡A handy debugging tip is that after blacklisting, you should see blacklisted requests returning a 503. If you do not you know you have some config issues somewhere. Note, this only works for XHR requests. If you have a large image on your page then you can not prevent a timeout on images!
Instead of applying a global blacklist, on a per-test basis, you could also tell a test to wait longer for certain requests. This is much safer than simply upping the whole tests timeout period. In testing the more specific you can be the better! To wait for an individual request is done using
cy.wait(). To tell Cypress which requests it should wait for using
.wait() you will need to define a request and use an
alias. The code to do this is shown below:
The key takeaway from this code is that you define the request you want to capture. Using
.as() you define an alias for the request. You then pass that alias name into
.wait() to configure the test. With these three techniques, you should be able to solve the majority of timeout issues you experience. If none of the techniques listed in this article helps to solve your issues, I suggest you revisit your code. I would hazard a guess you need to optimize your website as these techniques should cover most normal testing paths! Happy Coding 🤘