I've written a pretty straightforward test for react-router. The test is should simply test that the button with a to prop navigates to a new route on click.
const Routes = () => {
return (
<Switch>
<Route
exact
path="/"
render={() => (
<CornerButton to="/route">{btnText}</CornerButton>
)}
/>
<Route exact path="/route" render={() => <div>Route</div>} />
</Switch>
);
};
it("renders a route change with 'to' prop", async () => {
render(
<div>
<MemoryRouter initialEntries={["/"]}>
<Routes />
</MemoryRouter>
</div>
);
const btn = screen.getByRole("button", { name: btnText });
fireEvent.click(btn);
const newRoute = screen.getByText(/Route/i);
expect(newRoute).toBeInTheDocument();
});
I'm seeing the error:
TestingLibraryElementError: Unable to find an element with the text: /Route/i.
The button works fine and the rendered HTML looks good:
<body>
<div>
<div>
<a
class="sc-jgHCyG begwzL"
href="/route"
style="text-decoration: none;"
>
<button
class="sc-bBrOnJ gZtvsD"
color="primary"
type="button"
>
<div
class="sc-cOajty wNAWC"
>
<div
class="sc-khAkjo jvrrvJ"
>
text
</div>
<div
class="sc-AzgDb fmENQv"
/>
</div>
</button>
</a>
</div>
</div>
</body>
I'd love some help.
Edit:
I came closer to a solution but the behavior seems odd to me.
If I use: const btn = screen.getByRole("link", { name: btnText });
Instead of: const btn = screen.getByRole("button", { name: btnText });
Everything works. Does this somehow relate to the default behavior of the button? I do not call preventDefault() inside the component. But again, I have no problems clicking the button outside of tests.
const newRoute = await screen.fineByText(/Route/i);and it also failed with the same message.await waitFor(() => screen.getByText(/Route/i));. Perhaps HTML buttons don't have an aria-role of "button" by default since the semantics are already clear by the element type. Perhaps it is because the button captures the click event and isn't propagating it to the link that actually has the behavior. Did you try any other queries? I.E.ByLabelText,ByText,ByDisplayValue?"/"has been taken.