I am experiencing an issue after upgrading to React-Router version 7.6.2. I was able to replicate the failure: StackBlitz. Note that this test passed when I had v6 of React-Router-DOM.
The problem seems to be interacting with the react-router Link
component in the test. While the test can find the link text in the rendered Brother
component, invoking a click action should take us to a new route, i.e. "siblings/sister"
, and render a Sister
component. It is worth noting that when the app is running navigating to "siblings/brother"
, clicking the link, properly loads "/siblings/sister"
route and renders a Sister
component. It is only the problem to replicate this behavior in the RTL test.
- Navigate to Stackblitz terminal, on macOS Ctrl-C to stop the app
- Run
yarn test
So far my routing is configured:
<BrowserRouter>
<Routes>
<Route path="/siblings/*">
<Route path="*" element={<Navigate to="brother" />} />
<Route path="brother" element={<Brother />} />
<Route path="sister" element={<Sister />} />s
</Route>
</Routes>
</BrowserRouter>
The two components in question:
export const Brother = () => { return ( <Link to="/siblings/sister"> <span>i am a brother</span> </Link> ); };
export const Sister = () => { return <div>i am a sister</div>; };
Also my current test:
import { fireEvent, render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; import { MemoryRouter, Route, Router, Routes } from 'react-router'; import '@testing-library/jest-dom'; import { App, Brother, LocationDisplay } from './App';
const renderConnected = ( ui, { route = '', routeUrl = '', ...renderOptions } = {} ) => { // Makes sure the useLocation hook works in Menugrid header window.history.pushState({}, '', route);
const Wrapper = ({ children }) => ( <MemoryRouter initialEntries={[routeUrl]}> <Routes> <Route path={route} element={<div>{children}</div>} /> </Routes> </MemoryRouter> ); return render(ui, { wrapper: Wrapper, ...renderOptions }); };
test('full app rendering/navigating', async () => { const app = renderConnected(<Brother />, { route: '/siblings/', routeUrl: '/siblings/', });
const singleLink = app.getByRole('link', { name: /i am a brother/i });
// await userEvent.click(singleMenuLink); fireEvent.click(singleLink); expect(await app.findByText('i am a sister')).toBeInTheDocument(); });
And my package.json:
"dependencies": {
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router": "^7.6.2",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},