mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-22 10:10:36 +03:00
switch to playwright test runner, use esbuild for dev builds, switch to array destructuring
This commit is contained in:
@@ -1,55 +0,0 @@
|
||||
import 'jest-playwright-preset';
|
||||
import 'expect-playwright';
|
||||
import url from './.build/build.html';
|
||||
|
||||
describe('StructureLifecycle', () => {
|
||||
beforeEach(async () => {
|
||||
await jestPlaywright.resetPage();
|
||||
await page.goto(url);
|
||||
});
|
||||
|
||||
[false, true].forEach(async (nativeScrollbarStyling) => {
|
||||
const withText = nativeScrollbarStyling ? 'with' : 'without';
|
||||
const nss = async () => {
|
||||
if (!nativeScrollbarStyling) {
|
||||
await page.click('#nss');
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
};
|
||||
|
||||
describe(`structureLifecycles ${withText} native scrollbar styling`, () => {
|
||||
test('default', async () => {
|
||||
await nss();
|
||||
await page.click('#start');
|
||||
await expect(page).toHaveSelector('#testResult.passed');
|
||||
});
|
||||
|
||||
test('without flexbox glue & css custom props', async () => {
|
||||
await nss();
|
||||
await page.click('#fbg');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#ccp');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#start');
|
||||
await expect(page).toHaveSelector('#testResult.passed');
|
||||
});
|
||||
|
||||
// firefox can't simulate partially overlaid scrollbars, boost speed by omitting webkit
|
||||
test.jestPlaywrightSkip({ browsers: ['firefox', 'webkit'] }, 'with partially overlaid scrollbars', async () => {
|
||||
await nss();
|
||||
await page.click('#po');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#start');
|
||||
await expect(page).toHaveSelector('#testResult.passed');
|
||||
});
|
||||
|
||||
test('with fully overlaid scrollbars', async () => {
|
||||
await nss();
|
||||
await page.click('#fo');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#start');
|
||||
await expect(page).toHaveSelector('#testResult.passed');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
import 'jest-playwright-preset';
|
||||
import 'expect-playwright';
|
||||
import url from './.build/build.html';
|
||||
|
||||
describe('DOMObserver', () => {
|
||||
beforeEach(async () => {
|
||||
await jestPlaywright.resetPage();
|
||||
await page.goto(url);
|
||||
});
|
||||
|
||||
test('test', async () => {
|
||||
await page.click('#start');
|
||||
await expect(page).toHaveSelector('#testResult.passed');
|
||||
});
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
import 'jest-playwright-preset';
|
||||
import 'expect-playwright';
|
||||
import url from './.build/build.html';
|
||||
|
||||
describe('SizeObserver', () => {
|
||||
beforeEach(async () => {
|
||||
await jestPlaywright.resetPage();
|
||||
await page.goto(url);
|
||||
});
|
||||
|
||||
test('with ResizeOserver', async () => {
|
||||
await page.click('#start');
|
||||
await expect(page).toHaveSelector('#testResult.passed');
|
||||
});
|
||||
|
||||
test('with ResizeOserver polyfill', async () => {
|
||||
await page.click('#roPolyfill');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#start');
|
||||
await expect(page).toHaveSelector('#testResult.passed');
|
||||
});
|
||||
});
|
||||
@@ -1,31 +0,0 @@
|
||||
import 'jest-playwright-preset';
|
||||
import 'expect-playwright';
|
||||
import url from './.build/build.html';
|
||||
|
||||
describe('TrinsicObserver', () => {
|
||||
beforeEach(async () => {
|
||||
await jestPlaywright.resetPage();
|
||||
await page.goto(url);
|
||||
});
|
||||
|
||||
test('with IntersectionObserver', async () => {
|
||||
await page.click('#start');
|
||||
await expect(page).toHaveSelector('#testResult.passed');
|
||||
});
|
||||
|
||||
test('with ResizeObserver', async () => {
|
||||
await page.click('#ioPolyfill');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#start');
|
||||
await expect(page).toHaveSelector('#testResult.passed');
|
||||
});
|
||||
|
||||
test('with ResizeObserver polyfill', async () => {
|
||||
await page.click('#ioPolyfill');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#roPolyfill');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#start');
|
||||
await expect(page).toHaveSelector('#testResult.passed');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,902 @@
|
||||
import {
|
||||
Environment,
|
||||
StructureInitializationStaticElement,
|
||||
StructureInitializationDynamicElement,
|
||||
} from 'environment';
|
||||
import { OSTarget, StructureInitialization } from 'typings';
|
||||
import { createStructureSetup, StructureSetup } from 'setups/structureSetup';
|
||||
import { isHTMLElement } from 'support';
|
||||
|
||||
const mockGetEnvironment = jest.fn();
|
||||
jest.mock('environment', () => {
|
||||
return {
|
||||
getEnvironment: jest.fn().mockImplementation(() => mockGetEnvironment()),
|
||||
};
|
||||
});
|
||||
|
||||
interface StructureSetupProxy {
|
||||
input: OSTarget | StructureInitialization;
|
||||
setup: StructureSetup;
|
||||
}
|
||||
|
||||
const textareaId = 'textarea';
|
||||
const textareaHostId = 'host';
|
||||
const elementId = 'target';
|
||||
const dynamicContent = 'text<p>paragraph</p>';
|
||||
const textareaContent = `<textarea id="${textareaId}">text</textarea>`;
|
||||
const getSnapshot = () => document.body.innerHTML;
|
||||
const getTarget = (textarea?: boolean) =>
|
||||
document.getElementById(textarea ? textareaId : elementId)!;
|
||||
const fillBody = (textarea?: boolean, customDOM?: (content: string, hostId: string) => string) => {
|
||||
document.body.innerHTML = `
|
||||
<nav></nav>
|
||||
${
|
||||
customDOM
|
||||
? customDOM(
|
||||
textarea ? textareaContent : dynamicContent,
|
||||
textarea ? textareaHostId : elementId
|
||||
)
|
||||
: textarea
|
||||
? textareaContent
|
||||
: `<div id="${elementId}">${dynamicContent}</div>`
|
||||
}
|
||||
<footer></footer>
|
||||
`;
|
||||
return getSnapshot();
|
||||
};
|
||||
const clearBody = () => {
|
||||
document.body.innerHTML = '';
|
||||
};
|
||||
|
||||
const getElements = (textarea?: boolean) => {
|
||||
const target = getTarget(textarea);
|
||||
const host = document.querySelector('.os-host')!;
|
||||
const padding = document.querySelector('.os-padding')!;
|
||||
const viewport = document.querySelector('.os-viewport')!;
|
||||
const content = document.querySelector('.os-content')!;
|
||||
|
||||
return {
|
||||
target,
|
||||
host,
|
||||
padding,
|
||||
viewport,
|
||||
content,
|
||||
};
|
||||
};
|
||||
|
||||
const assertCorrectDOMStructure = (textarea?: boolean) => {
|
||||
const { target, host, padding, viewport, content } = getElements(textarea);
|
||||
|
||||
expect(host).toBeTruthy();
|
||||
expect(viewport).toBeTruthy();
|
||||
expect(viewport.parentElement).toBe(padding || host);
|
||||
|
||||
if (content) {
|
||||
expect(content.parentElement).toBe(viewport);
|
||||
}
|
||||
if (padding) {
|
||||
expect(padding.parentElement).toBe(host);
|
||||
}
|
||||
|
||||
expect(host.parentElement).toBe(document.body);
|
||||
expect(host.previousElementSibling).toBe(document.querySelector('nav'));
|
||||
expect(host.nextElementSibling).toBe(document.querySelector('footer'));
|
||||
|
||||
const contentElm = content || viewport;
|
||||
if (textarea) {
|
||||
expect(target.parentElement).toBe(contentElm);
|
||||
expect(contentElm.innerHTML).toBe(textareaContent);
|
||||
} else {
|
||||
expect(target).toBe(host);
|
||||
expect(contentElm.innerHTML).toBe(dynamicContent);
|
||||
}
|
||||
};
|
||||
|
||||
const createStructureSetupProxy = (
|
||||
target: OSTarget | StructureInitialization
|
||||
): StructureSetupProxy => ({
|
||||
input: target,
|
||||
setup: createStructureSetup(target),
|
||||
});
|
||||
|
||||
const assertCorrectSetup = (
|
||||
textarea: boolean,
|
||||
setupProxy: StructureSetupProxy,
|
||||
environment: Environment
|
||||
): StructureSetup => {
|
||||
const { input, setup } = setupProxy;
|
||||
const { _targetObj, _targetCtx, _destroy } = setup;
|
||||
const { _target, _host, _padding, _viewport, _content } = _targetObj;
|
||||
const { target, host, padding, viewport, content } = getElements(textarea);
|
||||
const isTextarea = target.matches('textarea');
|
||||
const isBody = target.matches('body');
|
||||
|
||||
expect(textarea).toBe(isTextarea);
|
||||
|
||||
expect(_target).toBe(target);
|
||||
expect(_host).toBe(host);
|
||||
|
||||
if (padding || _padding) {
|
||||
expect(_padding).toBe(padding);
|
||||
} else {
|
||||
expect(padding).toBeFalsy();
|
||||
expect(_padding).toBeFalsy();
|
||||
}
|
||||
|
||||
if (viewport || _viewport) {
|
||||
expect(_viewport).toBe(viewport);
|
||||
} else {
|
||||
expect(viewport).toBeFalsy();
|
||||
expect(_viewport).toBeFalsy();
|
||||
}
|
||||
|
||||
if (content || _content) {
|
||||
expect(_content).toBe(content);
|
||||
} else {
|
||||
expect(content).toBeFalsy();
|
||||
expect(_content).toBeFalsy();
|
||||
}
|
||||
|
||||
const { _isTextarea, _isBody, _bodyElm, _htmlElm, _documentElm, _windowElm } = _targetCtx;
|
||||
|
||||
expect(_isTextarea).toBe(isTextarea);
|
||||
expect(_isBody).toBe(isBody);
|
||||
expect(_windowElm).toBe(document.defaultView);
|
||||
expect(_documentElm).toBe(document);
|
||||
expect(_htmlElm).toBe(document.body.parentElement);
|
||||
expect(_bodyElm).toBe(document.body);
|
||||
|
||||
expect(typeof _destroy).toBe('function');
|
||||
|
||||
const { _nativeScrollbarStyling, _cssCustomProperties, _getInitializationStrategy } = environment;
|
||||
const {
|
||||
_host: hostInitStrategy,
|
||||
_viewport: viewportInitStrategy,
|
||||
_padding: paddingInitStrategy,
|
||||
_content: contentInitStrategy,
|
||||
} = _getInitializationStrategy();
|
||||
const inputIsElement = isHTMLElement(input);
|
||||
const inputAsObj = input as StructureInitialization;
|
||||
const styleElm = document.querySelector('style');
|
||||
const checkStrategyDependendElements = (
|
||||
elm: Element | null,
|
||||
input: HTMLElement | boolean | undefined,
|
||||
isStaticStrategy: boolean,
|
||||
strategy: StructureInitializationStaticElement | StructureInitializationDynamicElement,
|
||||
id: string
|
||||
) => {
|
||||
if (input) {
|
||||
expect(elm).toBeTruthy();
|
||||
} else {
|
||||
if (input === false) {
|
||||
expect(elm).toBeFalsy();
|
||||
}
|
||||
if (input === undefined) {
|
||||
if (isStaticStrategy) {
|
||||
strategy = strategy as StructureInitializationStaticElement;
|
||||
if (typeof strategy === 'function') {
|
||||
const result = strategy(target);
|
||||
if (result) {
|
||||
expect(result).toBe(elm);
|
||||
} else {
|
||||
expect(elm).toBeTruthy();
|
||||
}
|
||||
} else {
|
||||
expect(elm).toBeTruthy();
|
||||
}
|
||||
} else {
|
||||
strategy = strategy as StructureInitializationDynamicElement;
|
||||
const expectDefaultValue = () => {
|
||||
if (id === 'padding') {
|
||||
if (_nativeScrollbarStyling) {
|
||||
expect(elm).toBeFalsy();
|
||||
} else {
|
||||
expect(elm).toBeTruthy();
|
||||
}
|
||||
} else if (id === 'content') {
|
||||
expect(elm).toBeFalsy();
|
||||
}
|
||||
};
|
||||
if (typeof strategy === 'function') {
|
||||
const result = strategy(target);
|
||||
const resultIsBoolean = typeof result === 'boolean';
|
||||
if (resultIsBoolean) {
|
||||
if (result) {
|
||||
expect(elm).toBeTruthy();
|
||||
} else {
|
||||
expect(elm).toBeFalsy();
|
||||
}
|
||||
} else if (result) {
|
||||
expect(elm).toBe(result);
|
||||
} else {
|
||||
expectDefaultValue();
|
||||
}
|
||||
} else {
|
||||
const strategyIsBoolean = typeof strategy === 'boolean';
|
||||
if (strategyIsBoolean) {
|
||||
if (strategy) {
|
||||
expect(elm).toBeTruthy();
|
||||
} else {
|
||||
expect(elm).toBeFalsy();
|
||||
}
|
||||
} else {
|
||||
expectDefaultValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (_nativeScrollbarStyling || _cssCustomProperties) {
|
||||
expect(styleElm).toBeFalsy();
|
||||
} else {
|
||||
expect(styleElm).toBeTruthy();
|
||||
}
|
||||
|
||||
if (inputIsElement) {
|
||||
checkStrategyDependendElements(padding, undefined, false, paddingInitStrategy, 'padding');
|
||||
checkStrategyDependendElements(content, undefined, false, contentInitStrategy, 'content');
|
||||
checkStrategyDependendElements(viewport, undefined, true, viewportInitStrategy, 'viewport');
|
||||
checkStrategyDependendElements(host, undefined, true, hostInitStrategy, 'host');
|
||||
} else {
|
||||
const {
|
||||
padding: inputPadding,
|
||||
content: inputContent,
|
||||
viewport: inputViewport,
|
||||
host: inputHost,
|
||||
} = inputAsObj;
|
||||
checkStrategyDependendElements(padding, inputPadding, false, paddingInitStrategy, 'padding');
|
||||
checkStrategyDependendElements(content, inputContent, false, contentInitStrategy, 'content');
|
||||
checkStrategyDependendElements(viewport, inputViewport, true, viewportInitStrategy, 'viewport');
|
||||
checkStrategyDependendElements(host, inputHost, true, hostInitStrategy, 'host');
|
||||
}
|
||||
|
||||
return setup;
|
||||
};
|
||||
|
||||
const assertCorrectDestroy = (snapshot: string, setup: StructureSetup) => {
|
||||
const { _destroy } = setup;
|
||||
|
||||
_destroy();
|
||||
|
||||
// remove empty class attr
|
||||
const elms = document.querySelectorAll('*');
|
||||
Array.from(elms).forEach((elm) => {
|
||||
const classAttr = elm.getAttribute('class');
|
||||
if (classAttr === '') {
|
||||
elm.removeAttribute('class');
|
||||
}
|
||||
});
|
||||
|
||||
expect(snapshot).toBe(getSnapshot());
|
||||
};
|
||||
|
||||
const env: Environment = jest.requireActual('environment').getEnvironment();
|
||||
const envDefault = {
|
||||
name: 'default',
|
||||
env,
|
||||
};
|
||||
const envNativeScrollbarStyling = {
|
||||
name: 'native scrollbar styling',
|
||||
env: {
|
||||
...env,
|
||||
_nativeScrollbarStyling: true,
|
||||
},
|
||||
};
|
||||
const envCssCustomProperties = {
|
||||
name: 'custom css properties',
|
||||
env: {
|
||||
...env,
|
||||
_cssCustomProperties: true,
|
||||
},
|
||||
};
|
||||
const envInitStrategyMin = {
|
||||
name: 'initialization strategy min',
|
||||
env: {
|
||||
...env,
|
||||
_getInitializationStrategy: () => ({
|
||||
_host: null,
|
||||
_viewport: () => null,
|
||||
_content: () => false,
|
||||
_padding: false,
|
||||
_scrollbarsSlot: null,
|
||||
}),
|
||||
},
|
||||
};
|
||||
const envInitStrategyMax = {
|
||||
name: 'initialization strategy max',
|
||||
env: {
|
||||
...env,
|
||||
_getInitializationStrategy: () => ({
|
||||
_host: null,
|
||||
_viewport: null,
|
||||
_content: true,
|
||||
_padding: () => true,
|
||||
_scrollbarsSlot: null,
|
||||
}),
|
||||
},
|
||||
};
|
||||
const envInitStrategyAssigned = {
|
||||
name: 'initialization strategy assigned',
|
||||
env: {
|
||||
...env,
|
||||
_getInitializationStrategy: () => ({
|
||||
_host: () => document.querySelector('#host1') as HTMLElement,
|
||||
_viewport: (target: HTMLElement) => target.querySelector('#viewport') as HTMLElement,
|
||||
_content: (target: HTMLElement) => target.querySelector('#content') as HTMLElement,
|
||||
_padding: (target: HTMLElement) => target.querySelector('#padding') as HTMLElement,
|
||||
_scrollbarsSlot: null,
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
describe('structureSetup', () => {
|
||||
afterEach(() => clearBody());
|
||||
|
||||
[
|
||||
envDefault,
|
||||
envNativeScrollbarStyling,
|
||||
envCssCustomProperties,
|
||||
envInitStrategyMin,
|
||||
envInitStrategyMax,
|
||||
envInitStrategyAssigned,
|
||||
].forEach((envWithName) => {
|
||||
const { env: currEnv, name } = envWithName;
|
||||
describe(`Environment: ${name}`, () => {
|
||||
beforeAll(() => {
|
||||
mockGetEnvironment.mockImplementation(() => currEnv);
|
||||
});
|
||||
|
||||
[false, true].forEach((isTextarea) => {
|
||||
describe(isTextarea ? 'textarea' : 'element', () => {
|
||||
describe('basic', () => {
|
||||
test('Element', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy(getTarget(isTextarea)),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('Object', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({ target: getTarget(isTextarea) }),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('complex', () => {
|
||||
describe('single assigned', () => {
|
||||
test('padding', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="content">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('multiple assigned', () => {
|
||||
test('padding viewport content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding"><div id="viewport"><div id="content">${content}</div></div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('padding viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding"><div id="viewport">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('padding content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding"><div id="content">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('viewport content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport"><div id="content">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('single false', () => {
|
||||
test('padding', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
target: getTarget(isTextarea),
|
||||
padding: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('content', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
target: getTarget(isTextarea),
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('single true', () => {
|
||||
test('padding', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
target: getTarget(isTextarea),
|
||||
padding: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('content', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
target: getTarget(isTextarea),
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('multiple false', () => {
|
||||
test('padding & content', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
target: getTarget(isTextarea),
|
||||
padding: false,
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('multiple true', () => {
|
||||
test('padding & content', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
target: getTarget(isTextarea),
|
||||
padding: true,
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mixed', () => {
|
||||
test('false: padding & content | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: false,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: padding & content | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: true,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: content | false: padding | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: false,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: padding | false: content | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: true,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('false: padding | assigned: content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="content">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: false,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: padding | assigned: content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="content">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: true,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('false: padding | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: false,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: padding | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: true,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('false: padding | assigned: viewport & content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport"><div id="content">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
padding: false,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: padding | assigned: viewport & content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport"><div id="content">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
padding: true,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('false: content | assigned: padding', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: content | assigned: padding', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('false: content | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: content | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('false: content | assigned: padding & viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding"><div id="viewport">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: content | assigned: padding & viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding"><div id="viewport">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,870 +0,0 @@
|
||||
import { Environment, StructureInitializationStaticElement, StructureInitializationDynamicElement } from 'environment';
|
||||
import { OSTarget, StructureInitialization } from 'typings';
|
||||
import { createStructureSetup, StructureSetup } from 'setups/structureSetup';
|
||||
import { isHTMLElement } from 'support';
|
||||
|
||||
const mockGetEnvironment = jest.fn();
|
||||
jest.mock('environment', () => {
|
||||
return {
|
||||
getEnvironment: jest.fn().mockImplementation(() => mockGetEnvironment()),
|
||||
};
|
||||
});
|
||||
|
||||
interface StructureSetupProxy {
|
||||
input: OSTarget | StructureInitialization;
|
||||
setup: StructureSetup;
|
||||
}
|
||||
|
||||
const textareaId = 'textarea';
|
||||
const textareaHostId = 'host';
|
||||
const elementId = 'target';
|
||||
const dynamicContent = 'text<p>paragraph</p>';
|
||||
const textareaContent = `<textarea id="${textareaId}">text</textarea>`;
|
||||
const getSnapshot = () => document.body.innerHTML;
|
||||
const getTarget = (textarea?: boolean) => document.getElementById(textarea ? textareaId : elementId)!;
|
||||
const fillBody = (textarea?: boolean, customDOM?: (content: string, hostId: string) => string) => {
|
||||
document.body.innerHTML = `
|
||||
<nav></nav>
|
||||
${
|
||||
customDOM
|
||||
? customDOM(textarea ? textareaContent : dynamicContent, textarea ? textareaHostId : elementId)
|
||||
: textarea
|
||||
? textareaContent
|
||||
: `<div id="${elementId}">${dynamicContent}</div>`
|
||||
}
|
||||
<footer></footer>
|
||||
`;
|
||||
return getSnapshot();
|
||||
};
|
||||
const clearBody = () => {
|
||||
document.body.innerHTML = '';
|
||||
};
|
||||
|
||||
const getElements = (textarea?: boolean) => {
|
||||
const target = getTarget(textarea);
|
||||
const host = document.querySelector('.os-host')!;
|
||||
const padding = document.querySelector('.os-padding')!;
|
||||
const viewport = document.querySelector('.os-viewport')!;
|
||||
const content = document.querySelector('.os-content')!;
|
||||
|
||||
return {
|
||||
target,
|
||||
host,
|
||||
padding,
|
||||
viewport,
|
||||
content,
|
||||
};
|
||||
};
|
||||
|
||||
const assertCorrectDOMStructure = (textarea?: boolean) => {
|
||||
const { target, host, padding, viewport, content } = getElements(textarea);
|
||||
|
||||
expect(host).toBeTruthy();
|
||||
expect(viewport).toBeTruthy();
|
||||
expect(viewport.parentElement).toBe(padding || host);
|
||||
|
||||
if (content) {
|
||||
expect(content.parentElement).toBe(viewport);
|
||||
}
|
||||
if (padding) {
|
||||
expect(padding.parentElement).toBe(host);
|
||||
}
|
||||
|
||||
expect(host.parentElement).toBe(document.body);
|
||||
expect(host.previousElementSibling).toBe(document.querySelector('nav'));
|
||||
expect(host.nextElementSibling).toBe(document.querySelector('footer'));
|
||||
|
||||
const contentElm = content || viewport;
|
||||
if (textarea) {
|
||||
expect(target.parentElement).toBe(contentElm);
|
||||
expect(contentElm.innerHTML).toBe(textareaContent);
|
||||
} else {
|
||||
expect(target).toBe(host);
|
||||
expect(contentElm.innerHTML).toBe(dynamicContent);
|
||||
}
|
||||
};
|
||||
|
||||
const createStructureSetupProxy = (target: OSTarget | StructureInitialization): StructureSetupProxy => ({
|
||||
input: target,
|
||||
setup: createStructureSetup(target),
|
||||
});
|
||||
|
||||
const assertCorrectSetup = (textarea: boolean, setupProxy: StructureSetupProxy, environment: Environment): StructureSetup => {
|
||||
const { input, setup } = setupProxy;
|
||||
const { _targetObj, _targetCtx, _destroy } = setup;
|
||||
const { _target, _host, _padding, _viewport, _content } = _targetObj;
|
||||
const { target, host, padding, viewport, content } = getElements(textarea);
|
||||
const isTextarea = target.matches('textarea');
|
||||
const isBody = target.matches('body');
|
||||
|
||||
expect(textarea).toBe(isTextarea);
|
||||
|
||||
expect(_target).toBe(target);
|
||||
expect(_host).toBe(host);
|
||||
|
||||
if (padding || _padding) {
|
||||
expect(_padding).toBe(padding);
|
||||
} else {
|
||||
expect(padding).toBeFalsy();
|
||||
expect(_padding).toBeFalsy();
|
||||
}
|
||||
|
||||
if (viewport || _viewport) {
|
||||
expect(_viewport).toBe(viewport);
|
||||
} else {
|
||||
expect(viewport).toBeFalsy();
|
||||
expect(_viewport).toBeFalsy();
|
||||
}
|
||||
|
||||
if (content || _content) {
|
||||
expect(_content).toBe(content);
|
||||
} else {
|
||||
expect(content).toBeFalsy();
|
||||
expect(_content).toBeFalsy();
|
||||
}
|
||||
|
||||
const { _isTextarea, _isBody, _bodyElm, _htmlElm, _documentElm, _windowElm } = _targetCtx;
|
||||
|
||||
expect(_isTextarea).toBe(isTextarea);
|
||||
expect(_isBody).toBe(isBody);
|
||||
expect(_windowElm).toBe(document.defaultView);
|
||||
expect(_documentElm).toBe(document);
|
||||
expect(_htmlElm).toBe(document.body.parentElement);
|
||||
expect(_bodyElm).toBe(document.body);
|
||||
|
||||
expect(typeof _destroy).toBe('function');
|
||||
|
||||
const { _nativeScrollbarStyling, _cssCustomProperties, _getInitializationStrategy } = environment;
|
||||
const {
|
||||
_host: hostInitStrategy,
|
||||
_viewport: viewportInitStrategy,
|
||||
_padding: paddingInitStrategy,
|
||||
_content: contentInitStrategy,
|
||||
} = _getInitializationStrategy();
|
||||
const inputIsElement = isHTMLElement(input);
|
||||
const inputAsObj = input as StructureInitialization;
|
||||
const styleElm = document.querySelector('style');
|
||||
const checkStrategyDependendElements = (
|
||||
elm: Element | null,
|
||||
input: HTMLElement | boolean | undefined,
|
||||
isStaticStrategy: boolean,
|
||||
strategy: StructureInitializationStaticElement | StructureInitializationDynamicElement,
|
||||
id: string
|
||||
) => {
|
||||
if (input) {
|
||||
expect(elm).toBeTruthy();
|
||||
} else {
|
||||
if (input === false) {
|
||||
expect(elm).toBeFalsy();
|
||||
}
|
||||
if (input === undefined) {
|
||||
if (isStaticStrategy) {
|
||||
strategy = strategy as StructureInitializationStaticElement;
|
||||
if (typeof strategy === 'function') {
|
||||
const result = strategy(target);
|
||||
if (result) {
|
||||
expect(result).toBe(elm);
|
||||
} else {
|
||||
expect(elm).toBeTruthy();
|
||||
}
|
||||
} else {
|
||||
expect(elm).toBeTruthy();
|
||||
}
|
||||
} else {
|
||||
strategy = strategy as StructureInitializationDynamicElement;
|
||||
const expectDefaultValue = () => {
|
||||
if (id === 'padding') {
|
||||
if (_nativeScrollbarStyling) {
|
||||
expect(elm).toBeFalsy();
|
||||
} else {
|
||||
expect(elm).toBeTruthy();
|
||||
}
|
||||
} else if (id === 'content') {
|
||||
expect(elm).toBeFalsy();
|
||||
}
|
||||
};
|
||||
if (typeof strategy === 'function') {
|
||||
const result = strategy(target);
|
||||
const resultIsBoolean = typeof result === 'boolean';
|
||||
if (resultIsBoolean) {
|
||||
if (result) {
|
||||
expect(elm).toBeTruthy();
|
||||
} else {
|
||||
expect(elm).toBeFalsy();
|
||||
}
|
||||
} else if (result) {
|
||||
expect(elm).toBe(result);
|
||||
} else {
|
||||
expectDefaultValue();
|
||||
}
|
||||
} else {
|
||||
const strategyIsBoolean = typeof strategy === 'boolean';
|
||||
if (strategyIsBoolean) {
|
||||
if (strategy) {
|
||||
expect(elm).toBeTruthy();
|
||||
} else {
|
||||
expect(elm).toBeFalsy();
|
||||
}
|
||||
} else {
|
||||
expectDefaultValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (_nativeScrollbarStyling || _cssCustomProperties) {
|
||||
expect(styleElm).toBeFalsy();
|
||||
} else {
|
||||
expect(styleElm).toBeTruthy();
|
||||
}
|
||||
|
||||
if (inputIsElement) {
|
||||
checkStrategyDependendElements(padding, undefined, false, paddingInitStrategy, 'padding');
|
||||
checkStrategyDependendElements(content, undefined, false, contentInitStrategy, 'content');
|
||||
checkStrategyDependendElements(viewport, undefined, true, viewportInitStrategy, 'viewport');
|
||||
checkStrategyDependendElements(host, undefined, true, hostInitStrategy, 'host');
|
||||
} else {
|
||||
const { padding: inputPadding, content: inputContent, viewport: inputViewport, host: inputHost } = inputAsObj;
|
||||
checkStrategyDependendElements(padding, inputPadding, false, paddingInitStrategy, 'padding');
|
||||
checkStrategyDependendElements(content, inputContent, false, contentInitStrategy, 'content');
|
||||
checkStrategyDependendElements(viewport, inputViewport, true, viewportInitStrategy, 'viewport');
|
||||
checkStrategyDependendElements(host, inputHost, true, hostInitStrategy, 'host');
|
||||
}
|
||||
|
||||
return setup;
|
||||
};
|
||||
|
||||
const assertCorrectDestroy = (snapshot: string, setup: StructureSetup) => {
|
||||
const { _destroy } = setup;
|
||||
|
||||
_destroy();
|
||||
|
||||
// remove empty class attr
|
||||
const elms = document.querySelectorAll('*');
|
||||
Array.from(elms).forEach((elm) => {
|
||||
const classAttr = elm.getAttribute('class');
|
||||
if (classAttr === '') {
|
||||
elm.removeAttribute('class');
|
||||
}
|
||||
});
|
||||
|
||||
expect(snapshot).toBe(getSnapshot());
|
||||
};
|
||||
|
||||
const env: Environment = jest.requireActual('environment').getEnvironment();
|
||||
const envDefault = {
|
||||
name: 'default',
|
||||
env: env,
|
||||
};
|
||||
const envNativeScrollbarStyling = {
|
||||
name: 'native scrollbar styling',
|
||||
env: {
|
||||
...env,
|
||||
_nativeScrollbarStyling: true,
|
||||
},
|
||||
};
|
||||
const envCssCustomProperties = {
|
||||
name: 'custom css properties',
|
||||
env: {
|
||||
...env,
|
||||
_cssCustomProperties: true,
|
||||
},
|
||||
};
|
||||
const envInitStrategyMin = {
|
||||
name: 'initialization strategy min',
|
||||
env: {
|
||||
...env,
|
||||
_getInitializationStrategy: () => ({
|
||||
_host: null,
|
||||
_viewport: () => null,
|
||||
_content: () => false,
|
||||
_padding: false,
|
||||
_scrollbarsSlot: null,
|
||||
}),
|
||||
},
|
||||
};
|
||||
const envInitStrategyMax = {
|
||||
name: 'initialization strategy max',
|
||||
env: {
|
||||
...env,
|
||||
_getInitializationStrategy: () => ({
|
||||
_host: null,
|
||||
_viewport: null,
|
||||
_content: true,
|
||||
_padding: () => true,
|
||||
_scrollbarsSlot: null,
|
||||
}),
|
||||
},
|
||||
};
|
||||
const envInitStrategyAssigned = {
|
||||
name: 'initialization strategy assigned',
|
||||
env: {
|
||||
...env,
|
||||
_getInitializationStrategy: () => ({
|
||||
_host: () => document.querySelector('#host1') as HTMLElement,
|
||||
_viewport: (target: HTMLElement) => target.querySelector('#viewport') as HTMLElement,
|
||||
_content: (target: HTMLElement) => target.querySelector('#content') as HTMLElement,
|
||||
_padding: (target: HTMLElement) => target.querySelector('#padding') as HTMLElement,
|
||||
_scrollbarsSlot: null,
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
describe('structureSetup', () => {
|
||||
afterEach(() => clearBody());
|
||||
|
||||
[envDefault, envNativeScrollbarStyling, envCssCustomProperties, envInitStrategyMin, envInitStrategyMax, envInitStrategyAssigned].forEach(
|
||||
(envWithName) => {
|
||||
const { env: currEnv, name } = envWithName;
|
||||
describe(`Environment: ${name}`, () => {
|
||||
beforeAll(() => {
|
||||
mockGetEnvironment.mockImplementation(() => currEnv);
|
||||
});
|
||||
|
||||
[false, true].forEach((isTextarea) => {
|
||||
describe(isTextarea ? 'textarea' : 'element', () => {
|
||||
describe('basic', () => {
|
||||
test('Element', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(isTextarea, createStructureSetupProxy(getTarget(isTextarea)), currEnv);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('Object', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(isTextarea, createStructureSetupProxy({ target: getTarget(isTextarea) }), currEnv);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('complex', () => {
|
||||
describe('single assigned', () => {
|
||||
test('padding', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="content">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('multiple assigned', () => {
|
||||
test('padding viewport content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding"><div id="viewport"><div id="content">${content}</div></div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('padding viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding"><div id="viewport">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('padding content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding"><div id="content">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('viewport content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport"><div id="content">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('single false', () => {
|
||||
test('padding', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
target: getTarget(isTextarea),
|
||||
padding: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('content', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
target: getTarget(isTextarea),
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('single true', () => {
|
||||
test('padding', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
target: getTarget(isTextarea),
|
||||
padding: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('content', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
target: getTarget(isTextarea),
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('multiple false', () => {
|
||||
test('padding & content', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
target: getTarget(isTextarea),
|
||||
padding: false,
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('multiple true', () => {
|
||||
test('padding & content', () => {
|
||||
const snapshot = fillBody(isTextarea);
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
target: getTarget(isTextarea),
|
||||
padding: true,
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mixed', () => {
|
||||
test('false: padding & content | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: false,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: padding & content | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: true,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: content | false: padding | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: false,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: padding | false: content | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: true,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('false: padding | assigned: content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="content">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: false,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: padding | assigned: content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="content">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: true,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('false: padding | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: false,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: padding | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: true,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('false: padding | assigned: viewport & content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport"><div id="content">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
padding: false,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: padding | assigned: viewport & content', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport"><div id="content">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
padding: true,
|
||||
content: document.querySelector<HTMLElement>('#content')!,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('false: content | assigned: padding', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: content | assigned: padding', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('false: content | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: content | assigned: viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="viewport">${content}</div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('false: content | assigned: padding & viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding"><div id="viewport">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: false,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
|
||||
test('true: content | assigned: padding & viewport', () => {
|
||||
const snapshot = fillBody(isTextarea, (content, hostId) => {
|
||||
return `<div id="${hostId}"><div id="padding"><div id="viewport">${content}</div></div></div>`;
|
||||
});
|
||||
const setup = assertCorrectSetup(
|
||||
isTextarea,
|
||||
createStructureSetupProxy({
|
||||
host: document.querySelector<HTMLElement>('#host')!,
|
||||
target: getTarget(isTextarea),
|
||||
padding: document.querySelector<HTMLElement>('#padding')!,
|
||||
viewport: document.querySelector<HTMLElement>('#viewport')!,
|
||||
content: true,
|
||||
}),
|
||||
currEnv
|
||||
);
|
||||
assertCorrectDOMStructure(isTextarea);
|
||||
assertCorrectDestroy(snapshot, setup);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
+151
-38
@@ -7,7 +7,17 @@ import { setTestResult, waitForOrFailTest } from '@/testing-browser/TestResult';
|
||||
import { generateClassChangeSelectCallback, iterateSelect } from '@/testing-browser/Select';
|
||||
import { timeout } from '@/testing-browser/timeout';
|
||||
import { OverlayScrollbars } from 'overlayscrollbars';
|
||||
import { assignDeep, clientSize, from, getBoundingClientRect, style, parent, addClass, WH, removeAttr } from 'support';
|
||||
import {
|
||||
assignDeep,
|
||||
clientSize,
|
||||
from,
|
||||
getBoundingClientRect,
|
||||
style,
|
||||
parent,
|
||||
addClass,
|
||||
WH,
|
||||
removeAttr,
|
||||
} from 'support';
|
||||
|
||||
interface Metrics {
|
||||
offset: {
|
||||
@@ -74,8 +84,12 @@ const getMetrics = (elm: HTMLElement): Metrics => {
|
||||
|
||||
return {
|
||||
offset: {
|
||||
left: rounding(comparisonBCR.left - comparisonEnvBCR.left).toFixed(Math.min(fixedDigitsOffset, fixedDigits)),
|
||||
top: rounding(comparisonBCR.top - comparisonEnvBCR.top).toFixed(Math.min(fixedDigitsOffset, fixedDigits)),
|
||||
left: rounding(comparisonBCR.left - comparisonEnvBCR.left).toFixed(
|
||||
Math.min(fixedDigitsOffset, fixedDigits)
|
||||
),
|
||||
top: rounding(comparisonBCR.top - comparisonEnvBCR.top).toFixed(
|
||||
Math.min(fixedDigitsOffset, fixedDigits)
|
||||
),
|
||||
},
|
||||
size: {
|
||||
width: rounding(comparisonBCR.width).toFixed(fixedDigits),
|
||||
@@ -166,11 +180,11 @@ target!.querySelector('.os-viewport')?.addEventListener('scroll', (e) => {
|
||||
resize(target!).addResizeListener((width, height) => {
|
||||
style(comparison, { width, height });
|
||||
});
|
||||
//resize(comparison!).addResizeListener((width, height) => style(target, { width, height }));
|
||||
// resize(comparison!).addResizeListener((width, height) => style(target, { width, height }));
|
||||
resize(targetResize!).addResizeListener((width, height) => {
|
||||
style(comparisonResize, { width, height });
|
||||
});
|
||||
//resize(comparisonRes!).addResizeListener((width, height) => style(targetRes, { width, height }));
|
||||
// resize(comparisonRes!).addResizeListener((width, height) => style(targetRes, { width, height }));
|
||||
|
||||
const selectCallbackEnv = generateClassChangeSelectCallback(from(envElms));
|
||||
const envWidthSelect = document.querySelector<HTMLSelectElement>('#envWidth');
|
||||
@@ -230,58 +244,136 @@ const checkMetrics = async (checkComparison: CheckComparisonObj) => {
|
||||
|
||||
if (isFractionalPixelRatio()) {
|
||||
should.ok(
|
||||
plusMinusArr(targetMetrics.scroll.width, fractionalPixelRatioTollerance).indexOf(comparisonMetrics.scroll.width) > -1,
|
||||
plusMinusArr(targetMetrics.scroll.width, fractionalPixelRatioTollerance).indexOf(
|
||||
comparisonMetrics.scroll.width
|
||||
) > -1,
|
||||
`Scroll width equality. (+-${fractionalPixelRatioTollerance}) | Target: ${targetMetrics.scroll.width} | Comparison: ${comparisonMetrics.scroll.width}`
|
||||
);
|
||||
should.ok(
|
||||
plusMinusArr(targetMetrics.scroll.height, fractionalPixelRatioTollerance).indexOf(comparisonMetrics.scroll.height) > -1,
|
||||
plusMinusArr(targetMetrics.scroll.height, fractionalPixelRatioTollerance).indexOf(
|
||||
comparisonMetrics.scroll.height
|
||||
) > -1,
|
||||
`Scroll height equality. (+-${fractionalPixelRatioTollerance}) | Target: ${targetMetrics.scroll.height} | Comparison: ${comparisonMetrics.scroll.height}`
|
||||
);
|
||||
|
||||
should.ok(
|
||||
plusMinusArr(osInstance.state()._overflowAmount.w, fractionalPixelRatioTollerance).indexOf(comparisonMetrics.scroll.width) > -1,
|
||||
`Overflow amount width equality. (+-${fractionalPixelRatioTollerance}) | Amount: ${osInstance.state()._overflowAmount.w} | Comparison: ${
|
||||
plusMinusArr(osInstance.state()._overflowAmount.w, fractionalPixelRatioTollerance).indexOf(
|
||||
comparisonMetrics.scroll.width
|
||||
}`
|
||||
) > -1,
|
||||
`Overflow amount width equality. (+-${fractionalPixelRatioTollerance}) | Amount: ${
|
||||
osInstance.state()._overflowAmount.w
|
||||
} | Comparison: ${comparisonMetrics.scroll.width}`
|
||||
);
|
||||
should.ok(
|
||||
plusMinusArr(osInstance.state()._overflowAmount.h, fractionalPixelRatioTollerance).indexOf(comparisonMetrics.scroll.height) > -1,
|
||||
`Overflow amount height equality. (+-${fractionalPixelRatioTollerance}) | Amount: ${osInstance.state()._overflowAmount.h} | Comparison: ${
|
||||
plusMinusArr(osInstance.state()._overflowAmount.h, fractionalPixelRatioTollerance).indexOf(
|
||||
comparisonMetrics.scroll.height
|
||||
}`
|
||||
) > -1,
|
||||
`Overflow amount height equality. (+-${fractionalPixelRatioTollerance}) | Amount: ${
|
||||
osInstance.state()._overflowAmount.h
|
||||
} | Comparison: ${comparisonMetrics.scroll.height}`
|
||||
);
|
||||
} else {
|
||||
should.equal(targetMetrics.scroll.width, comparisonMetrics.scroll.width, 'Scroll width equality.');
|
||||
should.equal(targetMetrics.scroll.height, comparisonMetrics.scroll.height, 'Scroll height equality.');
|
||||
should.equal(
|
||||
targetMetrics.scroll.width,
|
||||
comparisonMetrics.scroll.width,
|
||||
'Scroll width equality.'
|
||||
);
|
||||
should.equal(
|
||||
targetMetrics.scroll.height,
|
||||
comparisonMetrics.scroll.height,
|
||||
'Scroll height equality.'
|
||||
);
|
||||
|
||||
should.equal(osInstance.state()._overflowAmount.w, comparisonMetrics.scroll.width, 'Overflow amount width equality.');
|
||||
should.equal(osInstance.state()._overflowAmount.h, comparisonMetrics.scroll.height, 'Overflow amount height equality.');
|
||||
should.equal(
|
||||
osInstance.state()._overflowAmount.w,
|
||||
comparisonMetrics.scroll.width,
|
||||
'Overflow amount width equality.'
|
||||
);
|
||||
should.equal(
|
||||
osInstance.state()._overflowAmount.h,
|
||||
comparisonMetrics.scroll.height,
|
||||
'Overflow amount height equality.'
|
||||
);
|
||||
|
||||
should.equal(targetMetrics.hasOverflow.x, comparisonMetrics.hasOverflow.x, 'Has overflow x equality.');
|
||||
should.equal(targetMetrics.hasOverflow.y, comparisonMetrics.hasOverflow.y, 'Has overflow y equality.');
|
||||
should.equal(
|
||||
targetMetrics.hasOverflow.x,
|
||||
comparisonMetrics.hasOverflow.x,
|
||||
'Has overflow x equality.'
|
||||
);
|
||||
should.equal(
|
||||
targetMetrics.hasOverflow.y,
|
||||
comparisonMetrics.hasOverflow.y,
|
||||
'Has overflow y equality.'
|
||||
);
|
||||
}
|
||||
|
||||
if (targetMetrics.hasOverflow.x) {
|
||||
should.equal(style(targetViewport!, 'overflowX'), 'scroll', 'Overflow-X should result in scroll.');
|
||||
should.ok(osInstance.state()._overflowAmount.w > 0, 'Overflow amount width should be > 0 with overflow.');
|
||||
should.equal(
|
||||
style(targetViewport!, 'overflowX'),
|
||||
'scroll',
|
||||
'Overflow-X should result in scroll.'
|
||||
);
|
||||
should.ok(
|
||||
osInstance.state()._overflowAmount.w > 0,
|
||||
'Overflow amount width should be > 0 with overflow.'
|
||||
);
|
||||
} else {
|
||||
should.notEqual(style(targetViewport!, 'overflowX'), 'scroll', 'No Overflow-X shouldnt result in scroll.');
|
||||
should.equal(osInstance.state()._overflowAmount.w, 0, 'Overflow amount width should be 0 without overflow.');
|
||||
should.notEqual(
|
||||
style(targetViewport!, 'overflowX'),
|
||||
'scroll',
|
||||
'No Overflow-X shouldnt result in scroll.'
|
||||
);
|
||||
should.equal(
|
||||
osInstance.state()._overflowAmount.w,
|
||||
0,
|
||||
'Overflow amount width should be 0 without overflow.'
|
||||
);
|
||||
}
|
||||
|
||||
if (targetMetrics.hasOverflow.y) {
|
||||
should.equal(style(targetViewport!, 'overflowY'), 'scroll', 'Overflow-Y should result in scroll.');
|
||||
should.ok(osInstance.state()._overflowAmount.h > 0, 'Overflow amount height should be > 0 with overflow.');
|
||||
should.equal(
|
||||
style(targetViewport!, 'overflowY'),
|
||||
'scroll',
|
||||
'Overflow-Y should result in scroll.'
|
||||
);
|
||||
should.ok(
|
||||
osInstance.state()._overflowAmount.h > 0,
|
||||
'Overflow amount height should be > 0 with overflow.'
|
||||
);
|
||||
} else {
|
||||
should.notEqual(style(targetViewport!, 'overflowY'), 'scroll', 'No Overflow-Y shouldnt result in scroll.');
|
||||
should.equal(osInstance.state()._overflowAmount.h, 0, 'Overflow amount height should be 0 without overflow.');
|
||||
should.notEqual(
|
||||
style(targetViewport!, 'overflowY'),
|
||||
'scroll',
|
||||
'No Overflow-Y shouldnt result in scroll.'
|
||||
);
|
||||
should.equal(
|
||||
osInstance.state()._overflowAmount.h,
|
||||
0,
|
||||
'Overflow amount height should be 0 without overflow.'
|
||||
);
|
||||
}
|
||||
|
||||
should.equal(targetMetrics.percentElm.width, comparisonMetrics.percentElm.width, 'Percent Elements width equality.');
|
||||
should.equal(targetMetrics.percentElm.height, comparisonMetrics.percentElm.height, 'Percent Elements height equality.');
|
||||
should.equal(
|
||||
targetMetrics.percentElm.width,
|
||||
comparisonMetrics.percentElm.width,
|
||||
'Percent Elements width equality.'
|
||||
);
|
||||
should.equal(
|
||||
targetMetrics.percentElm.height,
|
||||
comparisonMetrics.percentElm.height,
|
||||
'Percent Elements height equality.'
|
||||
);
|
||||
|
||||
should.equal(targetMetrics.endElm.width, comparisonMetrics.endElm.width, 'End Elements width equality.');
|
||||
should.equal(targetMetrics.endElm.height, comparisonMetrics.endElm.height, 'End Elements height equality.');
|
||||
should.equal(
|
||||
targetMetrics.endElm.width,
|
||||
comparisonMetrics.endElm.width,
|
||||
'End Elements width equality.'
|
||||
);
|
||||
should.equal(
|
||||
targetMetrics.endElm.height,
|
||||
comparisonMetrics.endElm.height,
|
||||
'End Elements height equality.'
|
||||
);
|
||||
|
||||
await timeout(1);
|
||||
|
||||
@@ -307,31 +399,36 @@ const iterate = async (select: HTMLSelectElement | null, afterEach?: () => any)
|
||||
afterEach,
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
const iterateEnvWidth = async (afterEach?: () => any) => {
|
||||
await iterate(envWidthSelect, afterEach);
|
||||
};
|
||||
const iterateEnvHeight = async (afterEach?: () => any) => {
|
||||
await iterate(envHeightSelect, afterEach);
|
||||
};
|
||||
*/
|
||||
const iterateHeight = async (afterEach?: () => any) => {
|
||||
await iterate(containerHeightSelect, afterEach);
|
||||
};
|
||||
const iterateWidth = async (afterEach?: () => any) => {
|
||||
await iterate(containerWidthSelect, afterEach);
|
||||
};
|
||||
/*
|
||||
const iterateFloat = async (afterEach?: () => any) => {
|
||||
await iterate(containerFloatSelect, afterEach);
|
||||
};
|
||||
*/
|
||||
const iteratePadding = async (afterEach?: () => any) => {
|
||||
await iterate(containerPaddingSelect, afterEach);
|
||||
};
|
||||
const iterateBorder = async (afterEach?: () => any) => {
|
||||
await iterate(containerBorderSelect, afterEach);
|
||||
};
|
||||
/*
|
||||
const iterateMargin = async (afterEach?: () => any) => {
|
||||
await iterate(containerMarginSelect, afterEach);
|
||||
};
|
||||
*/
|
||||
const iterateBoxSizing = async (afterEach?: () => any) => {
|
||||
await iterate(containerBoxSizingSelect, afterEach);
|
||||
};
|
||||
@@ -354,8 +451,10 @@ const overflowTest = async () => {
|
||||
const computedStyle = window.getComputedStyle(elm);
|
||||
const size = clientSize(elm);
|
||||
return {
|
||||
w: size.w - (parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight)),
|
||||
h: size.h - (parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom)),
|
||||
w:
|
||||
size.w - (parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight)),
|
||||
h:
|
||||
size.h - (parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -425,15 +524,29 @@ const overflowTest = async () => {
|
||||
|
||||
await waitForOrFailTest(() => {
|
||||
if (width) {
|
||||
should.ok(overflowAmountCheck.width >= addOverflow, 'Correct smallest possible overflow width. (?)');
|
||||
should.ok(
|
||||
overflowAmountCheck.width >= addOverflow,
|
||||
'Correct smallest possible overflow width. (?)'
|
||||
);
|
||||
} else {
|
||||
should.equal(overflowAmountCheck.width, 0, 'Correct smallest possible overflow width. (0)');
|
||||
should.equal(
|
||||
overflowAmountCheck.width,
|
||||
0,
|
||||
'Correct smallest possible overflow width. (0)'
|
||||
);
|
||||
}
|
||||
|
||||
if (height) {
|
||||
should.ok(overflowAmountCheck.height >= addOverflow, 'Correct smallest possible overflow height. (?)');
|
||||
should.ok(
|
||||
overflowAmountCheck.height >= addOverflow,
|
||||
'Correct smallest possible overflow height. (?)'
|
||||
);
|
||||
} else {
|
||||
should.equal(overflowAmountCheck.height, 0, 'Correct smallest possible overflow height. (0)');
|
||||
should.equal(
|
||||
overflowAmountCheck.height,
|
||||
0,
|
||||
'Correct smallest possible overflow height. (0)'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
// @ts-ignore
|
||||
import { playwrightRollup, expectSuccess } from '@/playwright/rollup';
|
||||
import { test, Page } from '@playwright/test';
|
||||
|
||||
playwrightRollup();
|
||||
|
||||
test.describe('StructureLifecycle', () => {
|
||||
[false, true].forEach(async (nativeScrollbarStyling) => {
|
||||
const withText = nativeScrollbarStyling ? 'with' : 'without';
|
||||
const nss = async (page: Page) => {
|
||||
if (!nativeScrollbarStyling) {
|
||||
await page.click('#nss');
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
};
|
||||
|
||||
test.describe(`structureLifecycles ${withText} native scrollbar styling`, () => {
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
test('default', async ({ page }) => {
|
||||
await nss(page);
|
||||
await page.click('#start');
|
||||
await expectSuccess(page);
|
||||
});
|
||||
|
||||
test('without flexbox glue & css custom props', async ({ page }) => {
|
||||
await nss(page);
|
||||
await page.click('#fbg');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#ccp');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#start');
|
||||
await expectSuccess(page);
|
||||
});
|
||||
|
||||
test('with partially overlaid scrollbars', async ({ page, browserName }) => {
|
||||
test.skip(
|
||||
browserName === 'firefox' || browserName === 'webkit',
|
||||
"firefox can't simulate partially overlaid scrollbars, boost speed by omitting webkit"
|
||||
);
|
||||
|
||||
await nss(page);
|
||||
await page.click('#po');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#start');
|
||||
await expectSuccess(page);
|
||||
});
|
||||
|
||||
test('with fully overlaid scrollbars', async ({ page }) => {
|
||||
await nss(page);
|
||||
await page.click('#fo');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#start');
|
||||
await expectSuccess(page);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
+144
-36
@@ -4,7 +4,19 @@ import should from 'should';
|
||||
import { generateSelectCallback, iterateSelect } from '@/testing-browser/Select';
|
||||
import { timeout } from '@/testing-browser/timeout';
|
||||
import { setTestResult, waitForOrFailTest } from '@/testing-browser/TestResult';
|
||||
import { appendChildren, createDiv, removeElements, children, isArray, isNumber, liesBetween, addClass, removeClass, diffClass, on } from 'support';
|
||||
import {
|
||||
appendChildren,
|
||||
createDiv,
|
||||
removeElements,
|
||||
children,
|
||||
isArray,
|
||||
isNumber,
|
||||
liesBetween,
|
||||
addClass,
|
||||
removeClass,
|
||||
diffClass,
|
||||
on,
|
||||
} from 'support';
|
||||
|
||||
import { createDOMObserver } from 'observers/domObserver';
|
||||
|
||||
@@ -27,8 +39,12 @@ const targetElm: HTMLElement | null = document.querySelector('#target');
|
||||
const trargetContentElm: HTMLElement | null = document.querySelector('#target .content');
|
||||
const targetElmContentElm: HTMLElement | null = document.querySelector('#content-host');
|
||||
const contentElmAttrChange: HTMLElement | null = document.querySelector('#target .content-nest');
|
||||
const contentBetweenElmAttrChange: HTMLElement | null = document.querySelector('#content-host .padding-nest-item');
|
||||
const contentHostElmAttrChange: HTMLElement | null = document.querySelector('#content-nest-item-host');
|
||||
const contentBetweenElmAttrChange: HTMLElement | null = document.querySelector(
|
||||
'#content-host .padding-nest-item'
|
||||
);
|
||||
const contentHostElmAttrChange: HTMLElement | null = document.querySelector(
|
||||
'#content-nest-item-host'
|
||||
);
|
||||
|
||||
const targetElmsSlot = document.querySelector('#target .host-nest-item');
|
||||
const targetContentElmsSlot = document.querySelector('#target .content .content-nest');
|
||||
@@ -36,20 +52,40 @@ const targetContentBetweenElmsSlot = document.querySelector('#content-host');
|
||||
const imgElmsSlot = document.querySelector('#target .content-nest');
|
||||
const transitionElmsSlot = document.querySelector('#content-host .content');
|
||||
|
||||
const addRemoveTargetElms: HTMLButtonElement | null = document.querySelector('#addRemoveTargetElms');
|
||||
const addRemoveTargetContentElms: HTMLButtonElement | null = document.querySelector('#addRemoveTargetContentElms');
|
||||
const addRemoveTargetContentBetweenElms: HTMLButtonElement | null = document.querySelector('#addRemoveTargetContentBetweenElms');
|
||||
const addRemoveTargetElms: HTMLButtonElement | null = document.querySelector(
|
||||
'#addRemoveTargetElms'
|
||||
);
|
||||
const addRemoveTargetContentElms: HTMLButtonElement | null = document.querySelector(
|
||||
'#addRemoveTargetContentElms'
|
||||
);
|
||||
const addRemoveTargetContentBetweenElms: HTMLButtonElement | null = document.querySelector(
|
||||
'#addRemoveTargetContentBetweenElms'
|
||||
);
|
||||
const addRemoveImgElms: HTMLButtonElement | null = document.querySelector('#addRemoveImgElms');
|
||||
const addRemoveTransitionElms: HTMLButtonElement | null = document.querySelector('#addRemoveTransitionElms');
|
||||
const addRemoveTransitionElms: HTMLButtonElement | null = document.querySelector(
|
||||
'#addRemoveTransitionElms'
|
||||
);
|
||||
const ignoreTargetChange: HTMLButtonElement | null = document.querySelector('#ignoreTargetChange');
|
||||
const setTargetAttr: HTMLSelectElement | null = document.querySelector('#setTargetAttr');
|
||||
const setFilteredTargetAttr: HTMLSelectElement | null = document.querySelector('#setFilteredTargetAttr');
|
||||
const setFilteredTargetAttr: HTMLSelectElement | null = document.querySelector(
|
||||
'#setFilteredTargetAttr'
|
||||
);
|
||||
const setContentAttr: HTMLSelectElement | null = document.querySelector('#setContentAttr');
|
||||
const setFilteredContentAttr: HTMLSelectElement | null = document.querySelector('#setFilteredContentAttr');
|
||||
const setContentBetweenAttr: HTMLSelectElement | null = document.querySelector('#setContentBetweenAttr');
|
||||
const setFilteredContentBetweenAttr: HTMLSelectElement | null = document.querySelector('#setFilteredContentBetweenAttr');
|
||||
const setContentHostElmAttr: HTMLSelectElement | null = document.querySelector('#setContentHostElmAttr');
|
||||
const setFilteredContentHostElmAttr: HTMLSelectElement | null = document.querySelector('#setFilteredContentHostElmAttr');
|
||||
const setFilteredContentAttr: HTMLSelectElement | null = document.querySelector(
|
||||
'#setFilteredContentAttr'
|
||||
);
|
||||
const setContentBetweenAttr: HTMLSelectElement | null = document.querySelector(
|
||||
'#setContentBetweenAttr'
|
||||
);
|
||||
const setFilteredContentBetweenAttr: HTMLSelectElement | null = document.querySelector(
|
||||
'#setFilteredContentBetweenAttr'
|
||||
);
|
||||
const setContentHostElmAttr: HTMLSelectElement | null = document.querySelector(
|
||||
'#setContentHostElmAttr'
|
||||
);
|
||||
const setFilteredContentHostElmAttr: HTMLSelectElement | null = document.querySelector(
|
||||
'#setFilteredContentHostElmAttr'
|
||||
);
|
||||
const summaryContent: HTMLElement | null = document.querySelector('#summary-content');
|
||||
const summaryBetween: HTMLElement | null = document.querySelector('#summary-between');
|
||||
|
||||
@@ -66,11 +102,21 @@ const targetDomObserver = createDOMObserver(
|
||||
document.querySelector('#target')!,
|
||||
false,
|
||||
(changedTargetAttrs: string[], styleChanged: boolean) => {
|
||||
should.ok(Array.isArray(changedTargetAttrs), 'The changedTargetAttrs parameter in a target dom observer must be a array.');
|
||||
should.equal(typeof styleChanged, 'boolean', 'The styleChanged parameter in a target dom observer must be a boolean.');
|
||||
should.ok(
|
||||
Array.isArray(changedTargetAttrs),
|
||||
'The changedTargetAttrs parameter in a target dom observer must be a array.'
|
||||
);
|
||||
should.equal(
|
||||
typeof styleChanged,
|
||||
'boolean',
|
||||
'The styleChanged parameter in a target dom observer must be a boolean.'
|
||||
);
|
||||
|
||||
if (styleChanged && changedTargetAttrs.length === 0) {
|
||||
should.ok(false, 'Style changing properties must always be inside the changedTargetAttrs array.');
|
||||
should.ok(
|
||||
false,
|
||||
'Style changing properties must always be inside the changedTargetAttrs array.'
|
||||
);
|
||||
}
|
||||
|
||||
domTargetObserverObservations.push({ changedTargetAttrs, styleChanged });
|
||||
@@ -106,14 +152,23 @@ const targetDomObserver = createDOMObserver(
|
||||
}
|
||||
);
|
||||
|
||||
const createContentDomOserver = (eventContentChange: Array<[string?, string?] | null | undefined>) => {
|
||||
const createContentDomOserver = (
|
||||
eventContentChange: Array<[string?, string?] | null | undefined>
|
||||
) => {
|
||||
return createDOMObserver(
|
||||
trargetContentElm!,
|
||||
true,
|
||||
(contentChangedTroughEvent: boolean) => {
|
||||
should.equal(typeof contentChangedTroughEvent, 'boolean', 'The contentChanged parameter in a content dom observer must be a boolean.');
|
||||
should.equal(
|
||||
typeof contentChangedTroughEvent,
|
||||
'boolean',
|
||||
'The contentChanged parameter in a content dom observer must be a boolean.'
|
||||
);
|
||||
|
||||
domContentObserverObservations.push({ contentChange: true, troughEvent: contentChangedTroughEvent });
|
||||
domContentObserverObservations.push({
|
||||
contentChange: true,
|
||||
troughEvent: contentChangedTroughEvent,
|
||||
});
|
||||
requestAnimationFrame(() => {
|
||||
if (contentChangesCountSlot) {
|
||||
contentChangesCountSlot.textContent = `${domContentObserverObservations.length}`;
|
||||
@@ -127,7 +182,11 @@ const createContentDomOserver = (eventContentChange: Array<[string?, string?] |
|
||||
_nestedTargetSelector: hostSelector,
|
||||
_ignoreContentChange: (mutation, isNestedTarget) => {
|
||||
const { target, attributeName } = mutation;
|
||||
return isNestedTarget ? false : attributeName ? liesBetween(target as Element, hostSelector, '.content') : false;
|
||||
return isNestedTarget
|
||||
? false
|
||||
: attributeName
|
||||
? liesBetween(target as Element, hostSelector, '.content')
|
||||
: false;
|
||||
},
|
||||
_ignoreNestedTargetChange: (target, attrName, oldValue, newValue) => {
|
||||
if (attrName === 'class' && oldValue && newValue) {
|
||||
@@ -149,8 +208,10 @@ const createContentDomOserver = (eventContentChange: Array<[string?, string?] |
|
||||
|
||||
let contentDomObserver = createContentDomOserver(contentChange);
|
||||
|
||||
const getTotalObservations = () => domTargetObserverObservations.length + domContentObserverObservations.length;
|
||||
const getLast = <T>(arr: T[], indexFromLast = 0): T => arr[arr.length - 1 - indexFromLast] || ({} as T);
|
||||
const getTotalObservations = () =>
|
||||
domTargetObserverObservations.length + domContentObserverObservations.length;
|
||||
const getLast = <T>(arr: T[], indexFromLast = 0): T =>
|
||||
arr[arr.length - 1 - indexFromLast] || ({} as T);
|
||||
const changedThrough = <ChangeThrough extends DOMContentObserverResult | DOMTargetObserverResult>(
|
||||
observationLists?: Array<ChangeThrough[]> | ChangeThrough[]
|
||||
) => {
|
||||
@@ -222,7 +283,9 @@ const attrChangeListener = (attrChangeTarget: HTMLElement | null) =>
|
||||
isClass && target.classList.add('something');
|
||||
!isClass && target.setAttribute(selectedValue, 'something');
|
||||
});
|
||||
const iterateAttrChange = async <ChangeThrough extends DOMContentObserverResult | DOMTargetObserverResult>(
|
||||
const iterateAttrChange = async <
|
||||
ChangeThrough extends DOMContentObserverResult | DOMTargetObserverResult
|
||||
>(
|
||||
select: HTMLSelectElement | null,
|
||||
changeThrough?: ChangeThrough[],
|
||||
checkChange?: (observation: ChangeThrough, selected: string) => any
|
||||
@@ -248,10 +311,17 @@ const iterateAttrChange = async <ChangeThrough extends DOMContentObserverResult
|
||||
},
|
||||
});
|
||||
};
|
||||
const addRemoveElementsTest = async (slot: Element | null, changeThrough?: DOMContentObserverResult[] | SeparateChangeThrough) => {
|
||||
const addRemoveElementsTest = async (
|
||||
slot: Element | null,
|
||||
changeThrough?: DOMContentObserverResult[] | SeparateChangeThrough
|
||||
) => {
|
||||
if (slot) {
|
||||
let addChangeThrough: DOMContentObserverResult[] | undefined = changeThrough as DOMContentObserverResult[] | undefined;
|
||||
let removeChangeThrough: DOMContentObserverResult[] | undefined = changeThrough as DOMContentObserverResult[] | undefined;
|
||||
let addChangeThrough: DOMContentObserverResult[] | undefined = changeThrough as
|
||||
| DOMContentObserverResult[]
|
||||
| undefined;
|
||||
let removeChangeThrough: DOMContentObserverResult[] | undefined = changeThrough as
|
||||
| DOMContentObserverResult[]
|
||||
| undefined;
|
||||
if (changeThrough && !isArray(changeThrough)) {
|
||||
addChangeThrough = (changeThrough as SeparateChangeThrough).added;
|
||||
removeChangeThrough = (changeThrough as SeparateChangeThrough).removed;
|
||||
@@ -272,7 +342,11 @@ const addRemoveElementsTest = async (slot: Element | null, changeThrough?: DOMCo
|
||||
if (addChangeThrough) {
|
||||
const contentChanged = getLast(addChangeThrough);
|
||||
await waitForOrFailTest(() => {
|
||||
should.deepEqual(contentChanged, { contentChange: true, troughEvent: false }, 'Adding an content element must result in a content change.');
|
||||
should.deepEqual(
|
||||
contentChanged,
|
||||
{ contentChange: true, troughEvent: false },
|
||||
'Adding an content element must result in a content change.'
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -311,7 +385,10 @@ const addRemoveElementsTest = async (slot: Element | null, changeThrough?: DOMCo
|
||||
await removeElm();
|
||||
}
|
||||
};
|
||||
const triggerSummaryElemet = async (summaryElm: HTMLElement | null, changeThrough?: DOMContentObserverResult[]) => {
|
||||
const triggerSummaryElemet = async (
|
||||
summaryElm: HTMLElement | null,
|
||||
changeThrough?: DOMContentObserverResult[]
|
||||
) => {
|
||||
// onyl do if summary is working (IE. exception)
|
||||
if (summaryElm && (summaryElm.nextElementSibling as HTMLElement)?.offsetHeight === 0) {
|
||||
const click = async () => {
|
||||
@@ -370,7 +447,11 @@ const addRemoveImgElmsFn = async () => {
|
||||
);
|
||||
|
||||
const lastContentChanged = getLast(domContentObserverObservations);
|
||||
should.deepEqual(lastContentChanged, { contentChange: true, troughEvent: true }, 'The images load event must result in a content change.');
|
||||
should.deepEqual(
|
||||
lastContentChanged,
|
||||
{ contentChange: true, troughEvent: true },
|
||||
'The images load event must result in a content change.'
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -424,7 +505,9 @@ const addRemoveImgElmsFn = async () => {
|
||||
await addMultiple();
|
||||
|
||||
// remove load event from image test
|
||||
const addChanged = async (newEventContentChange: Array<[string?, string?] | null | undefined>) => {
|
||||
const addChanged = async (
|
||||
newEventContentChange: Array<[string?, string?] | null | undefined>
|
||||
) => {
|
||||
contentDomObserver._destroy();
|
||||
contentDomObserver = createContentDomOserver(newEventContentChange);
|
||||
|
||||
@@ -449,7 +532,16 @@ const addRemoveImgElmsFn = async () => {
|
||||
contentDomObserver = createContentDomOserver(contentChange);
|
||||
};
|
||||
|
||||
await addChanged([['img', 'something'], ['img', 'something2'], ['img', ''], ['img', undefined], ['', ''], [undefined, undefined], null, undefined]);
|
||||
await addChanged([
|
||||
['img', 'something'],
|
||||
['img', 'something2'],
|
||||
['img', ''],
|
||||
['img', undefined],
|
||||
['', ''],
|
||||
[undefined, undefined],
|
||||
null,
|
||||
undefined,
|
||||
]);
|
||||
await addChanged([]);
|
||||
|
||||
removeElements(document.querySelectorAll('.img'));
|
||||
@@ -460,7 +552,11 @@ const addRemoveTransitionElmsFn = async () => {
|
||||
const startTransition = async (elm: Element, expectTransitionEndContentChange: boolean) => {
|
||||
await timeout(50); // time for css to apply class a bit later to trigger transition
|
||||
|
||||
const { before: beforeTransition, after: afterTransition, compare: compareTransition } = changedThrough(domContentObserverObservations);
|
||||
const {
|
||||
before: beforeTransition,
|
||||
after: afterTransition,
|
||||
compare: compareTransition,
|
||||
} = changedThrough(domContentObserverObservations);
|
||||
beforeTransition();
|
||||
removeClass(elm, 'resetTransition'); // IE...
|
||||
addClass(elm, 'active');
|
||||
@@ -523,7 +619,9 @@ const addRemoveTransitionElmsFn = async () => {
|
||||
await add(false);
|
||||
|
||||
contentDomObserver._destroy();
|
||||
contentDomObserver = createContentDomOserver(contentChange.concat([['.transition', 'transitionend']]));
|
||||
contentDomObserver = createContentDomOserver(
|
||||
contentChange.concat([['.transition', 'transitionend']])
|
||||
);
|
||||
|
||||
await add(true);
|
||||
};
|
||||
@@ -557,7 +655,11 @@ const iterateTargetAttrChange = async () => {
|
||||
true,
|
||||
'A attribute change on the target element for a DOMTargetObserver must be inside the changedTargetAttrs array.'
|
||||
);
|
||||
should.equal(styleChanged, true, 'A style changing attribute on the target element for a DOMTargetObserver must set styleChanged to true.');
|
||||
should.equal(
|
||||
styleChanged,
|
||||
true,
|
||||
'A style changing attribute on the target element for a DOMTargetObserver must set styleChanged to true.'
|
||||
);
|
||||
});
|
||||
await iterateAttrChange(setFilteredTargetAttr);
|
||||
};
|
||||
@@ -605,9 +707,15 @@ setFilteredTargetAttr?.addEventListener('change', attrChangeListener(targetElm))
|
||||
setContentAttr?.addEventListener('change', attrChangeListener(contentElmAttrChange));
|
||||
setFilteredContentAttr?.addEventListener('change', attrChangeListener(contentElmAttrChange));
|
||||
setContentBetweenAttr?.addEventListener('change', attrChangeListener(contentBetweenElmAttrChange));
|
||||
setFilteredContentBetweenAttr?.addEventListener('change', attrChangeListener(contentBetweenElmAttrChange));
|
||||
setFilteredContentBetweenAttr?.addEventListener(
|
||||
'change',
|
||||
attrChangeListener(contentBetweenElmAttrChange)
|
||||
);
|
||||
setContentHostElmAttr?.addEventListener('change', attrChangeListener(contentHostElmAttrChange));
|
||||
setFilteredContentHostElmAttr?.addEventListener('change', attrChangeListener(contentHostElmAttrChange));
|
||||
setFilteredContentHostElmAttr?.addEventListener(
|
||||
'change',
|
||||
attrChangeListener(contentHostElmAttrChange)
|
||||
);
|
||||
|
||||
const start = async () => {
|
||||
setTestResult(null);
|
||||
@@ -0,0 +1,12 @@
|
||||
// @ts-ignore
|
||||
import { playwrightRollup, expectSuccess } from '@/playwright/rollup';
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
playwrightRollup();
|
||||
|
||||
test.describe('DOMObserver', () => {
|
||||
test('test', async ({ page }) => {
|
||||
await page.click('#start');
|
||||
await expectSuccess(page);
|
||||
});
|
||||
});
|
||||
+50
-12
@@ -2,7 +2,11 @@ import 'styles/overlayscrollbars.scss';
|
||||
import './index.scss';
|
||||
import './handleEnvironment';
|
||||
import should from 'should';
|
||||
import { generateClassChangeSelectCallback, iterateSelect, selectOption } from '@/testing-browser/Select';
|
||||
import {
|
||||
generateClassChangeSelectCallback,
|
||||
iterateSelect,
|
||||
selectOption,
|
||||
} from '@/testing-browser/Select';
|
||||
import { setTestResult, waitForOrFailTest } from '@/testing-browser/TestResult';
|
||||
import { timeout } from '@/testing-browser/timeout';
|
||||
import { hasDimensions, offsetSize, WH, style } from 'support';
|
||||
@@ -15,8 +19,12 @@ const contentBox = (elm: HTMLElement | null): WH<number> => {
|
||||
if (elm) {
|
||||
const computedStyle = window.getComputedStyle(elm);
|
||||
return {
|
||||
w: elm.clientWidth - (parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight)),
|
||||
h: elm.clientHeight - (parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom)),
|
||||
w:
|
||||
elm.clientWidth -
|
||||
(parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight)),
|
||||
h:
|
||||
elm.clientHeight -
|
||||
(parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -37,7 +45,7 @@ const preInitChildren = targetElm?.children.length;
|
||||
|
||||
const sizeObserver = createSizeObserver(
|
||||
targetElm as HTMLElement,
|
||||
({ _directionIsRTLCache, _sizeChanged, _appear }) => {
|
||||
({ _directionIsRTLCache, _sizeChanged }) => {
|
||||
if (_sizeChanged) {
|
||||
sizeIterations += 1;
|
||||
}
|
||||
@@ -45,6 +53,7 @@ const sizeObserver = createSizeObserver(
|
||||
if (_directionIsRTLCache) {
|
||||
directionIterations += 1;
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
if (resizesSlot) {
|
||||
resizesSlot.textContent = (directionIterations + sizeIterations).toString();
|
||||
@@ -83,13 +92,22 @@ const iterate = async (select: HTMLSelectElement | null, afterEach?: () => any)
|
||||
currBoxSizing,
|
||||
};
|
||||
},
|
||||
async check({ currSizeIterations, currDirectionIterations, currOffsetSize, currContentSize, currDir, currBoxSizing }) {
|
||||
async check({
|
||||
currSizeIterations,
|
||||
currDirectionIterations,
|
||||
currOffsetSize,
|
||||
currContentSize,
|
||||
currDir,
|
||||
currBoxSizing,
|
||||
}) {
|
||||
const newOffsetSize = offsetSize(targetElm as HTMLElement);
|
||||
const newContentSize = contentBox(targetElm as HTMLElement);
|
||||
const newDir = style(targetElm as HTMLElement, 'direction');
|
||||
const newBoxSizing = style(targetElm as HTMLElement, 'box-sizing');
|
||||
const offsetSizeChanged = currOffsetSize.w !== newOffsetSize.w || currOffsetSize.h !== newOffsetSize.h;
|
||||
const contentSizeChanged = currContentSize.w !== newContentSize.w || currContentSize.h !== newContentSize.h;
|
||||
const offsetSizeChanged =
|
||||
currOffsetSize.w !== newOffsetSize.w || currOffsetSize.h !== newOffsetSize.h;
|
||||
const contentSizeChanged =
|
||||
currContentSize.w !== newContentSize.w || currContentSize.h !== newContentSize.h;
|
||||
const dirChanged = currDir !== newDir;
|
||||
const boxSizingChanged = currBoxSizing !== newBoxSizing;
|
||||
const dimensions = hasDimensions(targetElm as HTMLElement);
|
||||
@@ -113,20 +131,36 @@ const iterate = async (select: HTMLSelectElement | null, afterEach?: () => any)
|
||||
if (dirChanged) {
|
||||
await waitForOrFailTest(() => {
|
||||
const expectedCacheValue = newDir === 'rtl';
|
||||
should.equal(directionIterations, currDirectionIterations + 1, 'Direction change was detected correctly.');
|
||||
should.equal(sizeObserver._getCurrentCacheValues()._directionIsRTL._value, expectedCacheValue, 'Direction cache value is correct.');
|
||||
should.equal(
|
||||
directionIterations,
|
||||
currDirectionIterations + 1,
|
||||
'Direction change was detected correctly.'
|
||||
);
|
||||
should.equal(
|
||||
sizeObserver._getCurrentCacheValues()._directionIsRTL[0],
|
||||
expectedCacheValue,
|
||||
'Direction cache value is correct.'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (boxSizingChanged) {
|
||||
await waitForOrFailTest(() => {
|
||||
should.equal(sizeIterations, currSizeIterations + 1, 'BoxSizing change was detected correctly.');
|
||||
should.equal(
|
||||
sizeIterations,
|
||||
currSizeIterations + 1,
|
||||
'BoxSizing change was detected correctly.'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (dimensions && (offsetSizeChanged || contentSizeChanged)) {
|
||||
await waitForOrFailTest(() => {
|
||||
should.equal(sizeIterations, currSizeIterations + 1, 'Size change was detected correctly.');
|
||||
should.equal(
|
||||
sizeIterations,
|
||||
currSizeIterations + 1,
|
||||
'Size change was detected correctly.'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -229,7 +263,11 @@ const start = async () => {
|
||||
await cleanBoxSizingChange();
|
||||
|
||||
sizeObserver._destroy();
|
||||
should.equal(targetElm?.children.length, preInitChildren, 'Destruction removes all generated elements.');
|
||||
should.equal(
|
||||
targetElm?.children.length,
|
||||
preInitChildren,
|
||||
'Destruction removes all generated elements.'
|
||||
);
|
||||
setTestResult(true);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// @ts-ignore
|
||||
import { playwrightRollup, expectSuccess } from '@/playwright/rollup';
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
playwrightRollup();
|
||||
|
||||
test.describe('SizeObserver', () => {
|
||||
test('with ResizeOserver', async ({ page }) => {
|
||||
await page.click('#start');
|
||||
await expectSuccess(page);
|
||||
});
|
||||
|
||||
test('with ResizeOserver polyfill', async ({ page }) => {
|
||||
await page.click('#roPolyfill');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#start');
|
||||
await expectSuccess(page);
|
||||
});
|
||||
});
|
||||
+29
-8
@@ -2,7 +2,11 @@ import 'styles/overlayscrollbars.scss';
|
||||
import './index.scss';
|
||||
import './handleEnvironment';
|
||||
import should from 'should';
|
||||
import { generateClassChangeSelectCallback, iterateSelect, selectOption } from '@/testing-browser/Select';
|
||||
import {
|
||||
generateClassChangeSelectCallback,
|
||||
iterateSelect,
|
||||
selectOption,
|
||||
} from '@/testing-browser/Select';
|
||||
import { timeout } from '@/testing-browser/timeout';
|
||||
import { setTestResult, waitForOrFailTest } from '@/testing-browser/TestResult';
|
||||
import { offsetSize } from 'support';
|
||||
@@ -22,9 +26,10 @@ const changesSlot: HTMLButtonElement | null = document.querySelector('#changes')
|
||||
const preInitChildren = targetElm?.children.length;
|
||||
|
||||
const trinsicObserver = createTrinsicObserver(targetElm as HTMLElement, (heightIntrinsicCache) => {
|
||||
if (heightIntrinsicCache._changed) {
|
||||
const [currentHeightIntrinsic, currentHeightIntrinsicChanged] = heightIntrinsicCache;
|
||||
if (currentHeightIntrinsicChanged) {
|
||||
heightIterations += 1;
|
||||
heightIntrinsic = heightIntrinsicCache._value;
|
||||
heightIntrinsic = currentHeightIntrinsic;
|
||||
}
|
||||
requestAnimationFrame(() => {
|
||||
if (changesSlot) {
|
||||
@@ -65,10 +70,14 @@ const iterate = async (select: HTMLSelectElement | null, afterEach?: () => any)
|
||||
|
||||
await waitForOrFailTest(() => {
|
||||
if (trinsicHeightChanged) {
|
||||
should.equal(heightIterations, currHeightIterations + 1, 'Height intrinsic change has been detected correctly.');
|
||||
should.equal(
|
||||
heightIterations,
|
||||
currHeightIterations + 1,
|
||||
'Height intrinsic change has been detected correctly.'
|
||||
);
|
||||
}
|
||||
should.equal(
|
||||
trinsicObserver._getCurrentCacheValues()._heightIntrinsic._value,
|
||||
trinsicObserver._getCurrentCacheValues()._heightIntrinsic[0],
|
||||
newHeightIntrinsic,
|
||||
'Height intrinsic cache value is correct.'
|
||||
);
|
||||
@@ -97,7 +106,11 @@ const changeWhileHidden = async () => {
|
||||
selectOption(displaySelect as HTMLSelectElement, 'displayBlock');
|
||||
|
||||
await waitForOrFailTest(() => {
|
||||
should.equal(heightIntrinsic, false, 'Trinsic sizing changes while hidden from intrinsic to extrinsic.');
|
||||
should.equal(
|
||||
heightIntrinsic,
|
||||
false,
|
||||
'Trinsic sizing changes while hidden from intrinsic to extrinsic.'
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -111,7 +124,11 @@ const changeWhileHidden = async () => {
|
||||
selectOption(displaySelect as HTMLSelectElement, 'displayBlock');
|
||||
|
||||
await waitForOrFailTest(() => {
|
||||
should.equal(heightIntrinsic, true, 'Trinsic sizing changes while hidden from extrinsic to intrinsic.');
|
||||
should.equal(
|
||||
heightIntrinsic,
|
||||
true,
|
||||
'Trinsic sizing changes while hidden from extrinsic to intrinsic.'
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -133,7 +150,11 @@ const start = async () => {
|
||||
await changeWhileHidden();
|
||||
|
||||
trinsicObserver._destroy();
|
||||
should.equal(targetElm?.children.length, preInitChildren, 'After destruction all generated elements are removed.');
|
||||
should.equal(
|
||||
targetElm?.children.length,
|
||||
preInitChildren,
|
||||
'After destruction all generated elements are removed.'
|
||||
);
|
||||
setTestResult(true);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// @ts-ignore
|
||||
import { playwrightRollup, expectSuccess } from '@/playwright/rollup';
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
playwrightRollup();
|
||||
|
||||
test.describe('TrinsicObserver', () => {
|
||||
test('with IntersectionObserver', async ({ page }) => {
|
||||
await page.click('#start');
|
||||
await expectSuccess(page);
|
||||
});
|
||||
|
||||
test('with ResizeObserver', async ({ page }) => {
|
||||
await page.click('#ioPolyfill');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#start');
|
||||
await expectSuccess(page);
|
||||
});
|
||||
|
||||
test('with ResizeObserver polyfill', async ({ page }) => {
|
||||
await page.click('#ioPolyfill');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#roPolyfill');
|
||||
await page.waitForTimeout(500);
|
||||
await page.click('#start');
|
||||
await expectSuccess(page);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user