So I updated to React 18 and now I am getting TONS of act warnings as well as failing tests.
versions:
react: 18.2.0
react-dom: 18.2.0
jest: 29.3.1
jest-environment-jsdom: 29.3.1
ts-jest: 29.0.3
typescript: 4.9.4
console.error Warning: An update to ProductPrice inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
I have fixed about 80 tests by wrapping the assertions or my main render method in await waitFor(() => {}
.
Is there a better way I should be fixing these tests? Here is an example test that went from failing to passing with the following change... The following failing test was passing before I upgraded to React 18 and corresponding react-testing-library + jest versions
-------------failing test below --------------
async function findPlpHeaderText() {
return screen.findByTestId('plp__header-text');
}
test.only('Sold out products render as expected on store', async () => {
await renderPage({ route: '/boutique/21443255', siteName: 'anonymous-store' });
const headerText = await findPlpHeaderText();
await within(headerText).findByText('Childless boutique');
await screen.findByText('Sold Out');
await screen.findByText('Sold Out. Must Have It?');
});
----------passing test below--------------
note: I wrapped the assertion in waitFor(() =>
and then they passed, I tested that this wasn't a false positive as well... this blog post inspired me to wrap my assertions in waitFor after upgrading to react 18 -- https://www.felixmokross.dev/blog/react-18-upgrade#:~:text=Fixing%20the%20tests,wrap%20assertions%20in
test.only('Sold out products render as expected on store', async () => {
await renderPage({ route: '/boutique/21443255', siteName: 'anonymouse-store' });
const headerText = await findPlpHeaderText();
await waitFor(async () => {
within(headerText).getByText('Childless boutique');
screen.getByText('Sold Out');
screen.getByText('Sold Out. Must Have It?');
});
});
Has anyone else experienced this after upgrading to React 18? If there is a better solution I would love to know about it!
Another weird aspect of this is when I wrap the new passing tests with an:
waitFor(async () => {})
callback, the act()
warnings go away -- however if I only wrap them in waitFor(() => {})
not-async callback, the `act() warnings persist, however the tests still pass...