T
TanStack6mo ago
wise-white

How can I test navigation with Cypress Component Tests?

I am struggling to find a reliable way to test transitions from one page to another using CY component tests. I created a custom mount that is wrapped using the following provider:
interface TestProvidersProps {
children: ReactNode;
initialEntries?: string[];
// RoutePaths is a generated type from Tanstack Router
routes?: Array<RoutePaths>;
}

function TestProviders({ children, initialEntries = ['/'], routes = [] }: TestProvidersProps) {
const rootRoute = useMemo(() => {
const root = createRootRoute();
if (routes.length) {
root.addChildren(
routes.map(route =>
createRoute({
path: route,
component: ({ children }) => <>{children}</>,
getParentRoute: () => root,
})
)
);
}
return root;
}, [routes]);

const router = useMemo(
() =>
createRouter({
routeTree: rootRoute,
defaultComponent: () => <>{children}</>,
defaultPreload: false,
history: createMemoryHistory({
initialEntries,
}),
}),
[children, initialEntries, rootRoute]
);

return <RouterProvider router={router as any} />;
}

// In test I call it like this
cy.mount(<SomeComponent />, {
// populating the history
initialEntries: [`/initial-path`, `/other-route`],
// router config
routes: [`_some-layout/initial-path`, `_some-layout/other-route`]
})

// then there is a redirection happing inside <SomeComponent /> using useNavigate, which redirects to /other-route, I don't necessarily want to display the other-route component, but just want it to navigate to that route
// Is there something wrong in my setup? Also, since im using Vite with CY, i can't stub/spy the useNavigate hook so that isn't option here
interface TestProvidersProps {
children: ReactNode;
initialEntries?: string[];
// RoutePaths is a generated type from Tanstack Router
routes?: Array<RoutePaths>;
}

function TestProviders({ children, initialEntries = ['/'], routes = [] }: TestProvidersProps) {
const rootRoute = useMemo(() => {
const root = createRootRoute();
if (routes.length) {
root.addChildren(
routes.map(route =>
createRoute({
path: route,
component: ({ children }) => <>{children}</>,
getParentRoute: () => root,
})
)
);
}
return root;
}, [routes]);

const router = useMemo(
() =>
createRouter({
routeTree: rootRoute,
defaultComponent: () => <>{children}</>,
defaultPreload: false,
history: createMemoryHistory({
initialEntries,
}),
}),
[children, initialEntries, rootRoute]
);

return <RouterProvider router={router as any} />;
}

// In test I call it like this
cy.mount(<SomeComponent />, {
// populating the history
initialEntries: [`/initial-path`, `/other-route`],
// router config
routes: [`_some-layout/initial-path`, `_some-layout/other-route`]
})

// then there is a redirection happing inside <SomeComponent /> using useNavigate, which redirects to /other-route, I don't necessarily want to display the other-route component, but just want it to navigate to that route
// Is there something wrong in my setup? Also, since im using Vite with CY, i can't stub/spy the useNavigate hook so that isn't option here
1 Reply
wise-white
wise-whiteOP6mo ago
I think the main question here is: how can I get the router to work in a test environment so that I can navigate from one page to another, I know that these kind of things are more reserved for E2E tests, but I do have a specific case here that I want to test on a component level.

Did you find this page helpful?