I am writing a button, which will be disabled after clicked and start 60s countdown before active again. Here is the relevant JS code:
<GeneralButton variant="contained" disabled={state} onClick={onBtnClick}>
Resend verification email
<br></br>
{state ? seconds : ""}
</GeneralButton>
const [state, setState] = useState(false);
const [seconds, setSeconds] = useState(60);
useEffect(() => {
let secondsInterval: string | number | NodeJS.Timeout | undefined;
if (state === true) {
secondsInterval = setInterval(() => {
setSeconds((prev) => prev - 1);
}, 1000);
}
return () => clearInterval(secondsInterval);
}, [state]);
const onBtnClick = () => {
setSeconds(60);
setState(true);
setTimeout(() => {
setState(false);
}, 60000);
};
The button actually works, but when I write test code as following:
describe("<EmailVerificationPage />", () => {
it("button should be disabled when clicked", () => {
render(<EmailVerificationPage />);
userEvent.click(screen.getByRole("button", { name: "Resend verification email" }));
// eslint-disable-next-line jest/valid-expect
expect(screen.getByText("Resend verification email").closest("button")).toBeDisabled();
});
});
it always shows that
Received element is not disabled:
<button tabindex="0" type="button" />
8 | userEvent.click(screen.getByRole("button", { name: "Resend verification email" }));
9 | // eslint-disable-next-line jest/valid-expect
> 10 | expect(screen.getByText("Resend verification email").closest("button")).toBeDisabled();
is there something wrong? Really appreciate any help!
CodePudding user response:
The state update might take some time to happen. Put the check inside an await waitFor block and see.
describe("<EmailVerificationPage />", async () => {
it("button should be disabled when clicked", () => {
render(<EmailVerificationPage />);
userEvent.click(screen.getByRole("button", { name: "Resend verification email" }));
// eslint-disable-next-line jest/valid-expect
await waitFor(() =>{
expect(screen.getByText("Resend verification
email").closest("button")).toBeDisabled()
});
});
});