Skip to content

Commit 92398dc

Browse files
committed
fix(react-router): sync URL with display on browser back after tab switch
1 parent a1896e2 commit 92398dc

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

packages/react-router/src/ReactRouter/IonRouter.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,13 @@ export const IonRouter = ({ children, registerHistoryListener }: PropsWithChildr
272272
routeAction: 'pop',
273273
routeDirection: 'back',
274274
};
275+
} else if (prevInfo && prevInfo.pathname !== location.pathname && currentRoute.tab) {
276+
// Browser POP destination differs from within-tab back target.
277+
// Sync URL via replace, like handleNavigateBack's non-linear path (#25141).
278+
incomingRouteParams.current = { ...prevInfo, routeAction: 'pop', routeDirection: 'back' };
279+
forwardStack.current = [];
280+
handleNavigate(prevInfo.pathname + (prevInfo.search || ''), 'pop', 'back', undefined, undefined, prevInfo.tab);
281+
return;
275282
} else {
276283
incomingRouteParams.current = { ...prevInfo, routeAction: 'pop', routeDirection: 'back' };
277284
}

packages/react-router/test/apps/reactrouter6/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"test": "cypress open",
3131
"cypress": "node_modules/.bin/cypress run --headless --browser chrome",
3232
"cypress.open": "cypress open",
33-
"e2e": "concurrently \"serve -s build -l 3000\" \"wait-on http-get://localhost:3000 && npm run cypress\" --kill-others --success first",
33+
"e2e": "concurrently \"serve -s dist -l 3000\" \"wait-on http-get://localhost:3000 && npm run cypress\" --kill-others --success first",
3434
"playwright": "npx playwright test",
3535
"playwright.open": "npx playwright test --ui",
3636
"playwright.headed": "npx playwright test --headed",

packages/react-router/test/base/tests/e2e/playwright/tabs.spec.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { test, expect } from '@playwright/test';
22
import {
33
ionPageVisible, ionPageHidden, ionPageDoesNotExist,
4-
ionNav, ionBackClick, ionTabClick, withTestingMode
4+
ionNav, ionBackClick, ionTabClick, ionGoBack, withTestingMode
55
} from './utils/test-utils';
66

77
test.describe('Tabs', () => {
@@ -36,6 +36,34 @@ test.describe('Tabs', () => {
3636
await ionPageDoesNotExist(page, 'tab1');
3737
});
3838

39+
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/25141
40+
test('browser back from preserved child page should sync URL and display', async ({ page }, testInfo) => {
41+
testInfo.annotations.push({
42+
type: 'issue',
43+
description: 'https://github.com/ionic-team/ionic-framework/issues/25141',
44+
});
45+
46+
await page.goto(withTestingMode('/tabs/tab1'));
47+
await ionPageVisible(page, 'tab1');
48+
49+
await page.locator('#child-one').click();
50+
await ionPageHidden(page, 'tab1');
51+
await ionPageVisible(page, 'tab1child1');
52+
53+
await ionTabClick(page, 'Tab2');
54+
await ionPageHidden(page, 'tab1child1');
55+
await ionPageVisible(page, 'tab2');
56+
57+
await ionTabClick(page, 'Tab1');
58+
await ionPageHidden(page, 'tab2');
59+
await ionPageVisible(page, 'tab1child1');
60+
61+
await ionGoBack(page, '/tabs/tab1');
62+
await ionPageDoesNotExist(page, 'tab1child1');
63+
await ionPageVisible(page, 'tab1');
64+
await expect(page.locator('ion-tab-button.tab-selected')).toContainText('Tab1');
65+
});
66+
3967
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/23087
4068
test('should return to correct view and url when going back from child page after switching tabs', async ({ page }) => {
4169
await page.goto(withTestingMode('/tabs/tab1'));

0 commit comments

Comments
 (0)