Description
@testing-library/react
version: 5.11.6- Testing Framework and version: Jest 26.6.0 (react-scripts 4.0.1)
- DOM Environment: jsdom 16.4.0
- node 14.2.0
- react: 17.0.1
Considering a Component can make an API call, then instantiate a form with various widgets, some of which might need data from the server and make API calls too, we need a way to know when the page is "stable" and has resolved all its server side dependencies before trying to interact with the page (mostly forms).
Relevant code or config:
In our codebase, all calls to the server trigger the presence of a Loader element with data-testid="loader"
, and we wrote the following helper to wait until everything is ready :
export async function waitForPageLoaded() {
let ticksWithoutLoader = 0;
let loadersCount = 0;
await waitFor(
() => {
loadersCount = screen.queryAllByTestId('loader').length;
if (loadersCount === 0) {
ticksWithoutLoader += 1;
} else {
ticksWithoutLoader = 0;
}
if (loadersCount) {
throw new Error('Still waiting for Loaders to disappear...');
}
if (ticksWithoutLoader <= 3) {
throw new Error('Still waiting in case a Loader (re-)appears...');
}
},
{
onTimeout: (e) => {
// eslint-disable-next-line testing-library/no-debug
screen.debug();
throw e;
},
},
);
}
What you did:
The idea is to wait until there are no loader present and then let the waitFor
be called again 2 more times in case a component that has just been instantiated triggers a new server call. When we see no loader for 3 waitFor
calls in a row, we consider our page to be ready to play with.
Problem description:
We've been using that for a while, but noticed random test fails with it as tests number increased.
When using --runInBand
with jest to force a single worker, it seems to be working fine every time.
But when we use workers (the default), we have random test fails more and more frequently.
We started monitoring the failing tests to find a pattern, but so far we saw about 25 different tests failing, out of 660.
Also, it seems that increasing the timeout
option of the waitFor call helps, but that doesn't seem like a scalable solution...
Suggested solution:
Is there something fundamentally wrong with out approach ? Another way to achieve the same result in a more reliable way ? Is there a bug in the waitFor implementation that makes the jest workers affect each other's behavior ? We tried many things to fix the issue, and searched a lot on the matter, but can't get rid of it or find an alternative.
We love the react-testing-library's approach, but seem to be stuck in an uncomfortable situation and we're not sure if it's a bug or if we're doing things the wrong way.
Any hint would be appreciated :)