mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-17 02:31:34 +08:00
fix(vue): routing history is correctly replaced when overwriting browser history (#24670)
resolves #23873
This commit is contained in:
@ -85,11 +85,25 @@ export const createLocationHistory = () => {
|
|||||||
locationHistory.push(routeInfo);
|
locationHistory.push(routeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
const clearHistory = () => {
|
/**
|
||||||
locationHistory.length = 0;
|
* Wipes the location history arrays.
|
||||||
|
* You can optionally provide a routeInfo
|
||||||
|
* object which will wipe that entry
|
||||||
|
* and every entry that appears after it.
|
||||||
|
*/
|
||||||
|
const clearHistory = (routeInfo?: RouteInfo) => {
|
||||||
Object.keys(tabsHistory).forEach(key => {
|
Object.keys(tabsHistory).forEach(key => {
|
||||||
tabsHistory[key] = [];
|
tabsHistory[key] = [];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (routeInfo) {
|
||||||
|
const existingRouteIndex = locationHistory.findIndex(r => r.position === routeInfo.position);
|
||||||
|
if (existingRouteIndex === -1) return;
|
||||||
|
|
||||||
|
locationHistory.splice(existingRouteIndex);
|
||||||
|
} else {
|
||||||
|
locationHistory.length = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const getTabsHistory = (tab: string): RouteInfo[] => {
|
const getTabsHistory = (tab: string): RouteInfo[] => {
|
||||||
let history;
|
let history;
|
||||||
@ -105,17 +119,6 @@ export const createLocationHistory = () => {
|
|||||||
|
|
||||||
const size = () => locationHistory.length;
|
const size = () => locationHistory.length;
|
||||||
|
|
||||||
const updateByHistoryPosition = (routeInfo: RouteInfo, updateEntries: boolean) => {
|
|
||||||
const existingRouteIndex = locationHistory.findIndex(r => r.position === routeInfo.position);
|
|
||||||
if (existingRouteIndex === -1) return;
|
|
||||||
|
|
||||||
locationHistory[existingRouteIndex].pathname = routeInfo.pathname;
|
|
||||||
|
|
||||||
if (updateEntries) {
|
|
||||||
locationHistory[existingRouteIndex].pushedByRoute = routeInfo.pushedByRoute;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds and returns the location history item
|
* Finds and returns the location history item
|
||||||
* given the state of browser's history API.
|
* given the state of browser's history API.
|
||||||
@ -205,7 +208,6 @@ export const createLocationHistory = () => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
current,
|
current,
|
||||||
updateByHistoryPosition,
|
|
||||||
size,
|
size,
|
||||||
last,
|
last,
|
||||||
previous,
|
previous,
|
||||||
@ -214,6 +216,7 @@ export const createLocationHistory = () => {
|
|||||||
update,
|
update,
|
||||||
getFirstRouteInfoForTab,
|
getFirstRouteInfoForTab,
|
||||||
getCurrentRouteInfoForTab,
|
getCurrentRouteInfoForTab,
|
||||||
findLastLocation
|
findLastLocation,
|
||||||
|
clearHistory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
|||||||
* new pages or updating history via the forward
|
* new pages or updating history via the forward
|
||||||
* and back browser buttons.
|
* and back browser buttons.
|
||||||
*/
|
*/
|
||||||
const initialHistoryPosition = opts.history.state.position as number;
|
let initialHistoryPosition = opts.history.state.position as number;
|
||||||
let currentHistoryPosition = opts.history.state.position as number;
|
let currentHistoryPosition = opts.history.state.position as number;
|
||||||
|
|
||||||
let currentRouteInfo: RouteInfo;
|
let currentRouteInfo: RouteInfo;
|
||||||
@ -159,8 +159,60 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
|||||||
leavingLocationInfo = locationHistory.previous();
|
leavingLocationInfo = locationHistory.previous();
|
||||||
} else if (incomingRouteParams.routerAction === 'pop') {
|
} else if (incomingRouteParams.routerAction === 'pop') {
|
||||||
leavingLocationInfo = locationHistory.current(initialHistoryPosition, currentHistoryPosition + 1);
|
leavingLocationInfo = locationHistory.current(initialHistoryPosition, currentHistoryPosition + 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the Ionic Router action was "pop"
|
||||||
|
* and the browser history action was "replace", then
|
||||||
|
* it is the case that the user clicked an IonBackButton
|
||||||
|
* that is trying to go back to the route specified
|
||||||
|
* by the defaultHref property.
|
||||||
|
*
|
||||||
|
* The problem is that this route currently does
|
||||||
|
* not exist in the browser history, and we cannot
|
||||||
|
* prepend an item in the browser's history stack.
|
||||||
|
* To work around this, we replace the state of
|
||||||
|
* the current item instead.
|
||||||
|
* Given this scenario:
|
||||||
|
* /page2 --> /page3 --> (back) /page2 --> (defaultHref) /page1
|
||||||
|
* We would replace the state of /page2 with the state of /page1.
|
||||||
|
*
|
||||||
|
* When doing this, we are essentially re-writing past
|
||||||
|
* history which makes the future history no longer relevant.
|
||||||
|
* As a result, we clear out the location history so that users
|
||||||
|
* can begin pushing new routes to the stack.
|
||||||
|
*
|
||||||
|
* This pattern is aligned with how the browser handles
|
||||||
|
* pushing new routes after going back as well as how
|
||||||
|
* other stack based operations such as undo/redo work.
|
||||||
|
* For example, if you do tasks A, B, C, undo B and C, and
|
||||||
|
* then do task D, you cannot "redo" B and C because you
|
||||||
|
* rewrote the stack's past history.
|
||||||
|
*
|
||||||
|
* With browser history, it is a similar concept.
|
||||||
|
* Going /page1 --> /page2 --> /page3 and then doing
|
||||||
|
* router.go(-2) will bring you back to /page1.
|
||||||
|
* If you then push /page4, you have rewritten
|
||||||
|
* the past history and you can no longer go
|
||||||
|
* forward to /page2 or /page3.
|
||||||
|
*/
|
||||||
|
if (action === 'replace') {
|
||||||
|
locationHistory.clearHistory();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
leavingLocationInfo = locationHistory.current(initialHistoryPosition, currentHistoryPosition - 1);
|
/**
|
||||||
|
* If the routerDirection was specified as "root", then
|
||||||
|
* we are replacing the initial state of location history
|
||||||
|
* with this incoming route. As a result, the leaving
|
||||||
|
* history info is stored at the same location as
|
||||||
|
* where the incoming history location will be stored.
|
||||||
|
*
|
||||||
|
* Otherwise, we can assume this is just another route
|
||||||
|
* that will be pushed onto the end of location history,
|
||||||
|
* so we can grab the previous item in history relative
|
||||||
|
* to where the history state currently is.
|
||||||
|
*/
|
||||||
|
const position = (incomingRouteParams.routerDirection === 'root') ? currentHistoryPosition : currentHistoryPosition - 1;
|
||||||
|
leavingLocationInfo = locationHistory.current(initialHistoryPosition, position);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
leavingLocationInfo = currentRouteInfo;
|
leavingLocationInfo = currentRouteInfo;
|
||||||
@ -285,26 +337,40 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) =>
|
|||||||
*/
|
*/
|
||||||
if (historySize > historyDiff && routeInfo.tab === undefined) {
|
if (historySize > historyDiff && routeInfo.tab === undefined) {
|
||||||
/**
|
/**
|
||||||
* When going from /a --> /a/1 --> /b, then going
|
* When navigating back through the history,
|
||||||
* back to /a, then going /a --> /a/2 --> /b, clicking
|
* if users then push a new route the future
|
||||||
* the ion-back-button should return us to /a/2, not /a/1.
|
* history stack is no longer relevant. As
|
||||||
* However, since the route entry for /b already exists,
|
* a result, we need to clear out all entries
|
||||||
* we need to update other information such as the "pushedByRoute"
|
* that appear after the current routeInfo
|
||||||
* so we know which route pushed this new route.
|
* so that we can then append the new history.
|
||||||
*
|
*
|
||||||
* However, when using router.go with a stride of >1 or <-1,
|
* This does not apply when using router.go
|
||||||
* we should not update this additional information because
|
* as that is traversing through the history,
|
||||||
* we are traversing through the history, not pushing new states.
|
* not altering it.
|
||||||
* Going from /a --> /b --> /c, then doing router.go(-2), then doing
|
*
|
||||||
* router.go(2) to go from /a --> /c should not update the route
|
* Previously we had only updated the existing route
|
||||||
* listing to say that /c was pushed by /a.
|
* and then left the future history alone. That
|
||||||
|
* worked for some use cases but was not sufficient
|
||||||
|
* in other scenarios.
|
||||||
*/
|
*/
|
||||||
const hasDeltaStride = delta !== undefined && Math.abs(delta) !== 1;
|
|
||||||
locationHistory.updateByHistoryPosition(routeInfo, !hasDeltaStride);
|
if (routeInfo.routerAction === 'push' && delta === undefined) {
|
||||||
|
locationHistory.clearHistory(routeInfo);
|
||||||
|
locationHistory.add(routeInfo);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
locationHistory.add(routeInfo);
|
locationHistory.add(routeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we recently reset the location history
|
||||||
|
* then we also need to update the initial
|
||||||
|
* history position.
|
||||||
|
*/
|
||||||
|
if (locationHistory.size() === 1) {
|
||||||
|
initialHistoryPosition = routeInfo.position;
|
||||||
|
}
|
||||||
|
|
||||||
currentRouteInfo = routeInfo;
|
currentRouteInfo = routeInfo;
|
||||||
}
|
}
|
||||||
incomingRouteParams = undefined;
|
incomingRouteParams = undefined;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { IonApp, IonRouterOutlet } from '@ionic/vue';
|
import { IonApp, IonRouterOutlet, useIonRouter } from '@ionic/vue';
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@ -13,6 +13,9 @@ export default defineComponent({
|
|||||||
components: {
|
components: {
|
||||||
IonApp,
|
IonApp,
|
||||||
IonRouterOutlet
|
IonRouterOutlet
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
(window as any).debugIonRouter = useIonRouter();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -400,6 +400,119 @@ describe('Routing', () => {
|
|||||||
cy.ionPageVisible('home');
|
cy.ionPageVisible('home');
|
||||||
cy.ionPageHidden('inputs');
|
cy.ionPageHidden('inputs');
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/23873
|
||||||
|
it('should correctly show pages after going back to defaultHref page', () => {
|
||||||
|
cy.visit('http://localhost:8080/default-href');
|
||||||
|
|
||||||
|
cy.routerPush('/routing');
|
||||||
|
cy.ionPageVisible('routing');
|
||||||
|
cy.ionPageHidden('defaulthref');
|
||||||
|
|
||||||
|
cy.ionBackClick('routing');
|
||||||
|
cy.ionPageDoesNotExist('routing');
|
||||||
|
cy.ionPageVisible('defaulthref');
|
||||||
|
|
||||||
|
cy.ionBackClick('defaulthref');
|
||||||
|
cy.ionPageDoesNotExist('defaulthref');
|
||||||
|
cy.ionPageVisible('home');
|
||||||
|
|
||||||
|
cy.routerPush('/default-href');
|
||||||
|
cy.ionPageVisible('defaulthref');
|
||||||
|
cy.ionPageHidden('home');
|
||||||
|
|
||||||
|
cy.routerPush('/routing');
|
||||||
|
cy.ionPageVisible('routing');
|
||||||
|
cy.ionPageHidden('defaulthref');
|
||||||
|
|
||||||
|
cy.ionBackClick('routing');
|
||||||
|
cy.ionPageDoesNotExist('routing');
|
||||||
|
cy.ionPageVisible('defaulthref');
|
||||||
|
|
||||||
|
cy.ionBackClick('defaulthref');
|
||||||
|
cy.ionPageDoesNotExist('defaulthref');
|
||||||
|
cy.ionPageVisible('home');
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should correctly update location history after rewriting past state', () => {
|
||||||
|
cy.visit('http://localhost:8080');
|
||||||
|
|
||||||
|
cy.routerPush('/routing');
|
||||||
|
cy.ionPageVisible('routing');
|
||||||
|
cy.ionPageHidden('home');
|
||||||
|
|
||||||
|
cy.routerPush('/inputs');
|
||||||
|
cy.ionPageVisible('inputs');
|
||||||
|
cy.ionPageHidden('routing');
|
||||||
|
|
||||||
|
cy.ionBackClick('inputs');
|
||||||
|
cy.ionPageVisible('routing');
|
||||||
|
cy.ionPageDoesNotExist('inputs');
|
||||||
|
|
||||||
|
cy.ionBackClick('routing');
|
||||||
|
cy.ionPageVisible('home');
|
||||||
|
cy.ionPageDoesNotExist('routing');
|
||||||
|
|
||||||
|
cy.routerPush('default-href');
|
||||||
|
cy.ionPageVisible('defaulthref');
|
||||||
|
cy.ionPageHidden('home');
|
||||||
|
|
||||||
|
cy.routerPush('/routing');
|
||||||
|
cy.ionPageVisible('routing');
|
||||||
|
cy.ionPageHidden('defaulthref');
|
||||||
|
|
||||||
|
cy.routerPush('/inputs');
|
||||||
|
cy.ionPageVisible('inputs');
|
||||||
|
cy.ionPageHidden('routing');
|
||||||
|
|
||||||
|
cy.ionBackClick('inputs');
|
||||||
|
cy.ionPageVisible('routing');
|
||||||
|
cy.ionPageDoesNotExist('inputs');
|
||||||
|
|
||||||
|
cy.ionBackClick('routing');
|
||||||
|
cy.ionPageVisible('defaulthref');
|
||||||
|
cy.ionPageDoesNotExist('routing');
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should correctly update location history after setting root state', () => {
|
||||||
|
cy.visit('http://localhost:8080');
|
||||||
|
|
||||||
|
cy.routerPush('/routing');
|
||||||
|
cy.ionPageVisible('routing');
|
||||||
|
cy.ionPageHidden('home');
|
||||||
|
|
||||||
|
cy.routerPush('/routing/1');
|
||||||
|
cy.ionPageVisible('routingparameter-1');
|
||||||
|
cy.ionPageHidden('routing');
|
||||||
|
|
||||||
|
cy.ionBackClick('routingparameter-1');
|
||||||
|
cy.ionPageVisible('routing');
|
||||||
|
cy.ionPageDoesNotExist('routingparameter-1');
|
||||||
|
|
||||||
|
cy.ionBackClick('routing');
|
||||||
|
cy.ionPageVisible('home');
|
||||||
|
cy.ionPageDoesNotExist('routing');
|
||||||
|
|
||||||
|
cy.ionRouterNavigate('/inputs', 'root')
|
||||||
|
cy.ionPageVisible('inputs');
|
||||||
|
cy.ionPageDoesNotExist('home');
|
||||||
|
|
||||||
|
cy.routerPush('/routing');
|
||||||
|
cy.ionPageVisible('routing');
|
||||||
|
cy.ionPageHidden('inputs');
|
||||||
|
|
||||||
|
cy.routerPush('/routing/1');
|
||||||
|
cy.ionPageVisible('routingparameter-1');
|
||||||
|
cy.ionPageHidden('routing');
|
||||||
|
|
||||||
|
cy.ionBackClick('routingparameter-1');
|
||||||
|
cy.ionPageVisible('routing');
|
||||||
|
cy.ionPageDoesNotExist('routingparameter-1');
|
||||||
|
|
||||||
|
cy.ionBackClick('routing');
|
||||||
|
cy.ionPageVisible('inputs');
|
||||||
|
cy.ionPageDoesNotExist('routing');
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Routing - Swipe to Go Back', () => {
|
describe('Routing - Swipe to Go Back', () => {
|
||||||
|
@ -82,6 +82,12 @@ Cypress.Commands.add('routerGo', (n) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('ionRouterNavigate', (...args) => {
|
||||||
|
cy.window().then(win => {
|
||||||
|
win.debugIonRouter.navigate(...args);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
Cypress.Commands.add('ionBackButtonHidden', (pageId) => {
|
Cypress.Commands.add('ionBackButtonHidden', (pageId) => {
|
||||||
cy.get(`div.ion-page[data-pageid=${pageId}]`)
|
cy.get(`div.ion-page[data-pageid=${pageId}]`)
|
||||||
.should('be.visible', true)
|
.should('be.visible', true)
|
||||||
|
@ -312,6 +312,124 @@ describe('Routing', () => {
|
|||||||
expect(cmpAgain[0].props()).toEqual({ title: 'xyz' });
|
expect(cmpAgain[0].props()).toEqual({ title: 'xyz' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO(FW-653) Either Ionic Vue or Vue Test Utils
|
||||||
|
* is leaking routing information between tests. Moving these tests
|
||||||
|
* to the end cause them to fail. Need to figure out what the root cause is.
|
||||||
|
*/
|
||||||
|
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/24109
|
||||||
|
it('canGoBack() should return the correct value', async () => {
|
||||||
|
const Page = {
|
||||||
|
components: { IonPage },
|
||||||
|
template: `<ion-page></ion-page>`
|
||||||
|
}
|
||||||
|
const Page2 = {
|
||||||
|
components: { IonPage },
|
||||||
|
template: `<ion-page></ion-page>`
|
||||||
|
}
|
||||||
|
const AppWithInject = {
|
||||||
|
components: { IonApp, IonRouterOutlet },
|
||||||
|
template: '<ion-app><ion-router-outlet /></ion-app>',
|
||||||
|
setup() {
|
||||||
|
const ionRouter = useIonRouter();
|
||||||
|
return { ionRouter }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHistory(process.env.BASE_URL),
|
||||||
|
routes: [
|
||||||
|
{ path: '/', component: Page }
|
||||||
|
{ path: '/page2', component: Page2 }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
router.push('/');
|
||||||
|
await router.isReady();
|
||||||
|
const wrapper = mount(AppWithInject, {
|
||||||
|
global: {
|
||||||
|
plugins: [router, IonicVue]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const ionRouter = wrapper.vm.ionRouter;
|
||||||
|
expect(ionRouter.canGoBack()).toEqual(false);
|
||||||
|
|
||||||
|
router.push('/page2');
|
||||||
|
await waitForRouter();
|
||||||
|
|
||||||
|
expect(ionRouter.canGoBack()).toEqual(true);
|
||||||
|
|
||||||
|
router.back();
|
||||||
|
await waitForRouter();
|
||||||
|
|
||||||
|
expect(ionRouter.canGoBack()).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/24109
|
||||||
|
it('canGoBack() should return the correct value when using router.go', async () => {
|
||||||
|
const Page = {
|
||||||
|
components: { IonPage },
|
||||||
|
template: `<ion-page></ion-page>`
|
||||||
|
}
|
||||||
|
const Page2 = {
|
||||||
|
components: { IonPage },
|
||||||
|
template: `<ion-page></ion-page>`
|
||||||
|
}
|
||||||
|
const Page3 = {
|
||||||
|
components: { IonPage },
|
||||||
|
template: `<ion-page></ion-page>`
|
||||||
|
}
|
||||||
|
const AppWithInject = {
|
||||||
|
components: { IonApp, IonRouterOutlet },
|
||||||
|
template: '<ion-app><ion-router-outlet /></ion-app>',
|
||||||
|
setup() {
|
||||||
|
const ionRouter = useIonRouter();
|
||||||
|
return { ionRouter }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHistory(process.env.BASE_URL),
|
||||||
|
routes: [
|
||||||
|
{ path: '/', component: Page }
|
||||||
|
{ path: '/page2', component: Page2 },
|
||||||
|
{ path: '/page3', component: Page3 },
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
router.push('/');
|
||||||
|
await router.isReady();
|
||||||
|
const wrapper = mount(AppWithInject, {
|
||||||
|
global: {
|
||||||
|
plugins: [router, IonicVue]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const ionRouter = wrapper.vm.ionRouter;
|
||||||
|
expect(ionRouter.canGoBack()).toEqual(false);
|
||||||
|
|
||||||
|
router.push('/page2');
|
||||||
|
await waitForRouter();
|
||||||
|
|
||||||
|
expect(ionRouter.canGoBack()).toEqual(true);
|
||||||
|
|
||||||
|
router.push('/page3');
|
||||||
|
await waitForRouter();
|
||||||
|
|
||||||
|
expect(ionRouter.canGoBack()).toEqual(true);
|
||||||
|
|
||||||
|
router.go(-2);
|
||||||
|
await waitForRouter();
|
||||||
|
|
||||||
|
expect(ionRouter.canGoBack()).toEqual(false);
|
||||||
|
|
||||||
|
router.go(2);
|
||||||
|
await waitForRouter();
|
||||||
|
|
||||||
|
expect(ionRouter.canGoBack()).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/23043
|
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/23043
|
||||||
it('should call the props function again when params change', async () => {
|
it('should call the props function again when params change', async () => {
|
||||||
const Page1 = {
|
const Page1 = {
|
||||||
@ -549,117 +667,4 @@ describe('Routing', () => {
|
|||||||
expect(wrapper.findComponent(Page2).exists()).toBe(false);
|
expect(wrapper.findComponent(Page2).exists()).toBe(false);
|
||||||
expect(wrapper.findComponent(Page3).exists()).toBe(false);
|
expect(wrapper.findComponent(Page3).exists()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/24109
|
|
||||||
it('canGoBack() should return the correct value', async () => {
|
|
||||||
const Page = {
|
|
||||||
components: { IonPage },
|
|
||||||
template: `<ion-page></ion-page>`
|
|
||||||
}
|
|
||||||
const Page2 = {
|
|
||||||
components: { IonPage },
|
|
||||||
template: `<ion-page></ion-page>`
|
|
||||||
}
|
|
||||||
const AppWithInject = {
|
|
||||||
components: { IonApp, IonRouterOutlet },
|
|
||||||
template: '<ion-app><ion-router-outlet /></ion-app>',
|
|
||||||
setup() {
|
|
||||||
const ionRouter = useIonRouter();
|
|
||||||
return { ionRouter }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const router = createRouter({
|
|
||||||
history: createWebHistory(process.env.BASE_URL),
|
|
||||||
routes: [
|
|
||||||
{ path: '/', component: Page }
|
|
||||||
{ path: '/page2', component: Page2 }
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
router.push('/');
|
|
||||||
await router.isReady();
|
|
||||||
const wrapper = mount(AppWithInject, {
|
|
||||||
global: {
|
|
||||||
plugins: [router, IonicVue]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const ionRouter = wrapper.vm.ionRouter;
|
|
||||||
expect(ionRouter.canGoBack()).toEqual(false);
|
|
||||||
|
|
||||||
router.push('/page2');
|
|
||||||
await waitForRouter();
|
|
||||||
|
|
||||||
expect(ionRouter.canGoBack()).toEqual(true);
|
|
||||||
|
|
||||||
router.back();
|
|
||||||
await waitForRouter();
|
|
||||||
|
|
||||||
expect(ionRouter.canGoBack()).toEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Verifies fix for https://github.com/ionic-team/ionic-framework/issues/24109
|
|
||||||
it('canGoBack() should return the correct value when using router.go', async () => {
|
|
||||||
const Page = {
|
|
||||||
components: { IonPage },
|
|
||||||
template: `<ion-page></ion-page>`
|
|
||||||
}
|
|
||||||
const Page2 = {
|
|
||||||
components: { IonPage },
|
|
||||||
template: `<ion-page></ion-page>`
|
|
||||||
}
|
|
||||||
const Page3 = {
|
|
||||||
components: { IonPage },
|
|
||||||
template: `<ion-page></ion-page>`
|
|
||||||
}
|
|
||||||
const AppWithInject = {
|
|
||||||
components: { IonApp, IonRouterOutlet },
|
|
||||||
template: '<ion-app><ion-router-outlet /></ion-app>',
|
|
||||||
setup() {
|
|
||||||
const ionRouter = useIonRouter();
|
|
||||||
return { ionRouter }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const router = createRouter({
|
|
||||||
history: createWebHistory(process.env.BASE_URL),
|
|
||||||
routes: [
|
|
||||||
{ path: '/', component: Page }
|
|
||||||
{ path: '/page2', component: Page2 },
|
|
||||||
{ path: '/page3', component: Page3 },
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
router.push('/');
|
|
||||||
await router.isReady();
|
|
||||||
const wrapper = mount(AppWithInject, {
|
|
||||||
global: {
|
|
||||||
plugins: [router, IonicVue]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const ionRouter = wrapper.vm.ionRouter;
|
|
||||||
expect(ionRouter.canGoBack()).toEqual(false);
|
|
||||||
|
|
||||||
router.push('/page2');
|
|
||||||
await waitForRouter();
|
|
||||||
|
|
||||||
expect(ionRouter.canGoBack()).toEqual(true);
|
|
||||||
|
|
||||||
router.push('/page3');
|
|
||||||
await waitForRouter();
|
|
||||||
|
|
||||||
expect(ionRouter.canGoBack()).toEqual(true);
|
|
||||||
|
|
||||||
router.go(-2);
|
|
||||||
await waitForRouter();
|
|
||||||
|
|
||||||
expect(ionRouter.canGoBack()).toEqual(false);
|
|
||||||
|
|
||||||
router.go(2);
|
|
||||||
await waitForRouter();
|
|
||||||
|
|
||||||
expect(ionRouter.canGoBack()).toEqual(true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user