it('text field', async () => {
const props = {
openConfirmationModal: jest.fn()
}
const { queryByTestId, findByTestId } = render(
<FormInputs
openConfirmationModal={props.openConfirmationModal}
/>
);
const input = queryByTestId('input-component-amount') as HTMLInputElement;
expect(input).toBeInTheDocument();
fireEvent.change(input, { target: { value: 123 } });
const textArea = queryByTestId('textarea-component-textfield') as HTMLTextAreaElement;
expect(textArea).toBeInTheDocument();
fireEvent.change(textArea, { target: { value: 'This is some text!' } });
const submitButton = queryByTestId('button') as HTMLButtonElement;
expect(submitButton).toBeInTheDocument();
expect(submitButton).toBeEnabled();
fireEvent.click(submitButton);
expect(props.openConfirmationModal).toHaveBeenCalledTimes(1);
const submitModalButton = queryByTestId('confirmation-modal-submit-button') as HTMLButtonElement;
expect(submitModalButton).toBeInTheDocument();
});
import React, { useState } from 'react';
interface FormInputsProps {
openConfirmationModal: () => void;
}
const FormInputs: React.FC<FormInputsProps> = ({ openConfirmationModal }) => {
const [amount, setAmount] = useState<string>('');
const [reason, setReason] = useState<string>('');
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const handleSubmit = () => {
if (amount && reason) {
openConfirmationModal();
setIsModalOpen(true);
}
};
const handleModalSubmit = () => {
Calling API....
setIsModalOpen(false); // Close modal on confirmation
};
return (
<div>
<input
data-testid="input-component-amount"
type="number"
value={amount}
onChange={(e) => setAmount(e.target.value)}
/>
<textarea
data-testid="textarea-component-textfield"
value={reason}
onChange={(e) => setReason(e.target.value)}
/>
<button
data-testid="button"
onClick={handleSubmit}
disabled={!amount || !reason}
>
Submit
</button>
{isModalOpen && (
<div data-testid="confirmation-modal">
<p>Are you sure you want to submit?</p>
<button
data-testid="confirmation-modal-submit-button"
onClick={handleModalSubmit}
>
Confirm
</button>
</div>
)}
</div>
);
};
export default FormInputs;
After expect(props.openConfirmationModal).toHaveBeenCalledTimes(1)
unable to see the modal and getting error "unable to find element" for const submitModalButton = queryByTestId('confirmation-modal-submit-button') as HTMLButtonElement
.
I see two issues, fireEvent and queryByTestId. Instead of using queryByTestId to find the elements you can directly use findBy or getBy to look for elements. findBy is preferred in case of async usage.
Issue is with the fireEvent, without the act block. I would suggest use userEvent from react testing library inside act block.
userEvent Docs Please refer to the correct version as latest version have few changes in it.
await act(async () => {
await userEvent.type(textArea, "This is some text!");
}
await act(async () => {
await userEvent.click(submitButton);
});
This is what always preferred. But in anycase if youw ant to continue with fireEvent it is always required to wrap it in act block.
await act(async () => {
fireEvent.change(textArea, { target: { value: 'This is some text!' } });
}
await act(async () => {
fireEvent.click(submitButton);
});
Usually async states do not propogate correctly when using fireEvent, unless it is wrapped in act