UserEvent.type causes act warning with react-hook-form with mode: 'onChange'
See original GitHub issue@testing-library/user-event
version: 12.1.6- Testing Framework and version: react testing library 16.13.1 with jest 26.1.0
- DOM Environment: I’m using ts-jest to run the tests, which I think also defaults to jsdom
Relevant code or config Form:
const SomeForm = () => {
const { register } = useForm({
mode: "onChange",
});
return <input name="name" ref={register({ required: true })} />;
};
Form spec:
describe("SomeForm input name", () => {
it("can be changed", async () => {
render(<SomeForm />);
const nameInput = screen.getByRole("textbox", "name");
await userEvent.type(nameInput, "John");
// await fireEvent.change(nameInput, { target: { value: 'John' } })
expect(nameInput).toHaveValue('John');
});
});
What you did:
I tried using react-hook-form with validation mode onChange, which will trigger a validation whenever an input changes.
What happened:
The test works as expected, but an act warning appears. When using fireEvent.change, the warning does not show up. I can wrap the userEvent.type in an act(), but I feel like that hides the problem. I understand correctly the onChange event from the input happens asynchronously so userEvent.type ends before it gets called.
How can I expect validations to have been called? Does userEvent.type call onChange callbacks synchronously? Is there any way to await for all changes triggered by the input change? Maybe adding an extra empty validation function that I can mock and wait for it?
If this issue can’t be handled in userEvent maybe I should take it to react-hook-form.
Reproduction repository:
I have an example repository here: https://codesandbox.io/s/usereventtype-issue-example-g0g8h
It is currently failing because of an unrelated codesandbox issue, but you can download the zip, and run npm i
and npx jest src/SomeForm.spec.js
Issue Analytics
- State:
- Created 3 years ago
- Reactions:4
- Comments:7 (3 by maintainers)
Top GitHub Comments
I’m getting these warnings as well with react-hook-form, and I’m not quite clear if there’s a solution. If I try to wrap my
userEvent.type
calls in anact
, and when I try towaitFor
the value to be correct, I get a warning about overlappingact
calls.In my case, I’m using a
Controller
similar to what is shown here: https://codesandbox.io/s/react-hook-form-parse-and-format-textarea-zbgog?file=/src/index.tsx:666-805Edit: I was able to solve this by following this pattern:
I had a problem trying to waitFor something that was already true, so if you get
act
warnings you don’t expect, make sure that yourexpect
actually fails before your userEvent.Makes sense, then there’s nothing that userEvent can do right? The only alternative to stop the warning in this case is to wrap it in act.
Since the event triggers asynchronously, and it is internal to react-hook-form, there’s no way to test it. Maybe the correct thing would be to add a “onValidationFinished” callback to react-hook-form, that is called after the validation promise is returned.Then I could await a jest mock callback for that.
If you feel the solution lies outside of userEvent, or that wrapping in act is a good enough solution feel free to close the ticket. Thanks a lot for your help!