Introduction to the Jest and Puppeteer Timeouts

Dmytro Aponasenko
Wix Engineering
Published in
4 min readSep 8, 2020
Photo by Cris Ovalle on Unsplash

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:

  1. 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 elements page.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.

  1. 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 seconds page.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:

--

--