← Back to React Testing Library Mastery
Intermediate18 min read

Async & waitFor

Handle asynchronous UI updates with waitFor, findBy, and act.

waitFor

waitFor retries callback until assertion passes or timeout (default 1000ms). Use when state updates after fetch, timer, or transition without findBy convenience.

Do not pass empty waitFor—include expect inside callback.

await waitFor(() => {
  expect(screen.getByText("Loaded")).toBeInTheDocument();
});

waitForElementToBeRemoved

Waits for element to leave DOM—loading spinners, toasts, modals. Pass element or query function returning element.

Pair with queryBy for elements that should disappear—null when gone.

await waitForElementToBeRemoved(() => screen.queryByText(/loading/i));

findBy vs waitFor

findByRole("alert") equivalent to waitFor(() => getByRole("alert")). Choose findBy for single element appearance; waitFor for complex multi-assertion conditions.

Increase timeout option for slow CI: findByText("Done", {}, { timeout: 5000 })

  • Fake timers require userEvent setup advanceTimer integration
  • Avoid waitFor with side effects in callback—assertion only
  • Multiple async updates may need single waitFor wrapping all expects

act

React act wraps state updates so tests flush effects before assertions. RTL render and userEvent handle act internally in modern versions.

Manual act needed rarely—async state update in setTimeout you trigger directly without userEvent.

import { act } from "@testing-library/react";

await act(async () => {
  jest.advanceTimersByTime(1000);
});

Debugging Async Failures

screen.debug() prints DOM at failure point. Log container.innerHTML when element not found. Common bug: missing await on userEvent or findBy.

MSW handler delay simulates slow network; ensure handler registered before render triggers fetch.

  • Configure default asyncUtil timeout globally in configure({ asyncUtilTimeout: 5000 })
  • Testing Suspense: assert fallback then resolved content with findBy
  • Rejecting promises should show error UI—await findByRole alert

Get In Touch


Ready to discuss your next project? Drop me a message.