I understand that I'm not supposed to add act()
around user events because the testing library does it for me, but I get warnings if I don't. Specifically, for example given a MUI component with the ripple effect, here's what I find:
import { Tab as MuiTab } from "@mui/material";
describe("Tab", () => {
it("MuiTab creates a warning ", async () => {
const user = userEvent.setup();
render(<MuiTab label="hello" />);
// yep. There's a warning here.
await user.click(screen.getByRole("tab"));
});
it("MuiTab does NOT create a warning with disableTouchRipple", async () => {
const user = userEvent.setup();
// disabling the animation fixes the warning
render(<MuiTab label="hello" disableTouchRipple />);
await user.click(screen.getByRole("tab"));
});
it("MuiTab does NOT create a warning with act", async () => {
const user = userEvent.setup();
render(<MuiTab label="hello" />);
// no warning
await act(async () => await user.click(screen.getByRole("tab")));
});
});
These warnings started when I upgraded @testing-library/react
to ^14.0.0
, which fixed other act
warnings.
But now with the upgrade, I have 1.7M lines of warnings in my test suite. It's not "wrong" in that the ripple effect hasn't ended by the end of the test and I also understand that using jest timers can help resolve this.
But it feels wrong to add act
throughout the testing suite or to litter my test code with fake timers just because MUI has some animations.
Given all that, what's the recommended way for me to fix these warnings?
Versions:
(Also, please don't tell me that I should be asserting on the expected behavior after the click. I know that. I'm just using the Tab
as an example and I get the warnings whether there's an expect
afterwards or not.)
@testing-library/dom
incorrectly.This took a lot of time to figure out. Specifically, I would tweak the package.json
and pin specific versions, then run npm install && npm run test &> output##-version-details.log
so that I could track what happened with each change. When I started seeing conflicts in my output is when I looked at the package-lock.json
changes. By leveraging git I could then start easily compare package-lock.json
files.
Where @testing-library/react
wanted @testing-library/dom
as ^9.0.0
, what npm had actually resolved was 8.20.0
. I don't know why -- the package.json did not specify a dom version.
Once @testing-library/react
was using the correct dom version, the bulk of the warnings went away.
The upgrade also resulted in 7 new test failures out of ~950 tests, but those should be easy to resolve.
act()
or waitFor()
While I don't have specific evidence, I read a number of reports about waitFor
suppressing error messages. It doesn't make sense to waitFor
a click event since there's nothing identifiable for the library to say "yes, okay, it's done". I suspect that it "works" because it's suppressing the warnings and/or just a stand-in for wrapping it in another act()
directly.
On that note, wrapping events in act()
seemed like it should have been superfluous since testing-library
already wraps user events in act
. And when I did start adding it through my test suite, I started getting the Warning: The current testing environment is not configured to support act(...)
error in some cases.
Hence none of the documentation on react testing library nor my own experiences indicated to me this was the "right" solution.
This was a dead-end.
Before I figured out the package issue, I also spent a lot of time trying to disable the TouchRipple
effect in MUI and transitions in MUI. This resulted in ~20K warning lines reduced total, but it also resulted in more failed tests, too. I might go back later and disable TouchRipple
just because it's not necessary for tests.
import { createTheme } from '@mui/material';
const themeOverrides = createTheme({
transitions: {
// So we have `transition: none;` everywhere
create: () => 'none',
},
components: {
// Name of the component ⚛️
MuiButtonBase: {
defaultProps: {
// The props to apply
disableRipple: true, // No more ripple, on the whole application 💣!
},
},
},
});
## Then use the new these in a ThemeProvider for your tests.
## You can nest themes.