How can I find the first occurrence of an element using getBy*?
Asked Answered
P

1

17

My component has two similar forms (two forms with username/password fields), and two Submit buttons with the text 'Submit'. In order to test the submit handler, I'm mocking the type event for the form fields and then the clicking of the submit button like the following:

  it('test submit handler', async () => {
    const myProvider = ({children}) => <Provider store={store}>{children}</Provider>;
    render(<MyComponent />, {wrapper: myProvider});
    expect(await screen.findByText('username')).toBeTruthy();
    expect(await screen.findByText('password')).toBeTruthy();
    await userEvent.type(screen.getByLabelText('username'), 'someusername');
    await userEvent.type(screen.getByLabelText('password'), 'somepassword');
    fireEvent.click(screen.getByText('Submit'));
    await waitFor(() => expect(onSubmit).toBeCalledTimes(1));
  });
});

Doing this results in the error TestingLibraryElementError: Found multiple elements with the text: Submit. I looked up the docs for the getBy* methods and looks like they account for either the first element found or in case there's multiple, they throw an error, which is what's happening here. These two forms have different handler functions and I'd like to test that the two functions are being called on submit. What would be a good way to get access to the first occurrence of this Submit button?

I tried replacing the getByText with findByText but that results in returning a Promise { <pending> }, awaiting which results in the same TestingLibraryElementError error mentioned above.

Parasang answered 22/7, 2020 at 18:38 Comment(3)
Try fireEvent.click(screen.getAllByText('Submit')[0])Migdaliamigeon
this is super late but thanks a lot for helping with this. Your answer was the solution.Parasang
thank you both, for asking and aswering! It was the solutionHoran
B
9

In 2022, you use the userEvent package as it simulates real user behaviour:

userEvent.click(screen.getAllByText('Submit')[0])

Bonus: It's also better to find things by role as it ensures your code is accessibility friendly:

userEvent.click(screen.getAllByRole('button', { name: 'Submit'})[0])

Bryan answered 20/10, 2022 at 15:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.