Search code examples
javascriptreactjsjestjstesting-library

How do I wait for the user.click() in testing-library React to update the state?


https://codesandbox.io/p/github/Lir-kulikov/users/main?file=%2Fsrc%2F__tests__%2FApp.test.js&selection=%5B%7B%22endColumn%22%3A22%2C%22endLineNumber%22%3A21%2C%22startColumn%22%3A22%2C%22startLineNumber%22%3A21%7D%5D

In codesandbox in src/tests/App.test.js the trivial tests fail because after simulated click (line 21) screen.getByRole is triggered before the state is updated. To make sure you can uncomment the function with await on line 21. It will make everything work ok. How to fix it correctly following best practices?


And second question: in all tests, even those which pass ok, I get error with act (you can see it in sandbox too). When I have tried to wrap it into act(), eslint started swearing and it didn't help anyway. I've read various articles on the subject, but still didn't understand what's wrong.


Solution

  • This seems to work:

    import { waitFor } from '@testing-library/react'
    
    // ...
    await waitFor(async () => await user.keyboard("Joe@gmail.com"));
    

    See it working here.


    But I still think there should be a better way.

    Technically, user.keyboard doesn't return a promise, so the async/await should not be necessary. But when I remove them, I get an Avoid using side effects within waitFor warning. 1


    1 - No longer true for @testing-library/user-event@^14, fixed in react-testing-library/issues/1137, see @Lirrr's comment below.