dom-testing-library: findBy* no longer waiting when used with jest fake timers
@testing-library/domversion: 8.0.0- Testing Framework and version:
@testing-library/reactv12 - DOM Environment: jest 27
Relevant code or config:
"jest": {
"testEnvironment": "jsdom",
"setupFilesAfterEnv": ["<rootDir>/jest-setup.js"]
}
// jest-setup.js
import '@testing-library/jest-dom'
What you did:
I was trying to use fake timers and findBy*
What happened:
findBy* doesn’t wait when using fake timers as it used to.
Reproduction:
Created a repo with two branches, one using v11 of RTL and another one for v12.
v11 branch works fine (dom v7.31.2)
v12 branch is experiencing issues (dom v8)
https://github.com/deini/rtl-find/tree/v11 https://github.com/deini/rtl-find/tree/v12
Problem description:
When doing something like:
jest.useFakeTimers();
render(<Button />)
await screen.findByRole('dialog', {}, { timeout: 5000 })
I would expect it to wait for 5 seconds (unless I’m totally wrong 😅), however, seems like fake timers is now messing up with findBy* and it doesn’t wait anymore. This happens both in jest 26 and 27 with both legacy and modern fake timers.
Suggested solution:
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 17
- Comments: 39 (12 by maintainers)
Is there any working/recommended solution for this issue?
Let’s keep this open since
mswis quite popular and I’d like to ensure compatiblity short-term. I just don’t know where to start so some response from their maintainers would be nice.Yes, that tracks with my own experience. I have had to increase the timeout globally for all async utils. In src/setupTests.ts:
Have you tried running this with msw v.0.30 ? This includes a fix for Jest 27.
My workaround for
waitForElementToBeRemovedis wrapping it like this:Then whenever you need
waitForElementToBeRemovedjust import your ownwaitForElementToBeRemovedfunction instead of importing from testing library.I believe the same technique can be used for other async utils like
waitForandfindBy*.Hope this helps.
@rbrewington Thanks for the reply, I tried that already. But even after using
jest.runOnlyPendingTimers(), it is not passing.We are experiencing the same issue. jest fake timers are interfering with waitFor and findBy queries. Both of them make two attempts and the test fails irrespective of the timeout value. Some more data: We provided a 5 seconds timeout and both waitFor and findByXXXX made two retries only. The two retries are something consistent in our environment.
Any updates on this issue?
They shouldn’t do that. The point of fake timers is that you do want to inferfere with the time. If libraries just use a different clock, fake timers wouldn’t do anything.
It seems to me
mswis using a different clock. I would expect that if I advance the clock by 200ms and flush the microtask queue any response with a delay <200ms would resolve. But that’s not what’s happening:This sounds more like an
mswissue to me. Or maybe we’re disagreeing on whether you should or shouldn’t mix clocks (I think you should the clock that’s currently available and not mix real/fake clocks).Thanks again for the reply. The repo I linked in my previous comments is an isolation of the issue.
Couldn’t come up with something smaller to reproduce it.