I'm building some custom dev tools inspired by this Kent C Dodds post and trying to automatically fill in some values for a form I've created.
I have an button that triggers this function where I'm trying fill in an input box. Going off his suggestion to use some utilities from @testing-library/react
I thought this should be possible.
import { screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
async function FillOutForm() {
// const user = userEvent.setup(); // tried this on and off but didn't seem to matter
const uploadButton = screen.getByRole('button', { name: /upload/i });
uploadButton.click();
//await for upload modal to open
await screen.findByRole('dialog');
const input = await screen.findByLabelText('Name');
console.log('input', { input }); //works, it found the value
// userEvent.type(input, 'test'); //freezes, no input filled
// await user.type(input, 'test'); //freezes, no input filled
// await act(async () => userEvent.type(await input, 'some text')); //fills in the text, but freezes after and gives an error
console.log('i never get here?');
}
Edit: This appears to be specific to styled components or Material UI. When I use a vanilla input, userEvent.type
seems to work just fine.
Edit #2: Here's a repro in stack blitz - at least for some freezing behavior.
Uncomment this line to see some type of infinite loop get kicked off.
// userEvent.click(button) //uncomment to see what causes freeze - some type of infinite loop?
It turns out I had an infinitely rendering component behind the form I was using. It allowed me to interact fine with the form when typing manually, but chaos ensued when I brought in react testing library.
Turns out this is a completely valid use case/approach and works now after I fixed that infinite loop problem.