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.

`userEvent.click` fails due to timeout when used with `jest.useFakeTimers`

See original GitHub issue
  • @testing-library/user-event version: 14.0.0-beta.7
  • Testing Framework and version: jest version: 27.4.7, @testing-library/jest-dom version 5.15.1, @testing-library/react version 12.1.2
  • DOM Environment: jsdom version 19.0.0

Relevant code or config

// Dummy.js
import React from "react";

const Dummy = (props) => {
  const clickHandler = () => {
    setTimeout(() => {
      props.onClick();
    }, 500);
  };

  return <button onClick={clickHandler}>Click me</button>;
};

export default Dummy;
// Dummy.test.js
import React from "react";

import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import userEvent from "@testing-library/user-event";

import Dummy from "./Dummy";

// Fails
test("onClick prop is called on button (userEvent, fakeTimer)", async () => {
  jest.useFakeTimers();
  const user = userEvent.setup();
  const onClick = jest.fn();
  render(<Dummy onClick={onClick} />);

  const button = screen.getByRole("button");
  await user.click(button);
  jest.runOnlyPendingTimers();
  expect(onClick).toHaveBeenCalledTimes(1);
  jest.useRealTimers();
});

What you did: Dummy component calls onClick prop after a delay when its button is clicked. I tried testing it using userEvent.click alongside jest.fakeTimers to avoid waiting for the delay.

What happened: The test onClick prop is called on button (userEvent, fakeTimer) fails due to timeout.

npx jest output

 FAIL  client/src/dummy/Dummy.test.js (11.923 s)
  ✕ onClick prop is called on button (userEvent, fakeTimer) (5014 ms)

  ● onClick prop is called on button (userEvent, fakeTimer)

    thrown: "Exceeded timeout of 5000 ms for a test.
    Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."

      19 |
      20 | // Fails
    > 21 | test.only("onClick prop is called on button (userEvent, fakeTimer)", async () => {
         |      ^
      22 |   jest.useFakeTimers();
      23 |   const user = userEvent.setup();
      24 |   const onClick = jest.fn();

      at Object.<anonymous> (client/src/dummy/Dummy.test.js:21:6)

Reproduction repository: https://codesandbox.io/s/user-event-fake-timers-lwb65 (Source files are provided but I couldn’t get the tests to run on codesandbox)

Problem description:

The test fails due to timeout. The problem arises when using jest.useFakeTimers. The line await user.click(button) never completes.

Suggested solution:

Issue Analytics

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

github_iconTop GitHub Comments

16reactions
anomiexcommented, Jun 30, 2022

I wound up here looking for an answer to this problem. It seems to me that a better solution than described above is to make use of userEvent.setup({ advanceTimers: jest.advanceTimersByTime }): instead of disabling the delay entirely, use the provided mechanism to advance the fake timers when needed.

9reactions
ph-fritschecommented, Jan 16, 2022

The implementation waits for delay seconds per setTimeout between actions. When fake timers are activated, new Promise(r => setTimeout(r, delay)) only resolves when the timer is advanced.

As delaying to the next macrotask is default behavior in v14, maybe #585 is more pressing now. Maybe we should add a paragraph about fake timers in a more prominent place in the documentation - maybe in the introduction or in an extra FAQ section.

For now you can disable delaying the next action per userEvent.setup({delay: null}).

Edit: fixed link

Read more comments on GitHub >

github_iconTop Results From Across the Web

No results found

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