0

After updating testinglibrary/userEvent from version 13 to 14, it is not waiting for dynamically rendered.

My dialog is lazily loaded as well as the content inside the dialog.

An example code is below.

  it('updates the channel information after edit channel request succeeds', async () => {
    
    render();
    
    await userEvent.click(await screen.findByTestId('TestId'));
    const myDialog = await screen.findByRole('dialog');

    // This is problematic.
    const nameField = within(myDialog).getByLabelText(/name/i);

})

Dialog shows spinner until it finishes fully loading the content.

And the content will be rendered as long as query waits. But it doesn't wait for the content to be rendered but quits waiting as soon as it finds the spinner, saying it couldn't find the content but only spinner.

What I tried

  • Using find query instead of get, some tests are resolved only doing this but others aren't.
  • Using screen instead of within(dialog).findBy. This resolves some breaking test as well.

I looked over the document and changelog if there were effective change that possibly breaks the test code, but had no luck :(

What should I do with it?

JunKim
  • 647
  • 7
  • 17

1 Answers1

1

This might be because you haven't ran setup yet. userEvent's API have changed in 14, and now, per the documentation:

We recommend invoking userEvent.setup() before the component is rendered.

So in your case, you need to try something like this.

it('updates the channel information after edit channel request succeeds', async () => {

    const user = userEvent.setup()
    
    render();
    
    await user.click(await screen.findByTestId('TestId'));
    const myDialog = await screen.findByRole('dialog');

    // This is problematic.
    const nameField = within(myDialog).getByLabelText(/name/i);

})
davidx1
  • 3,525
  • 9
  • 38
  • 65
  • Thanks for answer! Does setting up userEvent relevant in this case? Although I didn't call `userEvent.setup`, I awaited all the method that userEvent provides and I couldn't find an explanation in the document here https://testing-library.com/docs/user-event/setup/ – JunKim Jul 26 '22 at 09:18
  • @JunKim Missing setup is the only thing I can think of by just reading the test itself. Without seeing what the component is actually doing, it's difficult to guess at the problem. Can you provide a minimal example demonstrating the problem on codesandbox or something? – davidx1 Jul 26 '22 at 09:25
  • @JunKim Wait.. you wrote "Dialog shows spinner until it finishes fully loading the content.". So an element with the role 'dialog' appears on the screen already while you are still loading? If that's the case then the problem is that `findByRole('dialog');` waits for the dialog element to appear. As soon as the `dialog` appears, it proceed to the next line. What you need to do is wait for the loading to finish. Maybe put a label text on the spinner and: `await waitForElementToBeRemoved(() => queryByLabelText('loader'))` – davidx1 Jul 26 '22 at 09:31