I have a form that is validated by the HTML5 form validation API. In this form, there is a required file input, which, in the test, always fails the validation, as if it were empty. I do use the fireEvent.change to input a mock file, but it only works on the change event, not on the submit. The file input is always marked as invalid on the submit event. How can I test the successful validation function?
The component simplified code:
const ExampleComponent = () => {
const submitForm = async e => {
e.preventDefault();
let form = e.target;
// just for debugging, always prints the fileInputExample
Array.from(form.elements).forEach(input => {
if (!input.validity.valid) {
console.log(input.id);
}
});
let formData = new FormData(form);
let body = Object.fromEntries(formData);
console.log(body); // always prints { fileInputExample: {} }
if (form.reportValidity()) { // always fails
// some logic here
console.log('success'); // here's where I'm trying to get to
} else {
console.log('validation fail'); // always prints this one
}
};
const changeFile = e => {
let input = e.target;
if (input.files.length === 0) {
input.setCustomValidity('');
console.log('no file');
} else if (input.files[0].type === 'text/html') {
input.setCustomValidity('');
console.log('valid file'); // prints this one
} else {
input.setCustomValidity('O tipo do arquivo deve ser .html');
console.log('wrong file');
}
};
return (
<S.Form onSubmit={submitForm}>
<Input
type="file"
label="Example label"
id="fileInputExample"
name="fileInputExample"
required
accept="text/html"
onChange={changeFile}
helperText="O arquivo deve ser um HTML"
/>
<button type="submit">Save</button>
</S.Form>
);
}
The test:
test('envia formulário completo', async () => {
render(<ExampleComponent />);
const file = new File(['(⌐□_□)'], 'chucknorris.html', {
type: 'text/html'
});
fireEvent.change(screen.getByLabelText('Example label'), {
target: { files: [file] }
});
expect(screen.getByLabelText('Example label').files[0].name).toBe(
'chucknorris.html'
); //passes
userEvent.click(screen.getByText('Save'));
expect(console.log).toHaveBeenCalledWith('sucesso'); // fails
});
PS: I do have the console.log mocked