mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
test(nested-params): adding extra coverage for deeply nested routing
This commit is contained in:
@@ -63,6 +63,7 @@ const UserLayout: React.FC = () => {
|
||||
<Route index element={<Navigate to="details" replace />} />
|
||||
<Route path="details" element={<UserDetails />} />
|
||||
<Route path="settings" element={<UserSettings />} />
|
||||
<Route path="profile/*" element={<ProfileLayout />} />
|
||||
</IonRouterOutlet>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
@@ -84,6 +85,79 @@ const UserDetails: React.FC = () => {
|
||||
<IonButton routerLink={`/nested-params/user/${userId}/settings`} id="go-to-settings">
|
||||
Go to Settings
|
||||
</IonButton>
|
||||
<IonButton routerLink={`/nested-params/user/${userId}/profile/edit`} id="go-to-profile-edit">
|
||||
Go to Profile Edit
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Deeply nested layout: /nested-params/user/:userId/profile/*
|
||||
* This tests 4 levels of outlet nesting with relative paths to validate
|
||||
* that derivePathnameToMatch correctly handles depth > 2 parent segments.
|
||||
*/
|
||||
const ProfileLayout: React.FC = () => {
|
||||
const { userId } = useParams<{ userId: string }>();
|
||||
|
||||
return (
|
||||
<IonPage data-pageid="nested-params-profile-layout">
|
||||
<IonHeader>
|
||||
<IonToolbar>
|
||||
<IonTitle>Profile Layout</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonContent>
|
||||
<IonLabel data-testid="profile-layout-param">Profile layout user: {userId ?? 'missing'}</IonLabel>
|
||||
<IonRouterOutlet ionPage id="nested-params-profile-outlet">
|
||||
<Route index element={<Navigate to="edit" replace />} />
|
||||
<Route path="edit" element={<ProfileEdit />} />
|
||||
<Route path="view" element={<ProfileView />} />
|
||||
</IonRouterOutlet>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
||||
const ProfileEdit: React.FC = () => {
|
||||
const { userId } = useParams<{ userId: string }>();
|
||||
|
||||
return (
|
||||
<IonPage data-pageid="nested-params-profile-edit">
|
||||
<IonHeader>
|
||||
<IonToolbar>
|
||||
<IonTitle>Profile Edit</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonContent>
|
||||
<IonLabel data-testid="profile-edit-param">Profile edit user: {userId ?? 'missing'}</IonLabel>
|
||||
<IonButton routerLink={`/nested-params/user/${userId}/profile/view`} id="go-to-profile-view">
|
||||
Go to Profile View
|
||||
</IonButton>
|
||||
<IonButton routerLink={`/nested-params/user/${userId}/details`} id="back-to-details">
|
||||
Back to Details
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
||||
const ProfileView: React.FC = () => {
|
||||
const { userId } = useParams<{ userId: string }>();
|
||||
|
||||
return (
|
||||
<IonPage data-pageid="nested-params-profile-view">
|
||||
<IonHeader>
|
||||
<IonToolbar>
|
||||
<IonTitle>Profile View</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonContent>
|
||||
<IonLabel data-testid="profile-view-param">Profile view user: {userId ?? 'missing'}</IonLabel>
|
||||
<IonButton routerLink={`/nested-params/user/${userId}/profile/edit`} id="back-to-profile-edit">
|
||||
Back to Profile Edit
|
||||
</IonButton>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
|
||||
@@ -222,6 +222,95 @@ describe('Nested Params', () => {
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Deep nesting tests (4 levels) to validate derivePathnameToMatch
|
||||
* handles relative paths correctly at depth > 2 parent segments.
|
||||
*
|
||||
* Route structure:
|
||||
* /nested-params/* (App level)
|
||||
* user/:userId/* (NestedParamsRoot outlet)
|
||||
* details (UserLayout outlet)
|
||||
* settings (UserLayout outlet)
|
||||
* profile/* (UserLayout outlet)
|
||||
* edit (ProfileLayout outlet - 4th level)
|
||||
* view (ProfileLayout outlet - 4th level)
|
||||
*/
|
||||
|
||||
it('/nested-params > Deep nesting > Navigate to profile edit (4 levels deep)', () => {
|
||||
cy.visit(`http://localhost:${port}/nested-params`);
|
||||
cy.ionPageVisible('nested-params-landing');
|
||||
|
||||
// Navigate to user 42 details
|
||||
cy.get('#go-to-user-42').click();
|
||||
cy.get('[data-testid="user-details-param"]').should('contain', 'Details view user: 42');
|
||||
|
||||
// Navigate to profile edit (4th level)
|
||||
cy.get('#go-to-profile-edit').click();
|
||||
cy.get('[data-testid="profile-layout-param"]').should('contain', 'Profile layout user: 42');
|
||||
cy.get('[data-testid="profile-edit-param"]').should('contain', 'Profile edit user: 42');
|
||||
cy.location('pathname').should('eq', '/nested-params/user/42/profile/edit');
|
||||
});
|
||||
|
||||
it('/nested-params > Deep nesting > Direct navigation to 4th level route', () => {
|
||||
// Navigate directly to a deeply nested route
|
||||
cy.visit(`http://localhost:${port}/nested-params/user/42/profile/edit`);
|
||||
|
||||
cy.get('[data-testid="profile-layout-param"]').should('contain', 'Profile layout user: 42');
|
||||
cy.get('[data-testid="profile-edit-param"]').should('contain', 'Profile edit user: 42');
|
||||
});
|
||||
|
||||
it('/nested-params > Deep nesting > Navigate between 4th level siblings (edit <-> view)', () => {
|
||||
cy.visit(`http://localhost:${port}/nested-params/user/42/profile/edit`);
|
||||
cy.get('[data-testid="profile-edit-param"]').should('contain', 'Profile edit user: 42');
|
||||
|
||||
// Navigate to profile view (sibling at 4th level)
|
||||
cy.get('#go-to-profile-view').click();
|
||||
cy.get('[data-testid="profile-view-param"]').should('contain', 'Profile view user: 42');
|
||||
cy.location('pathname').should('eq', '/nested-params/user/42/profile/view');
|
||||
|
||||
// Navigate back to profile edit
|
||||
cy.get('#back-to-profile-edit').click();
|
||||
cy.get('[data-testid="profile-edit-param"]').should('contain', 'Profile edit user: 42');
|
||||
cy.location('pathname').should('eq', '/nested-params/user/42/profile/edit');
|
||||
});
|
||||
|
||||
it('/nested-params > Deep nesting > Back navigation from 4th level to root', () => {
|
||||
cy.visit(`http://localhost:${port}/`);
|
||||
cy.ionPageVisible('home');
|
||||
|
||||
// Navigate to nested-params
|
||||
cy.contains('ion-item', 'Nested Params').click();
|
||||
cy.ionPageVisible('nested-params-landing');
|
||||
|
||||
// Navigate to user 42 details
|
||||
cy.get('#go-to-user-42').click();
|
||||
cy.get('[data-testid="user-details-param"]').should('contain', 'Details view user: 42');
|
||||
|
||||
// Navigate to profile edit (4th level)
|
||||
cy.get('#go-to-profile-edit').click();
|
||||
cy.get('[data-testid="profile-edit-param"]').should('contain', 'Profile edit user: 42');
|
||||
|
||||
// Navigate to profile view (sibling at 4th level)
|
||||
cy.get('#go-to-profile-view').click();
|
||||
cy.get('[data-testid="profile-view-param"]').should('contain', 'Profile view user: 42');
|
||||
|
||||
// Browser back: view -> edit
|
||||
cy.go('back');
|
||||
cy.get('[data-testid="profile-edit-param"]').should('contain', 'Profile edit user: 42');
|
||||
|
||||
// Browser back: edit -> details
|
||||
cy.go('back');
|
||||
cy.get('[data-testid="user-details-param"]').should('contain', 'Details view user: 42');
|
||||
|
||||
// Browser back: details -> landing
|
||||
cy.go('back');
|
||||
cy.ionPageVisible('nested-params-landing');
|
||||
|
||||
// Browser back: landing -> home
|
||||
cy.go('back');
|
||||
cy.ionPageVisible('home');
|
||||
});
|
||||
|
||||
it('/nested-params > Sibling route transitions > No nested scrollbars during transition', () => {
|
||||
// Start directly on the details page
|
||||
cy.visit(`http://localhost:${port}/nested-params/user/99/details`);
|
||||
|
||||
Reference in New Issue
Block a user