question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

waitFor with fake timers does not work with `getByRole`

See original GitHub issue
  • @testing-library/dom version: 7.22.6 (via @testing-library/react v10.4.9)
  • Testing Framework and version: jest v26.6.0 (via react-scripts v4.0.3)
  • DOM Environment: jsdom 16.6.0 (via react-scripts v4.0.3)

Relevant code or config:

import React, { useEffect, useState } from 'react'
import { render, screen, waitFor } from '@testing-library/react'

/**
 * Displays the passed `message` after `delay`
 */
function Test({ delay, message }) {
	console.log('rendering')
	const [delayedMessage, setDelayedMessage] = useState(null)
	useEffect(() => {
		setTimeout(() => {
			setDelayedMessage(message)
		}, delay)
	}, []) // Only run once

	return <h2>{delayedMessage}</h2>
}

describe('Fake Timers and waitFor and getByRole', () => {
	test('waitFor should work when used with fake timers and a long WAIT_TIME', async () => {
		jest.useFakeTimers()
		const WAIT_TIME = 80000
		const MESSAGE = 'Displayed Message'
		render(<Test delay={WAIT_TIME} message={MESSAGE} />)

		await waitFor(
			() => {
				expect(screen.getByRole('heading', { name: MESSAGE })).toBeTruthy()
				expect(screen.getByText(MESSAGE)).toBeTruthy()
			}
			// ,{ timeout: WAIT_TIME }
		)

		jest.useRealTimers()
	})
})

What you did:

Trying to test a component that depends on an interval to fetch some data. The code above is a much more simplified version with no network, no promises, etc.

What happened:

When trying to query the screen with getByRole, the test would fail. Using getByText allowed it to succeed. This only happens when the wait time is significantly larger than the default waitFor timeout.

Reproduction:

The code above is all that is needed to break it. Here’s a minimal repro https://github.com/dannyharding10/waitFor-useFakeTimers-fail

Problem description:

This was extremely confusing to come across, especially after I saw https://github.com/testing-library/dom-testing-library/issues/661 and the corresponding PR that fixed it (at least mostly 😅 ). I expected waitFor to either always work or always fail in this situation, but it seems to work only sometimes.

Suggested solution:

I don’t think it makes sense to allow waitFor to just go forever, but it would be nice if the behavior were more consistent. If the asynchronous action took longer than the timeout for waitFor, then it should fail 100% of the time. Right now, it seems like it succeeds and fails conditionally depending on the complexity of the query (*ByRole vs *ByText), the duration (always fails with a crazy high delay, like 1_000_000+), etc.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
danny-does-stuffcommented, Jul 9, 2022

@eps1lon Here’s a repro using the code from above. https://github.com/dannyharding10/waitFor-useFakeTimers-fail

Let me know if anything else is needed!

1reaction
ianldgscommented, May 6, 2022

I’m also experiencing fake timers not working with waitForElementToBeRemoved. My async timeout is 5s and this times out in 400ms.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Async Methods - Testing Library
waitFor may run the callback a number of times until the timeout is reached. Note that the number of calls is constrained by...
Read more >
Asyncronous test using React Testing Library/WaitFor
I'm looking for the simplest solution to this problem using the popular React Testing Library. I've looked ...
Read more >
API | React Native Testing Library - Open Source
waitFor. Using jest fake timers. waitForElementToBeRemoved; within , ... This options is experimental, in some cases it might not work as intended, ...
Read more >
Testing-library user event with fake timers - - One Step! Code
Using testing-library user-event library alongside jest fake timers to test ... This way, we won't have to wait for the setTimeout delay to ......
Read more >
You Probably Don't Need act() in Your React Tests
What problem does act() solve? react-testing-library already wraps ... you should see if RTL async utilities could be used instead: waitFor ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found