I'm having some problems that I'm not able to test the MUI dropdown. I'm getting this error: Unable to find an accessible element with the role "option" and name "/ninica/i"
I have an example code here: https://codesandbox.io/s/react-testing-library-material-ui-dropdown-5knbgu
My test:
test("select", () => {
render(<App />);
// Get and click in the dropdown
const dropdownButton = screen.getByRole("button", { name: /dog name /i });
fireEvent.click(dropdownButton);
// Get and click in the dropdown item
const dropdownItem = screen.getByRole("option", { name: /ninica/i });
fireEvent.click(dropdownItem);
});
I already try to use getByTestId
but have the same result, can't find.
Pls, any help :)
CodePudding user response:
First of all, for component interaction, prefer the use of userEvent
instead fireEvent
as testing-library
describes:
The built-in fireEvent is a utility to easily dispatch events. It dispatches exactly the events you tell it to and just those - even if those exact events never had been dispatched in a real interaction in a browser.
user-event on the other hand dispatches the events like they would happen if a user interacted with the document. That might lead to the same events you previously dispatched per fireEvent directly, but it also might catch bugs that make it impossible for a user to trigger said events. This is why you should use user-event to test interaction with your components.
You can check more about it here.
Related to test not find option
role, it´s because the element take some milliseconds to appear on screen and because of that your test should be async
and you need to use await
and findBy
query to succeed in the test:
import { render, screen, cleanup } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
test("select", async () => {
render(<App />);
const dropdownButton = screen.getByRole("button");
userEvent.click(dropdownButton);
const dropdownItem = await screen.findByRole("option", { name: /ninica/i });
userEvent.click(dropdownItem);
const typographyEl = await screen.findByText(/Chosen name: ninica/i);
expect(typographyEl).toBeInTheDocument();
});
You can check more about async/await
and findBy
query here.
You can also check the difference of queries here.
CodePudding user response:
Try
test("select", async () => {
render(<App />);
// Get and click in the dropdown
const dropdownButton = screen.getByRole("button", { name: /dog name /i });
fireEvent.click(dropdownButton);
// Wait for dropdown item and click it
const dropdownItem = await screen.findByTestId("name-item-2");
fireEvent.click(dropdownItem);
});
There are some ms in between the click and the apearance on the screen of the element, so you have declare your function as async
and to await
for your element to appear (and use findBy instead of getBy in order to work as async).
you can read more about testing-library async methods here