I test my SimpleForm, but even after writing input successfuly, my SaveButton is still disabled (contains className 'Mui-disabled').
npm packages useful here:
Toolbar:
const SaveCancelDeleteToolbar = (props: SaveCancelDeleteToolbarProps) => {
const { closeDrawer, handleCancel } = props
const translate = useTranslate()
const {
formState: { isValid },
} = useFormContext()
return (
<Toolbar>
<SaveButton disabled={!isValid} onClick={closeDrawer} />
<Button onClick={handleCancel}>{translate('ra.action.cancel')}</Button>
</Toolbar>
)
}
Form:
<SimpleForm mode="all" reValidateMode="onChange" toolbar={toolbar}>
<TextInput
data-testid="form.value"
label="resources.values.fields.value"
source="value"
validate={[required(), maxLength(50), noEmptySpace]}
/>
</SimpleForm>
To prevent react-hook-form crash on test env, I have to use a wrapper to add const formMethods = useForm()
Test file:
it('should be able to create element', async () => {
// ValueList contains somewhere the SimpleForm.
const { user, ...utils } = setup(
<FormContextWrapper resource="vat-rates">
<ValueList deleted={false} />
</FormContextWrapper>
)
/* Some code that open my SimpleForm **/
// Check that SaveButton is disabled when pristine
const saveButton = await screen.findByText('ra.action.save')
expect(saveButton.outerHTML.includes('Mui-disabled')).toBe(true)
const divValue = await screen.findByTestId(
'form.value'
)
const inputValue = divValue.children[1].children[0]
fireEvent.focus(inputValue )
await user.type(inputValue , '1')
fireEvent.blur(inputValue )
// This expect is successful, my input has been set to '1'.
expect(inputValue.value).toBe('1')
await waitFor(() => {
const saveButton2 = screen.getByText('ra.action.save')
// This expect fails. saveButton2 exist.
// Its outerHTML is the following. In react-admin I saw that in DOM, disabled is always "" so I check with 'Mui-disabled' presence.
// `<button class="LotsOfClasses Mui-disabled" tabindex="-1" type="submit" disabled="" aria-label="ra.action.save">ra.action.save</button>`
expect(saveButton2.outerHTML.includes('Mui-disabled')).toBe(false)
})
})
For an unknown reason, the SaveCancelDeleteToolbar component is not rerendered on test environment. And so isValid stays false and SaveButton still has 'Mui-disabled' className.
Please help, testing forms is a very important process that cannot be neglected.
As @slax57 said, it was the wrapper workaround that was problematic.
For a reason still unknown to me, on test environnement "both the esm and change version of react-hook-form was being loaded".
Solution was to add the following lines to vite.config.js
file.
resolve: {
alias: {
'react-hook-form': require.resolve('react-hook-form'),
}
}