Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

userEvent.type not updating value of input in test

I am testing this component, which is simply changing its state depending on new input into the input field and setting the value of the input element to that state.

function Login () {
    //Login Credentials
    const [loginCredentials, setLoginCredentials] = useState({ name: '' })
    const handleChange = ({target}) => {
        setLoginCredentials(prev => ({ ...prev, [target.name]: target.value }));
    }

    return (
            <div className="login-container">
                <h1>Log In</h1>
                    <div className="login-label-input">
                        <label htmlFor="name">Account Name
                            <input
                            type="name"
                            id="name"
                            name="name"
                            placeholder="Enter Name"
                            onChange={handleChange}
                            value={loginCredentials.name}
                            aria-label="name"
                            />
                        </label>
                  </div>
             </div>
    )
}

and for some reason this test does not show the value of input to be "testUser" in screen.debug() but only "t"....


    test("log in with empty name input returns error message",  () => {
    render(<Login />)
    const nameField = screen.getByLabelText(/account name/i);
    userEvent.type(nameField, 'testUser'); 
    screen.debug()
});

Shouldn't this work? Why doesn't it? excerpt from screen.debug():

           <label
              for="name"
            >
              Account Name
              <input
                aria-label="name"
                id="name"
                name="name"
                placeholder="Enter Name"
                type="name"
                value="t"
              />
            </label>
like image 562
SirNoob Avatar asked Nov 16 '22 02:11

SirNoob


2 Answers

In the current version of @testing-library/user-event: ^14.2.0 and its corresponding official docs, there is an example where calling userEvent.type is awaited:

test('type into an input field', async () => {
  render(<input defaultValue="Hello," />)
  const input = screen.getByRole('textbox')

  await userEvent.type(input, ' World!')

  expect(input).toHaveValue('Hello, World!')
})

Callback in test() needs to be declared as async then, of course.

Link to this in the docs at time of writing: https://testing-library.com/docs/user-event/utility/#type

Nice to know maybe: Also works with uncontrolled components.

like image 150
anarchist912 Avatar answered Mar 06 '23 23:03

anarchist912


If you update jest to the latest version it will work. Currently, the latest jest is 26.6.3

This issue was discussed here: https://github.com/testing-library/user-event/issues/387

like image 22
Kristjan Retter Avatar answered Mar 06 '23 23:03

Kristjan Retter