What i have is the simple page where I have the "Reset Password" button and "Confirm" button by defaut. If you will press "Reset password" it will be fetched from the server and displayed where this button was in "TextInput". Aslo "Confirm" button become active after that. Here is my component.
export default function App({ profileId, onClose }) {
const [ resetPasswordIsPressed, setResetPasswordIsPressed ] = useState(false);
const [ temporaryPassword, setTemporaryPassword ] = useState(null);
const [ isButtonDisabled, setIsButtonDisabled ] = true;
const handleUserUpdate = () => {
handleChangePassword(false);
onClose()
}
const handleChangePassword = async isPressed => {
const tempPassword = await fetchPassword(isPressed, profileId);
setTemporaryPassword(tempPassword);
setResetPasswordIsPressed(isPressed);
setIsButtonDisabled(false);
}
return (
<div className="App">
{ resetPasswordIsPressed ? (
<TextInput
isDisabled
testId='passwordInput'
value={temporaryPassword}
/>
) : (
<PasswrodResetButton
onClick={() => handleChangePassword(true)}
text='PasswordReset'
/>
)
}
<ConfirmButton isDisabled={isButtonDisabled} onClick={handleUserUpdate}/>
</div>
);
}
and here is fetch function which is imported from separate file
const fetchPassword = async (isPressed, profileId) => {
const getPassword = httpPost(userService, userendPoint);
try {
const {data} = await getPassword({
data: {
profileId
}
});
const { tempPassword } = data;
return tempPassword;
} catch (e) {
console.log(e.message)
}
}
What i need is to test that after clicking "Reset Password" handler was called, after that the "Reset Password" button is not on the page anymore, the "TextInput" with fetched password IS on the page, and the confirm button become active. Here is what I'm trying to do.
describe('User handlers', () => {
it('Should trigger reset password handler', async () => {
const mockCallBack = jest.fn();
const action = shallow(<PasswordResetButton onClick={mockCallBack}/>);
action.simulate('click');
await screen.findByTestId('passwordInput')
})
})
But got 'Unable to find and element by: [data-testid="passwordInput"]'
You're rendering your 'action' separately from your App component, which makes it completely independent.
I can't see in your code what 'screen' is, but most likely it's your shallowly rendered App component, and this is exactly where you need to find your <PasswordResetButton /> and click it.
If you were to add to your <PasswordResetButton /> a testid like you did to <TextInput />, you'd be able to do something like this:
it('Should trigger reset password handler', async () => {
const action = await screen.findByTestId('#passwordResetButton');
action.simulate('click');
const passwordInput = await screen.findByTestId('passwordInput');
expect(passwordInput).toHaveLength(1);
})
But again, I'm not sure what your screen variable is and what exactly screen.findByTestId does and returns.