@v4fire/client
Version:
V4Fire client core library
628 lines (494 loc) • 12.4 kB
JavaScript
/* eslint-disable max-lines-per-function */
// @ts-check
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/
/**
* @typedef {import('playwright').Page} Page
*/
const
h = include('tests/helpers').default;
/**
* Starts a test
*
* @param {Page} page
* @param {!Object} params
* @returns {!Promise<void>}
*/
module.exports = async (page, params) => {
await h.utils.setup(page, params.context);
beforeEach(async () => {
await page.evaluate(() => {
globalThis.removeCreatedComponents();
});
});
describe('b-dynamic-page', () => {
it("the `component` getter shouldn't be cached", async () => {
const target = await init({
page: 'p-v4-dynamic-page1'
});
expect(
await target.evaluate((ctx) => {
const {meta} = ctx;
return 'component' in meta.accessors && !('component' in meta.computedFields);
})
).toBeTrue();
});
it('setting `pageProp` and `page`', async () => {
const target = await init({
page: 'p-v4-dynamic-page1'
});
const scan = await target.evaluate(async (ctx) => {
const
res = [];
await ctx.nextTick();
res.push(ctx.page, ctx.component.componentName);
ctx.page = 'p-v4-dynamic-page2';
await ctx.nextTick();
res.push(ctx.page, ctx.component.componentName);
return res;
});
expect(scan).toEqual([
'p-v4-dynamic-page1',
'p-v4-dynamic-page1',
'p-v4-dynamic-page2',
'p-v4-dynamic-page2'
]);
});
it('switching between pages', async () => {
const
target = await init();
expect(await target.evaluate(switcher)).toEqual([
'p-v4-dynamic-page1',
'mounted',
'p-v4-dynamic-page1',
'mounted',
'// Previous component',
'destroyed',
'destroyed',
'destroyed',
'p-v4-dynamic-page1',
'mounted',
'// Previous component',
'destroyed',
'destroyed',
'destroyed'
]);
});
describe('providing `keep-alive`', () => {
it('switching between pages', async () => {
const target = await init({
keepAlive: true
});
expect(await target.evaluate(switcher)).toEqual([
'p-v4-dynamic-page1',
'activated',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'deactivated',
'deactivated',
'mounted',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'deactivated',
'deactivated',
'mounted'
]);
});
it('switching between pages with providing `keepAliveSize`', async () => {
const target = await init({
keepAlive: true,
keepAliveSize: 1
});
expect(
await target.evaluate(async (ctx) => {
const
res = [];
await ctx.router.push('page3');
const
prev = ctx.component;
res.push(ctx.component.componentName);
res.push(ctx.component.hook);
await ctx.router.push('page1');
await ctx.router.push('page2');
res.push(prev.componentName);
res.push(prev.hook);
return res;
})
).toEqual([
'p-v4-dynamic-page1',
'activated',
'p-v4-dynamic-page1',
'destroyed'
]);
});
describe('providing `include`', () => {
it('as a string', async () => {
const target = await init({
keepAlive: true,
include: 'p-v4-dynamic-page1'
});
expect(await target.evaluate(switcher)).toEqual([
'p-v4-dynamic-page1',
'activated',
'p-v4-dynamic-page1',
'mounted',
'// Previous component',
'deactivated',
'deactivated',
'mounted',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'destroyed',
'destroyed',
'destroyed'
]);
});
it('as a string array', async () => {
const target = await init({
keepAlive: true,
include: ['p-v4-dynamic-page1', 'p-v4-dynamic-page1']
});
expect(await target.evaluate(switcher)).toEqual([
'p-v4-dynamic-page1',
'activated',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'deactivated',
'deactivated',
'mounted',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'deactivated',
'deactivated',
'mounted'
]);
});
it('as a regular expression', async () => {
const target = await init({
keepAlive: true,
include: 'return /^p-v4-dynamic-page/'
});
expect(await target.evaluate(switcher)).toEqual([
'p-v4-dynamic-page1',
'activated',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'deactivated',
'deactivated',
'mounted',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'deactivated',
'deactivated',
'mounted'
]);
});
it('as a function that returns `null` or `false`', async () => {
const res = [
'p-v4-dynamic-page1',
'mounted',
'p-v4-dynamic-page1',
'mounted',
'// Previous component',
'destroyed',
'destroyed',
'destroyed',
'p-v4-dynamic-page1',
'mounted',
'// Previous component',
'destroyed',
'destroyed',
'destroyed'
];
{
const target = await init({
keepAlive: true,
include: 'return () => null'
});
expect(await target.evaluate(switcher)).toEqual(res);
}
{
const target = await init({
keepAlive: true,
include: 'return () => false'
});
expect(await target.evaluate(switcher)).toEqual(res);
}
});
it('as a function that returns `true` or a string', async () => {
const res = [
'p-v4-dynamic-page1',
'activated',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'deactivated',
'deactivated',
'mounted',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'deactivated',
'deactivated',
'mounted'
];
{
const target = await init({
keepAlive: true,
include: 'return () => true'
});
expect(await target.evaluate(switcher)).toEqual(res);
}
{
const target = await init({
keepAlive: true,
include: 'return (page) => page'
});
expect(await target.evaluate(switcher)).toEqual(res);
}
});
it('as a function that returns the cache strategy', async () => {
const include = `
return (page, route, ctx) => ({
cacheKey: page,
cacheGroup: page,
createCache: () => ctx.keepAliveCache.global
})`;
const target = await init({
keepAlive: true,
include
});
expect(await target.evaluate(switcher)).toEqual([
'p-v4-dynamic-page1',
'activated',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'deactivated',
'deactivated',
'mounted',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'deactivated',
'deactivated',
'mounted'
]);
});
});
describe('providing `exclude`', () => {
it('as a string', async () => {
const target = await init({
keepAlive: true,
exclude: 'p-v4-dynamic-page1'
});
expect(await target.evaluate(switcher)).toEqual([
'p-v4-dynamic-page1',
'mounted',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'destroyed',
'destroyed',
'destroyed',
'p-v4-dynamic-page1',
'mounted',
'// Previous component',
'deactivated',
'deactivated',
'mounted'
]);
});
it('as a string array', async () => {
const target = await init({
keepAlive: true,
exclude: ['p-v4-dynamic-page1', 'p-v4-dynamic-page1']
});
expect(await target.evaluate(switcher)).toEqual([
'p-v4-dynamic-page1',
'mounted',
'p-v4-dynamic-page1',
'mounted',
'// Previous component',
'destroyed',
'destroyed',
'destroyed',
'p-v4-dynamic-page1',
'mounted',
'// Previous component',
'destroyed',
'destroyed',
'destroyed'
]);
});
it('as a regular expression', async () => {
const target = await init({
keepAlive: true,
exclude: 'return /^p-v4-dynamic-page/'
});
expect(await target.evaluate(switcher)).toEqual([
'p-v4-dynamic-page1',
'mounted',
'p-v4-dynamic-page1',
'mounted',
'// Previous component',
'destroyed',
'destroyed',
'destroyed',
'p-v4-dynamic-page1',
'mounted',
'// Previous component',
'destroyed',
'destroyed',
'destroyed'
]);
});
it('as a function that returns `true`', async () => {
const target = await init({
keepAlive: true,
exclude: 'return () => true'
});
expect(await target.evaluate(switcher)).toEqual([
'p-v4-dynamic-page1',
'mounted',
'p-v4-dynamic-page1',
'mounted',
'// Previous component',
'destroyed',
'destroyed',
'destroyed',
'p-v4-dynamic-page1',
'mounted',
'// Previous component',
'destroyed',
'destroyed',
'destroyed'
]);
});
it('as a function that returns `false`', async () => {
const target = await init({
keepAlive: true,
exclude: 'return () => false'
});
expect(await target.evaluate(switcher)).toEqual([
'p-v4-dynamic-page1',
'activated',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'deactivated',
'deactivated',
'mounted',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'deactivated',
'deactivated',
'mounted'
]);
});
});
describe('providing `include` and `exclude`', () => {
it('`include` as a regular expression and `exclude` as a string', async () => {
const target = await init({
keepAlive: true,
include: 'return /p-v4-dynamic-page/',
exclude: 'p-v4-dynamic-page1'
});
expect(await target.evaluate(switcher)).toEqual([
'p-v4-dynamic-page1',
'activated',
'p-v4-dynamic-page1',
'mounted',
'// Previous component',
'deactivated',
'deactivated',
'mounted',
'p-v4-dynamic-page1',
'activated',
'// Previous component',
'destroyed',
'destroyed',
'destroyed'
]);
});
});
});
async function switcher(ctx) {
const
res = [];
let
prev;
await ctx.router.push('page3');
await ctx.router.push('page1');
res.push(ctx.component.componentName);
res.push(ctx.component.hook);
prev = ctx.component;
await ctx.router.push('page2');
res.push(ctx.component.componentName);
res.push(ctx.component.hook);
res.push('// Previous component');
res.push(prev.hook);
res.push(prev.block.element('button').component.hook);
res.push(prev.block.element('button-func').component.hook);
prev = ctx.component;
await ctx.router.push('page1');
res.push(ctx.component.componentName);
res.push(ctx.component.hook);
res.push('// Previous component');
res.push(prev.hook);
res.push(prev.block.element('button').component.hook);
res.push(prev.block.element('button-func').component.hook);
return res;
}
async function init(attrs = {}) {
await page.evaluate((attrs) => {
globalThis.renderComponents('b-router', [
{
attrs: {
routes: {
page1: {
path: '/page-1',
component: 'p-v4-dynamic-page1'
},
page2: {
path: '/page-2',
component: 'p-v4-dynamic-page1'
},
page3: {
path: '/page-3',
component: 'p-v4-dynamic-page1'
}
}
}
}
]);
Object.forEach(attrs, (el, key) => {
// eslint-disable-next-line no-new-func
attrs[key] = /return /.test(el) ? Function(el)() : el;
});
globalThis.renderComponents('b-dynamic-page', [
{
attrs: {
id: 'target',
...attrs
}
}
]);
}, attrs);
return h.component.waitForComponent(page, '#target');
}
});
};