testing-library / testing-library/dom-testing-library
Missing timeout error information for `waitFor`
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 3.3k
- Forks
- 474
- PR merge metrics
- No merged PRs in 30d
Description
@testing-library/domversion: 8.11.1- Testing Framework and version: Jest 27
- DOM Environment: jsdom
Relevant code or config:
TestingLibraryElementError: Unable to find an element with the text: Example. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
Ignored nodes: comments, <script />, <style />
{pretty printed markup}
23 |
24 | expect(
> 25 | await screen.findByText('Example')
26 | ).toBeInTheDocument();
What you did:
Using a find* query or waitFor.
What happened:
I see an error message which doesn't mention the timeout.
Reproduction:
Problem description:
We are using testing library and Jest not just for unit testing small components, but also whole pages. Naturally the tests take a bit longer than usual. At some point in time the tests became flaky in the CI and we really weren't sure why. Was it a recent change in our code? In some lib? In the GitLab runners?
In hindsight it might be obvious, but it really took us a long time to figure out that we were getting timeout errors in find* queries, because our app just got bigger over time. Why does it took so long?
- The error messages returned by
find*queries are the same as the ones fromget*/query*. - When you hit a timeout in Jest the error message usually tells us that we hit a timeout.
- If you just look at a simple example and are unfamiliar with dom-testing-library you might think
find*is using the same params asget*/query*- only that it returns a Promise. (One could think thatfind*does not come with its own timeout settings, but would just wait until we hit the test timeout specified in Jest.)
We knew find* is asynchronous, but with the given error message we actually didn't thought that we hit a timeout issue. (Might be our fault for not knowing about asyncUtilTimeout, but it was definitely not self explanatory. I personally really thought find* would wait until we hit the test timeout defined in Jest.)
Suggested solution:
The error messages returned by find* (and therefor waitFor) should be different then the usual error messages and should say the current timeout value.
Maybe something like:
TestingLibraryElementTimeoutError: Unable to find an element with the text: Example. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible. (Reached current timeout of 1000ms.)
Ignored nodes: comments, <script />, <style />
If I understood correctly a simple fix could be:
onTimeout = error => {
error.message = getConfig().getElementError(
`${error.message} (Reached current timeout of ${timeout}ms.)`,
container,
).message
error.name = 'TestingLibraryElementTimeoutError'
return error
},
here: https://github.com/testing-library/dom-testing-library/blob/main/src/wait-for.js#L26
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at src/wait-for.js around line 26, the entry point identified in the issue, and trace how timeout errors are assembled for waitFor and find* queries. Compare the current error with the requested timeout information and verify the resulting behavior for both APIs with the project's relevant tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100