diff --git a/develop-docs/frontend/using-rtl.mdx b/develop-docs/frontend/using-rtl.mdx index d4803681c02ce..0cd83ed13bb92 100644 --- a/develop-docs/frontend/using-rtl.mdx +++ b/develop-docs/frontend/using-rtl.mdx @@ -77,6 +77,8 @@ router.navigate('/new/path/'); router.navigate(-1); // Simulates clicking the back button ``` +### Route Param Values + If you need to test route param values (as in `useParams()`), the `route` will need to be provided in the config: ```tsx @@ -97,6 +99,106 @@ const {router} = render(, { expect(screen.getByText('123')).toBeInTheDocument(); ``` +### Outlet Context + +If you need to test outlet param values (as in `useOutletContext()`), you can pass them inside the `initialRouterConfig` object. + +```tsx +function TestComponent() { + const { id } = useOutletContext(); + return
{id}
; +} + +const { router } = render(, { + initialRouterConfig: { + outletContext: { id: '123' }, + }, +}); + +expect(screen.getByText('123')).toBeInTheDocument(); +``` + +### Nested Routes + +If directly setting outlet context isn't enough, instead you want to render some nested routes you can do that too! + +Suppose routes.tsx defines some nested routes like: +```tsx +{ + path: 'settings/', + component: SettingsWrapper, + children: [ + {index: true, component: SettingsIndex}, + {path: ':projectId/', component: ProjectSettings}, + ] +} +``` + +We can configure the in-memory router to know about just the route tree that you need. Remember to render the wrapper component itself, and the router + route child components will render themsevles. +```tsx +// settingsWrapper.tsx +interface OutletContext { + name: string; +} + +export function useCustomOutletContext() { + return useOutletContext(); +} + +export default function SettingsWrapper() { + const context: OutletContext = {name: "Default"}; + return ; +} + +// settingsIndex.tsx +function SettingsIndex() { + const {name} = useCustomOutletContext(); + return
Settings > {name}
; +} + +// projectSettings.tsx +function ProjectSettings() { + const {name} = useCustomOutletContext(); + const {projectId} = useParams(); + return
Settings > {name} > Project: {projectId}
; +} + +// settingsIndex.spec.tsx +render(, { + initialRouterConfig: { + location: { + pathname: '/settings/', + }, + route: '/settings/', + children: [ + { + index: true, + element: , + }, + ], + }, +}); +expect(screen.getByText('Settings > Default')).toBeInTheDocument(); + +// projectSettings.spec.tsx +render(, { + initialRouterConfig: { + location: { + pathname: '/settings/123/', + }, + route: '/settings/:projectId', + children: [ + { + path: ':projectId/', + element: , + }, + ], + }, +}); +expect(screen.getByText('Settings > Default > Project: 123')).toBeInTheDocument(); +``` + + ## Querying - use `getBy...` as much as possible