I am using a formik form to sign up and testing it with react testing library. The submit button is disabled if the email or password fields are invalid. I am testing if my btn is enabled or disabled when i type certain input. I am performing 2 tests the first one with invalid inputs and the second with valid inputs but the first one is always passing even if it shouldn't. The 2nd test is behaving as it should
const MockedSignUpFormView=()=>{
return(
<BrowserRouter>
<SignUpFormView/>
</BrowserRouter>
)
}
it('btn is disabled if sign up with wrong credentials ',async () => {
render(<MockedSignUpFormView />);
const emailInput = screen.getByRole('textbox', { name: /email address/i});
const passInput = screen.getByPlaceholderText(/password/i);
const confirmPassInput = screen.getByLabelText(/confirm password/i);
const signUpBtn = screen.getByRole('button', { name: /sign up/i})
userEvent.type(emailInput,'mnbmbm@gmail.com')
userEvent.type(passInput,'sadasdas')
userEvent.type(confirmPassInput,'czxcxzcxz')
await waitFor(async ()=>{
expect(signUpBtn).not.toHaveAttribute('disabled')})
screen.debug()
});
it('btn is enabled if sign up with right credentials ',async () => {
render(<MockedSignUpFormView />);
const emailInput = screen.getByRole('textbox', { name: /email address/i});
const passInput = screen.getByPlaceholderText(/password/i);
const confirmPassInput = screen.getByLabelText(/confirm password/i);
const signUpBtn = screen.getByRole('button', { name: /sign up/i})
userEvent.type(emailInput,'mnbmbm@gmail.com')
userEvent.type(passInput,'czxcxzcxz')
userEvent.type(confirmPassInput,'czxcxzcxz')
await waitFor(async ()=>{
expect(signUpBtn).toBeEnabled()})
screen.debug()
});
I am using screen.debug and i am getting disabled on the first btn but still test keeps passing for this expect(signUpBtn).not.toHaveAttribute('disabled')})
and this expect(signUpBtn).not.toBeDisabled()
Sreen.debug() for first btn <button class="login__btn" disabled="" type="submit">
Sreen.debug() for 2nd btn <button class="login__btn" type="submit">
SignUpFormView component
const SignUpFormView=(props:any)=>{
const [error,setError]=useState(false);
const navigate=useNavigate ();
return(
<React.Fragment>
<Formik
initialValues={{
email: "",
password:"",
confirmPassword:""
}}
validationSchema={Yup.object({
password: Yup.string()
.min(6, "Must be 6 characters or more")
.required("Required"),
confirmPassword: Yup.string()
.min(6, "Must be 6 characters or more")
.required("Required")
.oneOf([Yup.ref('password'), null], 'Passwords must match'),
email: Yup.string()
.email("Invalid email address`")
.required("Required"),
})}
onSubmit={(values, { setSubmitting }) => {
props.onSubmitHandler(values.email,values.password).then((userCredential:any) => {
setSubmitting(false);
navigate('/home');
}).catch((err:any)=>{
setError(err.message);
})
}}>
{formik => {
return (
<nav className={classes["nav"]}>
<h2 className={classes['nav__detail']}>Sign Up</h2>
<Form className={classes['form__login']}>
<Input
label="Email Address"
name="email"
type="email"
/>
<Input
label="Password"
name="password"
type="password"
placeholder='Password'
/>
<Input
label="Confirm Password"
name="confirmPassword"
type="password"
/>
{(formik.isSubmitting || error) /*&& renderResponseItem(formik.isSubmitting,error)*/}
{!formik.isSubmitting && <button type="submit" disabled={!formik.isValid || formik.isSubmitting ? true :false} className={classes['login__btn']}>Sign Up</button>}
</Form>
<Link to='/'>Have an account? Login</Link>
</nav>
)
}
}
</Formik>
</React.Fragment>
)
}
Input component
import React from 'react';
import { useField } from "formik";
import classes from './InputView.module.css';
interface Props{
name:string,
id?:string,
placeholder?:string,
label:string,
type:string
}
const Input:React.FC<Props>=(props)=>{
const [field, meta] = useField(props);
const inputClasses=meta.touched && meta.error ? `${classes.input} ${classes.error}`:`${classes.input}`;
return (
<React.Fragment>
<label className={classes.label} htmlFor={props.id || props.name}>{props.label}</label>
<input className={inputClasses} {...field} {...props} id={props.name} placeholder={props?.placeholder}/>
</React.Fragment>
);
}