testing-library / dom-testing-library

šŸ™ Simple and complete DOM testing utilities that encourage good testing practices.
https://testing-library.com/dom
MIT License
3.25k stars 463 forks source link

waitFor with getAllBy query not equivalent to findAllBy #1225

Open Clarity-89 opened 1 year ago

Clarity-89 commented 1 year ago

Relevant code or config:

import { act, render, screen, waitFor } from "@testing-library/react";
import { TestComponent } from "./App";

const mockDataProvider = {
  start: jest.fn().mockImplementation(() => Promise.resolve()),
  getKeys: () => ["key1", "key2"],
};
const props = {
  dataProvider: mockDataProvider,
  updateFilter: jest.fn(),
  item: {
    entry: "Sample entry",
    attributes: {
      key1: "value1",
      key3: "value3",
    },
  },
};

describe("Test", () => {
  it("Passing test", async () => {
    jest.useFakeTimers();
    render(<TestComponent {...props} />);
    await waitFor(() => {
      expect(props.dataProvider.start).toHaveBeenCalled();
      expect(screen.getAllByRole("alert")).toHaveLength(2);
    });
    act(() => {
      jest.runAllTimers();
    });
    expect(props.updateFilter).toHaveBeenCalled();
    jest.useRealTimers();
  });

  it("Failing test", async () => {
    jest.useFakeTimers();
    render(<TestComponent {...props} />);

    await waitFor(() => {
      expect(props.dataProvider.start).toHaveBeenCalled();
    });
    expect(await screen.findAllByRole("alert")).toHaveLength(2);
    act(() => {
      jest.runAllTimers();
    });
    expect(props.updateFilter).toHaveBeenCalled();
    jest.useRealTimers();
  });
});

What you did:

What happened:

The first test succeeds while the seconds test fails.

Reproduction:

Codesandbox

Problem description:

Not sure if this is an actual bug, but I can't understand why the combination of awaitFor + getAllByRole passes the test but using findAllByRole doesn't. Aren't findBy* queries just a wrapper for awaitFor + getBy*? Also the second test doesn't really need the mock timers, but I've included those to make the tests more comparable (it doesn't change the test result).

Suggested solution: