react-native-testing-library icon indicating copy to clipboard operation
react-native-testing-library copied to clipboard

`waitFor` with nested `expect` timeout in v9

Open florian-milky opened this issue 3 years ago • 3 comments

Describe the bug

Hey guys, I've been banging my head for hours following a migration to v9. I had some timeout issues with a waitFor and ~~I thought it was related to the timers thingy, but in fact in seems related to a nested expect in my waitFor~~ it looks like it could be related to timers.

This works:

await screen.findByA11yRole('progressbar', { interval: 10 }); // Need more aggressive interval to catch the spinner before it is removed
waitForElementToBeRemoved(() => screen.getByA11yRole('progressbar'));

This doesn't and acts weird:

await screen.findByA11yRole('progressbar', { interval: 10 }); // Need more aggressive interval to catch the spinner before it is removed
await waitFor(() => {
  expect(screen.queryByA11yRole('progressbar')).toBeFalsy();
});

When debugging the waitFor it appears to ignore interval or even timeout settings and is executed only twice, once right away and once when the default timeout hits.

Expected behavior

To work

Steps to Reproduce

Feels like this should be easily reproducible. I'll look into it if not.

Screenshots

Versions

    @testing-library/react-native: ^9.0.0 => 9.0.0 
    react: 17.0.2 => 17.0.2 
    react-native: 0.65.1 => 0.65.1 
    react-test-renderer: ^17.0.2 => 17.0.2 ```

florian-milky avatar Jan 07 '22 14:01 florian-milky

If I'm correct waitFor will pass if the callback inside doesn't throw an error. If it does, it will retry after some time until it timeouts, therefore await waitFor(() => false) will always pass whereas await waitFor(() => expect(true).toBeFalsy()) will fail. In your case, I'd say screen.queryByA11yRole('progressbar') is always truthy and that's why test using expect fails. Either the progress bar is really always there or it's an issue with waitFor, maybe you should try with waitForElementToBeRemoved instead ?

pierrezimmermannbam avatar Feb 07 '22 16:02 pierrezimmermannbam

Oh wow you are totally right @pierrezimmermannbam, it doesn't make sense to return a boolean. I mixed up with waitForElementToBeRemoved. I updated the bug report description with better context. Your suggestion to use waitForElementToBeRemoved works! Thanks! It doesn't explain why waitFor does not though.

florian-milky avatar Feb 24 '22 13:02 florian-milky

@florian-milky this is indeed very strange. waitForElementToBeRemoved uses waitFor under the hood but is also checks that the element is not initially removed, so waitFor should work if waitForElementToBeRemoved works.

I'm not able to reproduce the issue, could you provide a reproducible demo ?

pierrezimmermannbam avatar Feb 25 '22 20:02 pierrezimmermannbam

@florian-milky could you verify that the issue you reported does still occur on the latest version of RNTL (& React Native, React, React Test Renderer). If so, could you please provide repro repository hopefully based on ours examples/basic app in our repo.

mdjastrzebski avatar Sep 26 '22 13:09 mdjastrzebski

Closing as stale.

@florian-milky If the issue still occurs on the latest version of RNTL, please provide a minimal repro repository, hopefully based on examples/basic folder from our repo, so that we can better understand the issue.

mdjastrzebski avatar Sep 30 '22 11:09 mdjastrzebski

Sorry didn't have time to really follow up on that. I will test again with the latest version and report at least

florian-milky avatar Sep 30 '22 12:09 florian-milky