Introduction to the Jest and Puppeteer Timeouts
Overview
Applications aren’t responding with lightning speed on user actions and while creating the E2E tests this fact should be considered. In this article, I will highlight the basic timeouts for such powerful tools like Jest and Puppeteer with some recommendations on how to use them to avoid common pitfalls.
Test Execution Timeout
Let’s start with Jest. Jest is a fully-featured JavaScript Testing Framework developed by Facebook with a focus on simplicity and easy to use. And like any tool, it has its own rules and configuration settings. One of them is the test execution time. This timeout means that the test should pass in the specified time frame, otherwise Jest will kill the process and the test will fail. By default, it’s set to 5 seconds, if the test run exceeds this time the test will fail with the error like
Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Error
The error is not very helpful especially if the test started to run and was interrupted in the middle or while waiting for some selector. Of course, this time is enough for the low-level testing such as unit testing but it’s not suitable for the E2E testing except the case your application is very fast and the test flows are short.
So what can be done? The first thing that comes to the mind is to increase the default timeout and it’s the correct answer. Let’s set this timeout to 120000 ms (2 minutes). This can be done in a few ways:
- by increasing timeout for a particular test
2. by setting a timeout for all tests in out test kit, framework or a single file
After a while, you still can get the error like before but with the increased timeout
Timeout - Async callback was not invoked within the 120000ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 120000ms timeout specified by jest.setTimeout.Error
In this case, you should consider the next actions:
- split the test flow into several tests to make each test run time less than 2 minutes
- increase the timeout for a particular test
- increase the timeout for all tests
- revise your test flow and drivers for explicit waits, maybe there are a lot of waits like
page.waitFor(15000)
, in this case, the wait strategy should be reconsidered to wait for the particular elementspage.waitForSelector('some_selector')
- analyze your custom wait functions, there is a chance that they can execute forever, for example, waiting to finish the network activities when the application constantly sends the requests or waiting for animation. To fix it, the wait function must have strict timeouts or another wait condition should be used.
Navigation Timeout
Now let’s switch to Puppeteer. Puppeteer is a Node library created by Google, which provides a high-level API to control Chrome or Chromium over the DevTools Protocol. Like Jest, the Puppeteer also has its timeout settings.
One of the most usual problems with pages that have a lot of content, because of the images, different components, and complicated logic is the loading time. In this case, if the page total loading time is more than 30000 ms (30 seconds) the exception TimeoutError
will be thrown. There are two options to solve this issue, either to increase this timeout in the configuration or remove it at all.
- to increase it to 60000 ms (1 minute), you need to set the value in milliseconds like
2. to remove this timeout at all you need to specify
Setting this timeout affects the next methods in Puppeteer:
- page.goto
- page.goBack
- page.goForward
- page.reload
- page.waitForNavigation
Also, you can specify the custom timeout per each page navigation
Default Action Timeouts
The second useful Puppeteer’s timeout is responsible for working with the elements. Its default value is the same 30 seconds and can be changed using the command
Setting this timeout affects the next methods:
- page.goBack
- page.goForward
- page.goto
- page.reload
- page.setContent
- page.waitFor
- page.waitForFunction
- page.waitForNavigation
- page.waitForRequest
- page.waitForResponse
- page.waitForSelector
- page.waitForXPath
You may notice that it includes the methods from the previous timeout if both of them are set page.setDefaultNavigationTimeout
takes priority over page.setDefaultTimeout
You should set setDefaultTimeout
when:
- you want a control how long the element will be searching using the methods like
waitForSelector
, for example, all elements should be available less than in a 3 secondspage.setDefaultTimeout(3000)
- you want to increase the default timeout, for example, when you’re testing the third-party integrations.
Also, you can specify the custom timeout while waiting for a particular element
Conclusion
We saw how easy to manipulate with the timeouts in such tools as Jest and Puppeteer.
Using these set timeout methods will allow you to create more stable tests and control your test flow even more precisely.
I strongly encourage you to look at the official documentation for the up-to-date information and for enriching your knowledge: