import { mount } from '@vue/test-utils'; import { createRouter, createWebHistory } from '@ionic/vue-router'; import { IonicVue, IonApp, IonRouterOutlet, IonPage } from '@ionic/vue'; import { defineComponent } from 'vue'; import { waitForRouter } from './utils'; const App = { components: { IonApp, IonRouterOutlet }, template: '', } const BasePage = { template: '', components: { IonPage }, } const Page1 = { ...BasePage, data() { return { name: 'page1' } }, ionViewWillEnter: jest.fn(), ionViewDidEnter: jest.fn(), ionViewWillLeave: jest.fn(), ionViewDidLeave: jest.fn(), } const Page2 = defineComponent({ ...BasePage, setup() { return { name: 'page2' } }, ionViewWillEnter: jest.fn(), ionViewDidEnter: jest.fn(), ionViewWillLeave: jest.fn(), ionViewDidLeave: jest.fn(), }); const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes: [ { path: '/', component: Page1 }, { path: '/2', component: Page2 } ] }); describe('Lifecycle Events', () => { beforeAll(() => { (HTMLElement.prototype as HTMLIonRouterOutletElement).commit = jest.fn(); }); it('Triggers lifecycle events', async () => { // Initial render router.push('/'); await router.isReady(); const wrapper = mount(App, { global: { plugins: [router, IonicVue] } }); // Page 1 lifecycle hooks expect(Page1.ionViewWillEnter).toHaveBeenCalledWith(); expect(Page1.ionViewWillEnter.mock.instances[0]).toEqual(expect.objectContaining({ name: 'page1' })) expect(Page1.ionViewDidEnter).toHaveBeenCalled(); expect(Page1.ionViewDidEnter.mock.instances[0]).toEqual(expect.objectContaining({ name: 'page1' })) expect(Page1.ionViewWillLeave).not.toHaveBeenCalled(); expect(Page1.ionViewDidLeave).not.toHaveBeenCalled(); expect(wrapper.html()).toContain('page1'); // Page 2 lifecycle hooks expect(Page2.ionViewWillEnter).not.toHaveBeenCalled(); expect(Page2.ionViewDidEnter).not.toHaveBeenCalled(); expect(Page2.ionViewWillLeave).not.toHaveBeenCalled(); expect(Page2.ionViewDidLeave).not.toHaveBeenCalled(); // Navigate to 2nd page router.push('/2'); jest.resetAllMocks(); await waitForRouter(); // Page 1 lifecycle hooks expect(Page1.ionViewDidEnter).not.toHaveBeenCalled(); expect(Page1.ionViewWillEnter).not.toHaveBeenCalled(); expect(Page1.ionViewWillLeave).toHaveBeenCalled(); expect(Page1.ionViewWillLeave.mock.instances[0]).toEqual(expect.objectContaining({ name: 'page1' })) expect(Page1.ionViewDidLeave).toHaveBeenCalled(); expect(Page1.ionViewDidLeave.mock.instances[0]).toEqual(expect.objectContaining({ name: 'page1' })) // Page 2 lifecycle hooks expect(Page2.ionViewWillEnter).toHaveBeenCalled(); expect((Page2.ionViewWillEnter as jest.Mock).mock.instances[0]).toEqual(expect.objectContaining({ name: 'page2' })) expect(Page2.ionViewDidEnter).toHaveBeenCalled(); expect((Page2.ionViewDidEnter as jest.Mock).mock.instances[0]).toEqual(expect.objectContaining({ name: 'page2' })) expect(Page2.ionViewWillLeave).not.toHaveBeenCalled(); expect(Page2.ionViewDidLeave).not.toHaveBeenCalled(); expect(wrapper.html()).toContain('page2'); }); });