UNPKG

@v4fire/client

Version:

V4Fire client core library

160 lines (130 loc) 4.54 kB
/*! * V4Fire Client Core * https://github.com/V4Fire/Client * * Released under the MIT license * https://github.com/V4Fire/Client/blob/master/LICENSE */ import type { JSHandle, Page } from 'playwright'; import type bDynamicPage from 'base/b-dynamic-page/b-dynamic-page'; import test from 'tests/config/unit/test'; import { Component } from 'tests/helpers'; test.describe('<b-dynamic-page>', () => { test.beforeEach(({demoPage}) => demoPage.goto()); test('should reuse the page component instance if the page does not change and the page key is not specified', async ({page}) => { const target = await renderDynamicPage( page, { keepAlive: true, include: (_, route) => Object.fastHash(route.params) }, { page1: { path: '/page-1/:id', component: 'p-v4-dynamic-page1' } } ); const isSamePageComponent = await target.evaluate(async (ctx) => { await ctx.router?.push('page1', {params: {id: 1}}); const page1Component = ctx.unsafe.$refs.component?.[0]; const routeTransition = ctx.unsafe.async.promisifyOnce(ctx.r, 'transition'); await ctx.router?.push('page1', {params: {id: 2}}); await routeTransition; const page2Component = ctx.unsafe.$refs.component?.[0]; return page1Component === page2Component; }); test.expect(isSamePageComponent).toBe(true); }); test('should create a new page component if the page does not change but the page key changes', async ({page}) => { const target = await renderDynamicPage( page, { keepAlive: true, eventConverter: (route) => ([route?.meta?.component ?? null, Object.fastHash(route?.params)]), include: (_, route) => Object.fastHash(route.params) }, { page1: { path: '/page-1/:id', component: 'p-v4-dynamic-page1' } } ); const isSamePageComponent = await target.evaluate(async (ctx) => { await ctx.router?.push('page1', {params: {id: 1}}); const page1Component = ctx.unsafe.$refs.component?.[0]; const routeTransition = ctx.unsafe.async.promisifyOnce(ctx.r, 'transition'); await ctx.router?.push('page1', {params: {id: 2}}); await routeTransition; const page2Component = ctx.unsafe.$refs.component?.[0]; return page1Component === page2Component; }); test.expect(isSamePageComponent).toBe(false); }); test('should emit the `beforeSwitchPage` event before removing the page element', async ({page}) => { const target = await renderDynamicPage(page, {keepAlive: true}); const count = await page.evaluateHandle(() => ({value: 0})); await target.evaluate((ctx, count) => { ctx.watch('rootEmitter:onBeforeSwitchPage', () => { count.value++; }); }, count); await target.evaluate(async (ctx) => { await ctx.router?.push('page1'); await ctx.router?.push('page2'); }); const calls = await count.evaluate(({value}) => value); test.expect(calls).toBe(1); }); test('should save and apply scroll to the cached page element for the children', async ({page}) => { const scrollOptions = {left: 200, top: 200}, target = await renderDynamicPage(page, {keepAlive: true}); await target.evaluate((ctx) => ctx.router?.push('page1')); const scroll = await page.getByTestId('scrollable'); await scroll.evaluate((el, [{top, left}]) => el.scrollTo({top, left}), [scrollOptions]); await target.evaluate((ctx) => ctx.router?.push('page2')); await test.expect(scroll).toBeHidden(); await target.evaluate((ctx) => ctx.router?.push('page1')); await test.expect(scroll.evaluate(scrollAfterRequestAnimationFrame)).resolves.toEqual(scrollOptions); function scrollAfterRequestAnimationFrame(el: Element): Promise<{top: number; left: number}> { return new Promise((resolve) => { requestAnimationFrame(() => resolve({top: el.scrollTop, left: el.scrollLeft})); }); } }); }); /** * Creates the `bRouter`, renders the `bDynamicPage` component and returns Promise<JSHandle> * * @param page * @param attrs * @param routesConfig */ export async function renderDynamicPage( page: Page, attrs: RenderComponentsVnodeParams['attrs'] = {}, routesConfig?: Dictionary ): Promise<JSHandle<bDynamicPage>> { await Component.createComponent(page, 'b-router', { attrs: { routes: routesConfig ?? { page1: { path: '/page-1', component: 'p-v4-dynamic-page1' }, page2: { path: '/page-2', component: 'p-v4-dynamic-page2' } } } }); return Object.cast(Component.createComponent(page, 'b-dynamic-page', { attrs: { id: 'target', ...attrs } })); }