mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-19 06:10:35 +03:00
rename tests folder to test
This commit is contained in:
+223
@@ -0,0 +1,223 @@
|
||||
import '~/index.scss';
|
||||
import './index.scss';
|
||||
import should from 'should';
|
||||
import { timeout, setTestResult, waitForOrFailTest, resize } from '@~local/browser-testing';
|
||||
import { OverlayScrollbars } from '~/overlayscrollbars';
|
||||
import { addClass, each, isArray, removeAttr, style } from '~/support';
|
||||
import { addPlugin, ScrollbarsHidingPlugin, SizeObserverPlugin } from '~/plugins';
|
||||
|
||||
if (!window.ResizeObserver) {
|
||||
addPlugin(SizeObserverPlugin);
|
||||
}
|
||||
if (!OverlayScrollbars.env().scrollbarsHiding) {
|
||||
addPlugin(ScrollbarsHidingPlugin);
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
window.OverlayScrollbars = OverlayScrollbars;
|
||||
|
||||
OverlayScrollbars.env().setDefaultInitialization({
|
||||
cancel: { nativeScrollbarsOverlaid: false },
|
||||
});
|
||||
|
||||
const startBtn: HTMLButtonElement | null = document.querySelector('#start');
|
||||
const targetRoot: HTMLElement | null = document.querySelector('#targetRoot');
|
||||
const targetA: HTMLElement | null = document.querySelector('#targetA');
|
||||
const targetB: HTMLElement | null = document.querySelector('#targetB');
|
||||
const targetC: HTMLElement | null = document.querySelector('#targetC');
|
||||
const updatesRootSlot: HTMLElement | null = document.querySelector('#updatesRoot');
|
||||
const updatesASlot: HTMLElement | null = document.querySelector('#updatesA');
|
||||
const updatesBSlot: HTMLElement | null = document.querySelector('#updatesB');
|
||||
const updatesCSlot: HTMLElement | null = document.querySelector('#updatesC');
|
||||
const resizeRoot: HTMLElement | null = document.querySelector('#resizeRoot');
|
||||
const resizeA: HTMLElement | null = document.querySelector('#resizeA');
|
||||
const resizeB: HTMLElement | null = document.querySelector('#resizeB');
|
||||
const resizeC: HTMLElement | null = document.querySelector('#resizeC');
|
||||
const resizeBetweenRoot: HTMLElement | null = document.createElement('div');
|
||||
const resizeBetweenA: HTMLElement | null = document.createElement('div');
|
||||
const resizeBetweenB: HTMLElement | null = document.createElement('div');
|
||||
const resizeBetweenC: HTMLElement | null = document.createElement('div');
|
||||
|
||||
let rootUpdateCount = 0;
|
||||
let aUpdateCount = 0;
|
||||
let bUpdateCount = 0;
|
||||
let cUpdateCount = 0;
|
||||
|
||||
const rootInstance = OverlayScrollbars(
|
||||
{ target: targetRoot!, elements: { padding: true } },
|
||||
{},
|
||||
{
|
||||
initialized() {
|
||||
requestAnimationFrame(() => {
|
||||
addClass(rootInstance.elements().content, 'flex');
|
||||
addClass(resizeBetweenRoot, 'resize resizeBetween');
|
||||
targetRoot!.append(resizeBetweenRoot);
|
||||
});
|
||||
},
|
||||
updated() {
|
||||
rootUpdateCount++;
|
||||
requestAnimationFrame(() => {
|
||||
if (updatesRootSlot) {
|
||||
updatesRootSlot.textContent = `${rootUpdateCount}`;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
const aInstance = OverlayScrollbars(
|
||||
{ target: targetA!, elements: { content: true } },
|
||||
{},
|
||||
{
|
||||
initialized() {
|
||||
requestAnimationFrame(() => {
|
||||
addClass(aInstance.elements().content, 'flex');
|
||||
addClass(resizeBetweenA, 'resize resizeBetween');
|
||||
targetA!.append(resizeBetweenA);
|
||||
});
|
||||
},
|
||||
updated() {
|
||||
aUpdateCount++;
|
||||
requestAnimationFrame(() => {
|
||||
if (updatesASlot) {
|
||||
updatesASlot.textContent = `${aUpdateCount}`;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
const bInstance = OverlayScrollbars(
|
||||
targetB!,
|
||||
{},
|
||||
{
|
||||
initialized() {
|
||||
requestAnimationFrame(() => {
|
||||
addClass(bInstance.elements().content, 'flex');
|
||||
addClass(resizeBetweenB, 'resize resizeBetween');
|
||||
targetB!.append(resizeBetweenB);
|
||||
});
|
||||
},
|
||||
updated() {
|
||||
bUpdateCount++;
|
||||
requestAnimationFrame(() => {
|
||||
if (updatesBSlot) {
|
||||
updatesBSlot.textContent = `${bUpdateCount}`;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
OverlayScrollbars(
|
||||
{ target: targetC!, elements: { viewport: targetC! } },
|
||||
{},
|
||||
{
|
||||
initialized() {
|
||||
addClass(resizeBetweenC, 'resize resizeBetween');
|
||||
targetC!.append(resizeBetweenC);
|
||||
},
|
||||
updated() {
|
||||
cUpdateCount++;
|
||||
requestAnimationFrame(() => {
|
||||
if (updatesCSlot) {
|
||||
updatesCSlot.textContent = `${cUpdateCount}`;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
resize(resizeRoot!);
|
||||
resize(resizeA!);
|
||||
resize(resizeB!);
|
||||
resize(resizeC!);
|
||||
resize(resizeBetweenRoot!);
|
||||
resize(resizeBetweenA!);
|
||||
resize(resizeBetweenB!);
|
||||
resize(resizeBetweenC!);
|
||||
|
||||
const resizeBetween = async (betweenElm: HTMLElement) => {
|
||||
const styleObj = {
|
||||
width: parseInt(style(betweenElm, 'width'), 10) + 50,
|
||||
height: parseInt(style(betweenElm, 'height'), 10) + 50,
|
||||
};
|
||||
const updateCountsBefore = [rootUpdateCount, aUpdateCount, bUpdateCount, cUpdateCount];
|
||||
style(betweenElm, styleObj);
|
||||
|
||||
await timeout(250);
|
||||
const updateCountsAfter = [rootUpdateCount, aUpdateCount, bUpdateCount, cUpdateCount];
|
||||
|
||||
should.equal(
|
||||
JSON.stringify(updateCountsBefore),
|
||||
JSON.stringify(updateCountsAfter),
|
||||
`Resizing a between element shouldn't trigger any updates.`
|
||||
);
|
||||
removeAttr(betweenElm, 'style');
|
||||
};
|
||||
|
||||
const resizeResize = async (resizeElm: HTMLElement) => {
|
||||
const styleObj = {
|
||||
width: parseInt(style(resizeElm, 'width'), 10) - 10,
|
||||
height: parseInt(style(resizeElm, 'height'), 10) - 10,
|
||||
};
|
||||
const updateCountsBefore = [rootUpdateCount, aUpdateCount, bUpdateCount, cUpdateCount];
|
||||
style(resizeElm, styleObj);
|
||||
|
||||
await timeout(250);
|
||||
const updateCountsAfter = [rootUpdateCount, aUpdateCount, bUpdateCount, cUpdateCount];
|
||||
|
||||
should.equal(
|
||||
JSON.stringify(updateCountsBefore),
|
||||
JSON.stringify(updateCountsAfter),
|
||||
`Non size changing mutations shouldn't trigger any updates.`
|
||||
);
|
||||
removeAttr(resizeElm, 'style');
|
||||
};
|
||||
|
||||
const overwriteScrollHeight = (elm: HTMLElement | HTMLElement[]) => {
|
||||
const elements = isArray(elm) ? elm : [elm];
|
||||
|
||||
each(elements, (currElm) => {
|
||||
Object.defineProperty(currElm, 'scrollHeight', {
|
||||
configurable: true,
|
||||
get() {
|
||||
setTestResult(false);
|
||||
throw new Error('accessed scrollHeight');
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const testBetweenElements = async () => {
|
||||
overwriteScrollHeight([
|
||||
rootInstance.elements().viewport,
|
||||
aInstance.elements().viewport,
|
||||
bInstance.elements().viewport,
|
||||
]);
|
||||
await waitForOrFailTest(async () => {
|
||||
await resizeBetween(resizeBetweenRoot);
|
||||
await resizeBetween(resizeBetweenA);
|
||||
await resizeBetween(resizeBetweenB);
|
||||
});
|
||||
};
|
||||
|
||||
const testResizeElements = async () => {
|
||||
await waitForOrFailTest(
|
||||
async () => {
|
||||
await resizeResize(resizeRoot!);
|
||||
await resizeResize(resizeA!);
|
||||
await resizeResize(resizeB!);
|
||||
await resizeResize(resizeC!);
|
||||
},
|
||||
{ timeout: 5000 }
|
||||
);
|
||||
};
|
||||
|
||||
const start = async () => {
|
||||
setTestResult(null);
|
||||
|
||||
await testResizeElements();
|
||||
await testBetweenElements(); // has to be last
|
||||
|
||||
setTestResult(true);
|
||||
};
|
||||
|
||||
startBtn?.addEventListener('click', start);
|
||||
@@ -0,0 +1,19 @@
|
||||
<div id="controls">
|
||||
<button id="start">start</button>
|
||||
</div>
|
||||
<div id="stage">
|
||||
<div>
|
||||
<div id="targetRoot" class="container">
|
||||
<div id="targetA" class="container">
|
||||
<div id="targetB" class="container">
|
||||
<div id="targetC" class="container">
|
||||
<div id="resizeC" class="resize">UpdatesC: <span id="updatesC"></span></div>
|
||||
</div>
|
||||
<div id="resizeB" class="resize">UpdatesB: <span id="updatesB"></span></div>
|
||||
</div>
|
||||
<div id="resizeA" class="resize">UpdatesA: <span id="updatesA"></span></div>
|
||||
</div>
|
||||
<div id="resizeRoot" class="resize">UpdatesRoot: <span id="updatesRoot"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,77 @@
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: scroll;
|
||||
}
|
||||
#controls {
|
||||
flex: none;
|
||||
}
|
||||
#stage {
|
||||
flex: auto;
|
||||
position: relative;
|
||||
|
||||
& > div {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: lightgoldenrodyellow;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
border: 1px solid red;
|
||||
width: 75%;
|
||||
height: 60%;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.resize {
|
||||
overflow: hidden;
|
||||
background: lime;
|
||||
border: 1px solid green;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.resizer {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.resizeBetween {
|
||||
background: tomato;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.resizeBtn {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
background: blue;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
#targetRoot {
|
||||
height: 80%;
|
||||
}
|
||||
|
||||
#targetA {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#targetC {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
|
||||
& > .resize {
|
||||
width: 80px;
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import { playwrightRollup, expectSuccess } from '@~local/playwright-tooling';
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
playwrightRollup();
|
||||
|
||||
test.describe('StructureSetup.nesting', () => {
|
||||
test('nesting updates', async ({ page }) => {
|
||||
await expectSuccess(page);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user