mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
test(react-router): trying to make tests more reliable
This commit is contained in:
@@ -28,10 +28,12 @@ import { extractRouteChildren, getRoutesChildren, isNavigateElement } from './ut
|
||||
const VIEW_UNMOUNT_DELAY_MS = 250;
|
||||
|
||||
/**
|
||||
* Delay in milliseconds to wait for an IonPage element to be mounted before
|
||||
* proceeding with a page transition.
|
||||
* Delay (ms) to wait for an IonPage to mount before proceeding with a
|
||||
* page transition. Only container routes (nested outlets with no direct
|
||||
* IonPage) actually hit this timeout; normal routes clear it early via
|
||||
* registerIonPage, so a larger value here doesn't affect the happy path.
|
||||
*/
|
||||
const ION_PAGE_WAIT_TIMEOUT_MS = 50;
|
||||
const ION_PAGE_WAIT_TIMEOUT_MS = 300;
|
||||
|
||||
interface StackManagerProps {
|
||||
routeInfo: RouteInfo;
|
||||
|
||||
@@ -5,6 +5,10 @@ export default defineConfig({
|
||||
pageLoadTimeout: 6000000000,
|
||||
screenshotOnRunFailure: false,
|
||||
defaultCommandTimeout: 10000,
|
||||
retries: {
|
||||
runMode: 2,
|
||||
openMode: 0,
|
||||
},
|
||||
fixturesFolder: 'tests/e2e/fixtures',
|
||||
screenshotsFolder: 'tests/e2e/screenshots',
|
||||
videosFolder: 'tests/e2e/videos',
|
||||
|
||||
@@ -141,6 +141,8 @@ describe('Index Param Priority', () => {
|
||||
cy.get('[data-testid="notfound-page-label"]').should('contain', 'Page not found');
|
||||
|
||||
cy.get('#back-to-index-from-notfound').click();
|
||||
cy.url().should('include', '/index-param-priority');
|
||||
cy.wait(300);
|
||||
cy.ionPageVisible('index-param-priority-index');
|
||||
cy.get('[data-testid="index-page-label"]').should('contain', 'This is the index page');
|
||||
});
|
||||
|
||||
@@ -23,12 +23,10 @@ describe('Index Route Reuse - Nested Outlet Index Routes', () => {
|
||||
|
||||
// Switch to Tab 2
|
||||
cy.ionTabClick('Tab 2');
|
||||
cy.url().should('include', '/index-route-reuse/tab2');
|
||||
cy.ionPageVisible('irr-tab2-home');
|
||||
cy.get('[data-testid="irr-tab2-home-content"]').should('be.visible');
|
||||
cy.get('[data-testid="irr-tab2-home-content"]').should('contain', 'Tab 2 Index Route Content');
|
||||
|
||||
// Verify URL changed to tab2
|
||||
cy.url().should('include', '/index-route-reuse/tab2');
|
||||
});
|
||||
|
||||
it('should show tab3 index content when switching to tab3', () => {
|
||||
@@ -37,12 +35,10 @@ describe('Index Route Reuse - Nested Outlet Index Routes', () => {
|
||||
|
||||
// Switch to Tab 3
|
||||
cy.ionTabClick('Tab 3');
|
||||
cy.url().should('include', '/index-route-reuse/tab3');
|
||||
cy.ionPageVisible('irr-tab3-home');
|
||||
cy.get('[data-testid="irr-tab3-home-content"]').should('be.visible');
|
||||
cy.get('[data-testid="irr-tab3-home-content"]').should('contain', 'Tab 3 Index Route Content');
|
||||
|
||||
// Verify URL changed to tab3
|
||||
cy.url().should('include', '/index-route-reuse/tab3');
|
||||
});
|
||||
|
||||
it('should correctly show each tab index when cycling through all tabs', () => {
|
||||
@@ -52,18 +48,21 @@ describe('Index Route Reuse - Nested Outlet Index Routes', () => {
|
||||
|
||||
// Tab 1 -> Tab 2
|
||||
cy.ionTabClick('Tab 2');
|
||||
cy.url().should('include', '/index-route-reuse/tab2');
|
||||
cy.ionPageVisible('irr-tab2-home');
|
||||
cy.get('[data-testid="irr-tab2-home-content"]').should('be.visible');
|
||||
cy.get('[data-testid="irr-tab2-home-content"]').should('contain', 'Tab 2 Index Route Content');
|
||||
|
||||
// Tab 2 -> Tab 3
|
||||
cy.ionTabClick('Tab 3');
|
||||
cy.url().should('include', '/index-route-reuse/tab3');
|
||||
cy.ionPageVisible('irr-tab3-home');
|
||||
cy.get('[data-testid="irr-tab3-home-content"]').should('be.visible');
|
||||
cy.get('[data-testid="irr-tab3-home-content"]').should('contain', 'Tab 3 Index Route Content');
|
||||
|
||||
// Tab 3 -> Tab 1 (back to start)
|
||||
cy.ionTabClick('Tab 1');
|
||||
cy.url().should('include', '/index-route-reuse/tab1');
|
||||
cy.ionPageVisible('irr-tab1-home');
|
||||
cy.get('[data-testid="irr-tab1-home-content"]').should('be.visible');
|
||||
cy.get('[data-testid="irr-tab1-home-content"]').should('contain', 'Tab 1 Index Route Content');
|
||||
@@ -80,11 +79,13 @@ describe('Index Route Reuse - Nested Outlet Index Routes', () => {
|
||||
|
||||
// Switch to Tab 2
|
||||
cy.ionTabClick('Tab 2');
|
||||
cy.url().should('include', '/index-route-reuse/tab2');
|
||||
cy.ionPageVisible('irr-tab2-home');
|
||||
cy.get('[data-testid="irr-tab2-home-content"]').should('be.visible');
|
||||
|
||||
// Switch back to Tab 1 - should show detail (preserved history)
|
||||
cy.ionTabClick('Tab 1');
|
||||
cy.url().should('include', '/index-route-reuse/tab1');
|
||||
cy.ionPageVisible('irr-tab1-detail');
|
||||
cy.get('[data-testid="irr-tab1-detail-content"]').should('be.visible');
|
||||
});
|
||||
@@ -95,17 +96,21 @@ describe('Index Route Reuse - Nested Outlet Index Routes', () => {
|
||||
|
||||
// Rapid switching: Tab1 -> Tab2 -> Tab3 -> Tab2 -> Tab1
|
||||
cy.ionTabClick('Tab 2');
|
||||
cy.url().should('include', '/index-route-reuse/tab2');
|
||||
cy.ionPageVisible('irr-tab2-home');
|
||||
|
||||
cy.ionTabClick('Tab 3');
|
||||
cy.url().should('include', '/index-route-reuse/tab3');
|
||||
cy.ionPageVisible('irr-tab3-home');
|
||||
|
||||
cy.ionTabClick('Tab 2');
|
||||
cy.url().should('include', '/index-route-reuse/tab2');
|
||||
cy.ionPageVisible('irr-tab2-home');
|
||||
cy.get('[data-testid="irr-tab2-home-content"]').should('be.visible');
|
||||
cy.get('[data-testid="irr-tab2-home-content"]').should('contain', 'Tab 2 Index Route Content');
|
||||
|
||||
cy.ionTabClick('Tab 1');
|
||||
cy.url().should('include', '/index-route-reuse/tab1');
|
||||
cy.ionPageVisible('irr-tab1-home');
|
||||
cy.get('[data-testid="irr-tab1-home-content"]').should('be.visible');
|
||||
cy.get('[data-testid="irr-tab1-home-content"]').should('contain', 'Tab 1 Index Route Content');
|
||||
|
||||
@@ -17,15 +17,14 @@ describe('Non-linear POP Forward Navigation', () => {
|
||||
|
||||
// Browser back - this is a non-linear POP because settings route has no pushedByRoute.
|
||||
// The else branch should push the current location key onto forwardStack.
|
||||
cy.go('back');
|
||||
cy.ionGoBack('/routing/tabs/home/details/1');
|
||||
cy.ionPageVisible('home-details-page-1');
|
||||
cy.get('ion-tab-button.tab-selected').contains('Home');
|
||||
|
||||
// Browser forward - should be detected as forward navigation via forwardStack.
|
||||
// Without the fix, forwardStack is empty so this falls into the wrong branch
|
||||
// (else-if, treating it as back navigation with wrong animation).
|
||||
cy.go('forward');
|
||||
cy.wait(500);
|
||||
cy.ionGoForward('/routing/tabs/settings');
|
||||
cy.ionPageVisible('settings-page');
|
||||
cy.get('ion-tab-button.tab-selected').contains('Settings');
|
||||
});
|
||||
@@ -43,27 +42,25 @@ describe('Non-linear POP Forward Navigation', () => {
|
||||
cy.ionPageVisible('settings-page');
|
||||
|
||||
// Browser back (non-linear POP)
|
||||
cy.go('back');
|
||||
cy.ionGoBack('/routing/tabs/home/details/1');
|
||||
cy.ionPageVisible('home-details-page-1');
|
||||
|
||||
// Browser forward
|
||||
cy.go('forward');
|
||||
cy.wait(500);
|
||||
cy.ionGoForward('/routing/tabs/settings');
|
||||
cy.ionPageVisible('settings-page');
|
||||
|
||||
// Browser back again - without the fix, the forward stack is corrupted from
|
||||
// the previous misclassification, causing this back to be treated as forward.
|
||||
cy.go('back');
|
||||
cy.ionGoBack('/routing/tabs/home/details/1');
|
||||
cy.ionPageVisible('home-details-page-1');
|
||||
cy.get('ion-tab-button.tab-selected').contains('Home');
|
||||
|
||||
// One more forward/back cycle to verify stack integrity
|
||||
cy.go('forward');
|
||||
cy.wait(500);
|
||||
cy.ionGoForward('/routing/tabs/settings');
|
||||
cy.ionPageVisible('settings-page');
|
||||
cy.get('ion-tab-button.tab-selected').contains('Settings');
|
||||
|
||||
cy.go('back');
|
||||
cy.ionGoBack('/routing/tabs/home/details/1');
|
||||
cy.ionPageVisible('home-details-page-1');
|
||||
cy.get('ion-tab-button.tab-selected').contains('Home');
|
||||
});
|
||||
@@ -81,22 +78,21 @@ describe('Non-linear POP Forward Navigation', () => {
|
||||
cy.ionPageVisible('settings-page');
|
||||
|
||||
// Browser back (non-linear POP)
|
||||
cy.go('back');
|
||||
cy.ionGoBack('/routing/tabs/home/details/1');
|
||||
cy.ionPageVisible('home-details-page-1');
|
||||
|
||||
// Browser forward to Settings
|
||||
cy.go('forward');
|
||||
cy.wait(500);
|
||||
cy.ionGoForward('/routing/tabs/settings');
|
||||
cy.ionPageVisible('settings-page');
|
||||
|
||||
// Browser back to D1
|
||||
cy.go('back');
|
||||
cy.ionGoBack('/routing/tabs/home/details/1');
|
||||
cy.ionPageVisible('home-details-page-1');
|
||||
|
||||
// Browser back to Home. The D1 route lost its pushedByRoute when it was
|
||||
// recreated via a non-linear POP, so this back also goes through the
|
||||
// non-linear else branch.
|
||||
cy.go('back');
|
||||
cy.ionGoBack('/routing/tabs/home');
|
||||
cy.ionPageVisible('home-page');
|
||||
cy.contains('[data-pageid=home-page]', '"routeAction":"pop"');
|
||||
cy.contains('[data-pageid=home-page]', '"pathname":"/routing/tabs/home"');
|
||||
|
||||
@@ -89,6 +89,22 @@ Cypress.Commands.add('ionTabClick', (tabText) => {
|
||||
cy.contains('ion-tab-button', tabText).click({ force: true });
|
||||
});
|
||||
|
||||
Cypress.Commands.add('ionGoBack', (expectedUrlPart) => {
|
||||
cy.go('back');
|
||||
if (expectedUrlPart) {
|
||||
cy.url().should('include', expectedUrlPart);
|
||||
}
|
||||
cy.wait(300);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('ionGoForward', (expectedUrlPart) => {
|
||||
cy.go('forward');
|
||||
if (expectedUrlPart) {
|
||||
cy.url().should('include', expectedUrlPart);
|
||||
}
|
||||
cy.wait(300);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('ionBackClick', (pageId) => {
|
||||
cy.get(`div.ion-page[data-pageid=${pageId}]`)
|
||||
.should('be.visible', true)
|
||||
|
||||
Reference in New Issue
Block a user