@v4fire/client
Version:
V4Fire client core library
255 lines (202 loc) • 6.61 kB
JavaScript
/* eslint-disable max-lines,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
*/
const
delay = require('delay'),
h = include('tests/helpers').default;
/**
* Starts a test
*
* @param {Playwright.Page} page
* @param {!Object} params
* @returns {!Promise<void>}
*/
module.exports = async (page, params) => {
await h.utils.setup(page, params.context);
let
componentNode,
component,
resizeWatcher,
divNode;
beforeAll(async () => {
componentNode = await h.dom.waitForEl(page, '#dummy-component');
component = await h.component.waitForComponent(page, '#dummy-component');
resizeWatcher = await component.evaluateHandle((ctx) => ctx.modules.resizeWatcher);
await component.evaluate((ctx) => globalThis.dummy = ctx);
});
beforeEach(async () => {
await resizeWatcher.evaluate((ctx) => {
if (globalThis.target == null) {
return;
}
ctx.clear(globalThis.target);
globalThis.target.remove();
});
// eslint-disable-next-line no-inline-comments
await componentNode.evaluate((/** @type HTMLElement */ ctx) => {
ctx.innerHTML = '';
const div = document.createElement('div');
div.id = 'div-target';
ctx.appendChild(div);
Object.assign(div.style, {
height: '200px',
width: '200px',
display: 'block',
transition: ''
});
globalThis.tmp = undefined;
globalThis.target = div;
});
divNode = await page.$('#div-target');
});
describe('core/dom/resize-observer', () => {
it('invokes the initial callback', async () => {
await resizeWatcher.evaluate((ctx) => {
globalThis.fn = () => globalThis.tmp = true;
ctx.observe(globalThis.target, globalThis.fn);
});
await expectAsync(page.waitForFunction(() => globalThis.tmp === true)).toBeResolved();
});
it('does not invoke the initial callback', async () => {
await resizeWatcher.evaluate((ctx) => {
globalThis.fn = () => globalThis.tmp = true;
ctx.observe(globalThis.target, {
callback: globalThis.fn,
initial: false
});
});
await delay(300);
expect(await page.evaluate(() => globalThis.tmp)).toBeUndefined();
});
it('invokes once with `once` settled to `true`', async () => {
await resizeWatcher.evaluate((ctx) => {
globalThis.tmp = 0;
globalThis.fn = () => globalThis.tmp += 1;
ctx.observe(globalThis.target, {
callback: globalThis.fn,
once: true,
initial: false
});
});
await page.evaluate(() => globalThis.target.style.width = '300px');
await h.bom.waitForIdleCallback(page);
await page.evaluate(() => globalThis.target.style.width = '320px');
await h.bom.waitForIdleCallback(page);
expect(await page.evaluate(() => globalThis.tmp)).toBe(1);
});
it('invokes the callback after an element width has been changed `watchWidth: true`', async () => {
await resizeWatcher.evaluate((ctx) => {
globalThis.fn = () => globalThis.tmp = true;
ctx.observe(globalThis.target, {
callback: globalThis.fn,
initial: false,
watchHeight: false,
watchWidth: true
});
});
await h.bom.waitForIdleCallback(page);
await page.evaluate(() => globalThis.target.style.width = '300px');
await h.bom.waitForIdleCallback(page);
expect(await page.evaluate(() => globalThis.tmp)).toBeTrue();
});
it('does not invoke the callback after an element width has been changed `watchWidth: false`', async () => {
await resizeWatcher.evaluate((ctx) => {
globalThis.fn = () => globalThis.tmp = true;
ctx.observe(globalThis.target, {
callback: globalThis.fn,
initial: false,
watchHeight: true,
watchWidth: false
});
});
await h.bom.waitForIdleCallback(page);
await divNode.evaluate((ctx) => ctx.style.width = '300px');
await h.bom.waitForIdleCallback(page);
expect(await page.evaluate(() => globalThis.tmp)).toBeUndefined();
});
it('invokes the callback after an element height has been changed', async () => {
await resizeWatcher.evaluate((ctx) => {
globalThis.fn = () => globalThis.tmp = true;
ctx.observe(globalThis.target, {
callback: globalThis.fn,
initial: false,
watchHeight: true,
watchWidth: false
});
});
await h.bom.waitForIdleCallback(page);
await divNode.evaluate((ctx) => ctx.style.height = '300px');
await h.bom.waitForIdleCallback(page);
await expectAsync(page.waitForFunction(() => globalThis.tmp)).toBeResolved();
});
it('invokes the lazy callback after an element width has been changed', async () => {
await resizeWatcher.evaluate((ctx) => {
globalThis.tmp = 0;
globalThis.fn = () => globalThis.tmp += 1;
ctx.observe(globalThis.target, {
callback: globalThis.fn,
initial: false,
watchHeight: false,
watchWidth: true
});
});
await divNode.evaluate((ctx) => new Promise((res) => {
let flag = true;
const interval = setInterval(() => {
ctx.style.width = flag === true ? '400px' : '300px';
flag = !flag;
}, 30);
setTimeout(() => {
clearInterval(interval);
res();
}, 300);
}));
await h.bom.waitForIdleCallback(page);
expect(await page.evaluate(() => globalThis.tmp)).toBe(1);
});
it('invokes the callback multiple times if the size of an element has been changed', async () => {
await resizeWatcher.evaluate((ctx) => {
globalThis.tmp = 0;
globalThis.fn = () => globalThis.tmp += 1;
ctx.observe(globalThis.target, {
callback: globalThis.fn,
initial: false,
watchHeight: false,
watchWidth: true,
immediate: true
});
});
await divNode.evaluate((ctx) => new Promise((res) => {
let flag = true;
const interval = setInterval(() => {
ctx.style.width = flag === true ? '400px' : '300px';
flag = !flag;
}, 30);
setTimeout(() => {
clearInterval(interval);
res();
}, 300);
}));
expect(await page.evaluate(() => globalThis.tmp)).toBeGreaterThan(1);
});
it('unobserved element does not invokes the callback', async () => {
await resizeWatcher.evaluate((ctx) => {
globalThis.fn = () => globalThis.tmp = true;
ctx.observe(globalThis.target, {
callback: globalThis.fn,
initial: false
});
ctx.unobserve(globalThis.target, globalThis.fn);
});
await divNode.evaluate((ctx) => ctx.style.height = '300px');
await h.bom.waitForIdleCallback(page);
expect(await page.evaluate(() => globalThis.tmp)).toBeUndefined();
});
});
};