TrinsicObserver with tests

This commit is contained in:
Rene
2020-11-22 20:12:30 +01:00
parent 5497f610de
commit cdc0aecd2f
9 changed files with 266 additions and 5 deletions
+2
View File
@@ -1,6 +1,7 @@
import { createDOM } from 'support/dom';
import { getEnvironment } from 'environment';
import { createSizeObserver } from 'overlayscrollbars/observers/SizeObserver';
import { createTrinsicObserver } from 'overlayscrollbars/observers/TrinsicObserver';
const abc = {
a: 1,
@@ -12,6 +13,7 @@ export default () => {
return [
getEnvironment(),
createSizeObserver(document.body, () => {}),
createTrinsicObserver(document.body, () => {}),
createDOM(
'\
<div class="os-host">\
@@ -1,4 +1,5 @@
@import './sizeobserver.scss';
@import './trinsicobserver.scss';
#os-environment {
position: fixed;
@@ -52,7 +52,7 @@ export const createSizeObserver = (
onSizeChangedCallback(dir === true);
};
const offListeners: (() => void)[] = [];
let appearCallback: (...args: any) => any = onSizeChangedCallbackProxy;
let appearCallback: ((...args: any) => any) | null = appear ? onSizeChangedCallbackProxy : null;
if (ResizeObserverConstructor) {
const resizeObserverInstance = new ResizeObserverConstructor(onSizeChangedCallbackProxy);
@@ -81,7 +81,9 @@ export const createSizeObserver = (
};
const onResized = function () {
rAFId = 0;
if (!isDirty) return;
if (!isDirty) {
return;
}
cacheSize = currSize;
onSizeChangedCallbackProxy();
@@ -114,7 +116,7 @@ export const createSizeObserver = (
height: scrollAmount,
});
reset();
appearCallback = onScroll;
appearCallback = appear ? onScroll : reset;
}
if (direction) {
@@ -140,7 +142,8 @@ export const createSizeObserver = (
);
}
if (appear) {
// appearCallback is always needed on scroll-observer strategy to reset it
if (appearCallback) {
addClass(sizeObserver, classNameSizeObserverAppear);
offListeners.push(on(sizeObserver, animationStartEventName, appearCallback));
}
@@ -36,6 +36,7 @@ export const createTrinsicObserver = (
createSizeObserver(trinsicObserver, () => {
const newSize = offsetSize(trinsicObserver);
const newHeightIntrinsic = newSize.h === 0;
if (newHeightIntrinsic !== heightIntrinsic) {
onTrinsicChangedCallback(false, newSize.h === 0);
heightIntrinsic = newHeightIntrinsic;
@@ -75,7 +75,7 @@ const iterate = async (select: HTMLSelectElement | null, afterEach?: () => any)
if (dimensions && (offsetSizeChanged || dirChanged)) {
await waitFor(
async () => {
() => {
if (offsetSizeChanged) {
should.equal(sizeIterations, currSizeIterations + 1);
}
@@ -0,0 +1,141 @@
import 'overlayscrollbars.scss';
import './index.scss';
import should from 'should';
import { waitFor } from '@testing-library/dom';
import { generateSelectCallback, iterateSelect, selectOption } from '@/testing-browser/Select';
import { timeout } from '@/testing-browser/timeout';
import { setTestResult } from '@/testing-browser/TestResult';
import { offsetSize } from 'support';
import { createTrinsicObserver } from 'overlayscrollbars/observers/TrinsicObserver';
const waitForOptions = {
onTimeout(error: Error): Error {
setTestResult(false);
return error;
},
};
let heightIterations = 0;
let heightIntrinsicCache: boolean;
const envElm = document.querySelector('#env');
const targetElm = document.querySelector('#target');
const checkElm = document.querySelector('#check');
const envHeightSelect: HTMLSelectElement | null = document.querySelector('#envHeight');
const targetHeightSelect: HTMLSelectElement | null = document.querySelector('#targetHeight');
const displaySelect: HTMLSelectElement | null = document.querySelector('#display');
const startBtn: HTMLButtonElement | null = document.querySelector('#start');
const changesSlot: HTMLButtonElement | null = document.querySelector('#changes');
const envElmSelectCallback = generateSelectCallback(envElm as HTMLElement);
const targetElmSelectCallback = generateSelectCallback(targetElm as HTMLElement);
envHeightSelect?.addEventListener('change', envElmSelectCallback);
targetHeightSelect?.addEventListener('change', targetElmSelectCallback);
displaySelect?.addEventListener('change', targetElmSelectCallback);
envElmSelectCallback(envHeightSelect);
targetElmSelectCallback(targetHeightSelect);
targetElmSelectCallback(displaySelect);
const iterate = async (select: HTMLSelectElement | null, afterEach?: () => any) => {
interface IterateSelect {
currHeightIterations: number;
currHeightIntrinsic: boolean;
}
await iterateSelect<IterateSelect>(select, {
beforeEach() {
const currHeightIterations = heightIterations;
const currHeightIntrinsic = offsetSize(checkElm as HTMLElement).h === 0;
return {
currHeightIterations,
currHeightIntrinsic,
};
},
async check({ currHeightIterations, currHeightIntrinsic }) {
const newHeightIntrinsic = offsetSize(checkElm as HTMLElement).h === 0;
const trinsicHeightChanged = newHeightIntrinsic !== currHeightIntrinsic;
await waitFor(() => {
if (trinsicHeightChanged) {
should.equal(heightIterations, currHeightIterations + 1);
}
}, waitForOptions);
},
afterEach,
});
};
const iterateEnvHeight = async (afterEach?: () => any) => {
await iterate(envHeightSelect, afterEach);
};
const iterateTargetHeight = async (afterEach?: () => any) => {
await iterate(targetHeightSelect, afterEach);
};
const changeWhileHidden = async () => {
selectOption(targetHeightSelect as HTMLSelectElement, 'targetHeightHundred');
const autoToHundred = async () => {
selectOption(envHeightSelect as HTMLSelectElement, 'envHeightAuto');
selectOption(displaySelect as HTMLSelectElement, 'displayNone');
await timeout(250);
selectOption(envHeightSelect as HTMLSelectElement, 'envHeightHundred');
selectOption(displaySelect as HTMLSelectElement, 'displayBlock');
await waitFor(() => {
should.equal(heightIntrinsicCache, false);
}, waitForOptions);
};
const hundredToAuto = async () => {
selectOption(envHeightSelect as HTMLSelectElement, 'envHeightHundred');
selectOption(displaySelect as HTMLSelectElement, 'displayNone');
await timeout(250);
selectOption(envHeightSelect as HTMLSelectElement, 'envHeightAuto');
selectOption(displaySelect as HTMLSelectElement, 'displayBlock');
await waitFor(() => {
should.equal(heightIntrinsicCache, true);
}, waitForOptions);
};
await autoToHundred();
await hundredToAuto();
await autoToHundred();
await hundredToAuto();
};
const start = async () => {
setTestResult(null);
targetElm?.removeAttribute('style');
await iterateEnvHeight();
await iterateTargetHeight();
await iterateEnvHeight(async () => {
await iterateTargetHeight();
});
await changeWhileHidden();
setTestResult(true);
};
startBtn?.addEventListener('click', start);
createTrinsicObserver(targetElm as HTMLElement, (widthIntrinsic: boolean, heightIntrinsic: boolean) => {
if (heightIntrinsic !== heightIntrinsicCache) {
heightIterations += 1;
heightIntrinsicCache = heightIntrinsic;
}
requestAnimationFrame(() => {
if (changesSlot) {
changesSlot.textContent = heightIterations.toString();
}
});
});
export { start };
@@ -0,0 +1,31 @@
<div id="controls">
<label for="display">display</label>
<select name="display" id="display">
<option value="displayBlock">block</option>
<option value="displayNone">none</option>
</select>
<label for="envHeight">envHeight</label>
<select name="envHeight" id="envHeight">
<option value="envHeightAuto">auto</option>
<option value="envHeightHundred">100%</option>
<option value="envHeight200">200px</option>
</select>
<label for="targetHeight">targetHeight</label>
<select name="targetHeight" id="targetHeight">
<option value="targetHeightAuto">auto</option>
<option value="targetHeightHundred">100%</option>
<option value="targetHeight200">200px</option>
</select>
<button id="start">start</button>
<span>Detected changes: <span id="changes">0</span></span>
</div>
<div id="stage">
<div>
<div id="env">
<div id="target">
<div id="check"></div>
</div>
</div>
</div>
</div>
@@ -0,0 +1,67 @@
body {
display: flex;
flex-direction: column;
}
#controls {
flex: none;
}
#stage {
flex: auto;
position: relative;
& > div {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: lightgoldenrodyellow;
}
}
#canvas > div {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
#env {
background: rgba(0, 0, 0, 0.3);
}
#target {
background: rgba(0, 0, 0, 0.3);
overflow: hidden;
position: relative;
// prevent container from reaching 0x0 dimensions for testing purposes
min-width: 50px;
min-height: 50px;
}
#check {
height: 100%;
}
.envHeightAuto,
.targetHeightAuto {
height: auto;
}
.envHeight200,
.targetHeight200 {
height: 200px;
}
.envHeightHundred,
.targetHeightHundred {
height: 100%;
}
.displayNone {
display: none;
}
.displayBlock {
display: block;
}
@@ -0,0 +1,15 @@
import expectPuppeteer from 'expect-puppeteer';
import url from './.build/build.html';
describe('Environment', () => {
beforeAll(async () => {
await page.goto(url);
});
it('test', async () => {
await expectPuppeteer(page).toClick('#start');
await expectPuppeteer(page).toMatchElement('#testResult.passed', {
timeout: 60000,
});
}, 60000);
});