DLO
DLO

Reputation: 1194

Wait for multiple elements to be removed React testing Library

I have a react application where I'm using jest and react testing library for my unit tests. I have a unit test where I want to test that SomeComponent when loaded doesn't render any skeleton. SomeComponent renders skeletons when data isn't loaded yet. Problem is that multiple skeletons are rendered and waitForElementToBeRemoved only takes one HTMLElement.

So I was wondering if there was a way to waitForMultipleElementsToBeRemoved?

test("SomeComponent when loaded doesn't render any skeleton", async () => {
    render(
      <SomeComponent />,
    )

  const skeletons = screen.getAllByTestId("skeleton");
  await waitForElementToBeRemoved(skeletons);

  expect(
    screen.queryByTestId("skeleton") 
  ).not.toBeInTheDocument();
});

Note:

This test works as intended when there is only one skeleton.

Upvotes: 4

Views: 9962

Answers (2)

Mike
Mike

Reputation: 612

You can just:

await waitForElementToBeRemoved(() => screen.getAllByTestId("initLoader"));

or in your case:

await waitForElementToBeRemoved(() => skeletons);

I think you just missing the callback. Otherwise your code is fine!

Upvotes: 6

Moistbobo
Moistbobo

Reputation: 2962

You could do this if you only want to test for 1 skeleton to be rendered


test("only 1 skeleton", async () => {
  const { getAllByTestId } = render(
    <div data-testId="skeleton">spooky skeleton</div>
  );

  const skeletons = getAllByTestId("skeleton");
  
  await waitFor(()=>{
    expect(skeletons.length).toBe(1);
  })
});

Here, I use getAllByTestId, but instead of checking for it to not be in the document, I just check if the length of the returned query is 1, meaning there is only one skeleton element being rendered.

I also wrap it in a waitFor as I'm assuming that the skeletons disappear over time. Note that the default timeout is only 1000ms, but this can be configured using the options parameter.

sandbox

Upvotes: 1

Related Questions