improve tests

This commit is contained in:
Rene
2022-07-05 09:53:54 +02:00
parent fabc318107
commit 82151d6bc3
5 changed files with 168 additions and 107 deletions
@@ -397,6 +397,7 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
const [showNativeOverlaidScrollbarsOption, showNativeOverlaidScrollbarsChanged] = const [showNativeOverlaidScrollbarsOption, showNativeOverlaidScrollbarsChanged] =
checkOption<boolean>('nativeScrollbarsOverlaid.show'); checkOption<boolean>('nativeScrollbarsOverlaid.show');
const [overflow, overflowChanged] = checkOption<XY<OverflowBehavior>>('overflow'); const [overflow, overflowChanged] = checkOption<XY<OverflowBehavior>>('overflow');
const showNativeOverlaidScrollbars = const showNativeOverlaidScrollbars =
showNativeOverlaidScrollbarsOption && showNativeOverlaidScrollbarsOption &&
_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.x &&
@@ -427,10 +428,6 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
fixFlexboxGlue(preMeasureViewportOverflowState, _heightIntrinsic); fixFlexboxGlue(preMeasureViewportOverflowState, _heightIntrinsic);
} }
if (overflowVisible) {
removeClass(_viewport, classNameOverflowVisible);
}
if ( if (
_sizeChanged || _sizeChanged ||
_paddingStyleChanged || _paddingStyleChanged ||
@@ -438,6 +435,10 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
_directionChanged || _directionChanged ||
showNativeOverlaidScrollbarsChanged showNativeOverlaidScrollbarsChanged
) { ) {
if (overflowVisible) {
removeClass(_viewport, classNameOverflowVisible);
}
const [redoViewportArrange, undoViewportArrangeOverflowState] = undoViewportArrange( const [redoViewportArrange, undoViewportArrangeOverflowState] = undoViewportArrange(
showNativeOverlaidScrollbars, showNativeOverlaidScrollbars,
_directionIsRTL, _directionIsRTL,
@@ -18,6 +18,8 @@ import { resize } from '@/testing-browser/Resize';
import { setTestResult, waitForOrFailTest } from '@/testing-browser/TestResult'; import { setTestResult, waitForOrFailTest } from '@/testing-browser/TestResult';
import { generateClassChangeSelectCallback, iterateSelect } from '@/testing-browser/Select'; import { generateClassChangeSelectCallback, iterateSelect } from '@/testing-browser/Select';
import { timeout } from '@/testing-browser/timeout'; import { timeout } from '@/testing-browser/timeout';
import { OSOptions } from 'options';
import { PartialOptions } from 'typings';
interface Metrics { interface Metrics {
offset: { offset: {
@@ -53,6 +55,70 @@ interface CheckComparisonObj {
const isFractionalPixelRatio = () => window.devicePixelRatio % 1 !== 0; const isFractionalPixelRatio = () => window.devicePixelRatio % 1 !== 0;
const isVisibleOverflow = (val: string) => val.indexOf('visible') === 0;
const expectedOverflowVisibleBehavior = (
overflowOptionAxis: string,
hasOverflowOtherAxis: boolean
) => {
const overflowVisibleBehavior = overflowOptionAxis.replace('visible', '').slice(1);
return hasOverflowOtherAxis ? overflowVisibleBehavior || 'hidden' : 'visible';
};
// @ts-ignore
const msie11 = !!window.MSInputMethodContext && !!document.documentMode;
const msedge = window.navigator.userAgent.toLowerCase().indexOf('edge') > -1;
msie11 && addClass(document.body, 'msie11');
const useContentElement = false;
const fixedDigits = msie11 ? 1 : 3;
const fixedDigitsOffset = 3;
const startBtn: HTMLButtonElement | null = document.querySelector('#start');
const target: HTMLElement | null = document.querySelector('#target');
const targetMetrics: HTMLElement | null = document.querySelector('#targetMetrics');
const comparison: HTMLElement | null = document.querySelector('#comparison');
const comparisonMetrics: HTMLElement | null = document.querySelector('#comparisonMetrics');
const targetResize: HTMLElement | null = document.querySelector('#target .resize');
const comparisonResize: HTMLElement | null = document.querySelector('#comparison .resize');
const targetPercent: HTMLElement | null = document.querySelector('#target .percent');
const comparisonPercent: HTMLElement | null = document.querySelector('#comparison .percent');
const targetEnd: HTMLElement | null = document.querySelector('#target .end');
const comparisonEnd: HTMLElement | null = document.querySelector('#comparison .end');
const targetOptionsSlot: HTMLElement | null = document.querySelector('#options');
const targetUpdatesSlot: HTMLElement | null = document.querySelector('#updates');
const envElms = document.querySelectorAll<HTMLElement>('.env');
if (!useContentElement) {
envElms.forEach((elm) => {
addClass(elm, 'intrinsic-hack');
});
}
let updateCount = 0;
// @ts-ignore
const osInstance =
// @ts-ignore
(window.os = OverlayScrollbars(
{ target: target!, content: useContentElement },
{ nativeScrollbarsOverlaid: { initialize: true } },
{
updated() {
updateCount++;
requestAnimationFrame(() => {
if (targetUpdatesSlot) {
targetUpdatesSlot.textContent = `${updateCount}`;
}
if (targetOptionsSlot) {
targetOptionsSlot.textContent = JSON.stringify(osInstance.options().overflow, null, 2);
}
});
},
}
));
const getMetrics = (elm: HTMLElement): Metrics => { const getMetrics = (elm: HTMLElement): Metrics => {
// const rounding = isFractionalPixelRatio() ? Math.round : (num: number) => num; // const rounding = isFractionalPixelRatio() ? Math.round : (num: number) => num;
const elmIsTarget = elm === target; const elmIsTarget = elm === target;
@@ -128,66 +194,6 @@ const metricsDimensionsEqual = (a: Metrics, b: Metrics) => {
return JSON.stringify(aDimensions) === JSON.stringify(bDimensions); return JSON.stringify(aDimensions) === JSON.stringify(bDimensions);
}; };
const isVisibleOverflow = (val: string) => val.indexOf('visible') === 0;
const expectedOverflowVisibleBehavior = (
overflowOptionAxis: string,
hasOverflowOtherAxis: boolean
) => {
const overflowVisibleBehavior = overflowOptionAxis.replace('visible', '').slice(1);
return hasOverflowOtherAxis ? overflowVisibleBehavior || 'hidden' : 'visible';
};
// @ts-ignore
const msie11 = !!window.MSInputMethodContext && !!document.documentMode;
const msedge = window.navigator.userAgent.toLowerCase().indexOf('edge') > -1;
msie11 && addClass(document.body, 'msie11');
const useContentElement = false;
const fixedDigits = msie11 ? 1 : 3;
const fixedDigitsOffset = 3;
const startBtn: HTMLButtonElement | null = document.querySelector('#start');
const target: HTMLElement | null = document.querySelector('#target');
const targetMetrics: HTMLElement | null = document.querySelector('#targetMetrics');
const comparison: HTMLElement | null = document.querySelector('#comparison');
const comparisonMetrics: HTMLElement | null = document.querySelector('#comparisonMetrics');
const targetResize: HTMLElement | null = document.querySelector('#target .resize');
const comparisonResize: HTMLElement | null = document.querySelector('#comparison .resize');
const targetPercent: HTMLElement | null = document.querySelector('#target .percent');
const comparisonPercent: HTMLElement | null = document.querySelector('#comparison .percent');
const targetEnd: HTMLElement | null = document.querySelector('#target .end');
const comparisonEnd: HTMLElement | null = document.querySelector('#comparison .end');
const targetUpdatesSlot: HTMLElement | null = document.querySelector('#updates');
const envElms = document.querySelectorAll<HTMLElement>('.env');
if (!useContentElement) {
envElms.forEach((elm) => {
addClass(elm, 'intrinsic-hack');
});
}
let updateCount = 0;
// @ts-ignore
const osInstance =
// @ts-ignore
(window.os = OverlayScrollbars(
{ target: target!, content: useContentElement },
{ nativeScrollbarsOverlaid: { initialize: true } },
{
updated() {
updateCount++;
requestAnimationFrame(() => {
if (targetUpdatesSlot) {
targetUpdatesSlot.textContent = `${updateCount}`;
}
});
},
}
));
target!.querySelector('.os-viewport')?.addEventListener('scroll', (e) => { target!.querySelector('.os-viewport')?.addEventListener('scroll', (e) => {
const viewport: HTMLElement | null = e.currentTarget as HTMLElement; const viewport: HTMLElement | null = e.currentTarget as HTMLElement;
comparison!.scrollLeft = viewport.scrollLeft; comparison!.scrollLeft = viewport.scrollLeft;
@@ -445,8 +451,13 @@ const checkMetrics = async (checkComparison: CheckComparisonObj) => {
}); });
}; };
const iterate = async (select: HTMLSelectElement | null, afterEach?: () => any) => { const iterate = async (
select: HTMLSelectElement | null,
afterEach?: () => any,
skippedItems?: string[]
) => {
await iterateSelect<CheckComparisonObj>(select, { await iterateSelect<CheckComparisonObj>(select, {
filter: (item: string) => !skippedItems?.includes(item),
beforeEach() { beforeEach() {
const metrics = getMetrics(comparison!); const metrics = getMetrics(comparison!);
return { return {
@@ -468,22 +479,22 @@ const iterateEnvHeight = async (afterEach?: () => any) => {
await iterate(envHeightSelect, afterEach); await iterate(envHeightSelect, afterEach);
}; };
*/ */
const iterateHeight = async (afterEach?: () => any) => { const iterateHeight = async (afterEach?: () => any, skippedItems?: string[]) => {
await iterate(containerHeightSelect, afterEach); await iterate(containerHeightSelect, afterEach, skippedItems);
}; };
const iterateWidth = async (afterEach?: () => any) => { const iterateWidth = async (afterEach?: () => any, skippedItems?: string[]) => {
await iterate(containerWidthSelect, afterEach); await iterate(containerWidthSelect, afterEach, skippedItems);
}; };
/* /*
const iterateFloat = async (afterEach?: () => any) => { const iterateFloat = async (afterEach?: () => any) => {
await iterate(containerFloatSelect, afterEach); await iterate(containerFloatSelect, afterEach);
}; };
*/ */
const iteratePadding = async (afterEach?: () => any) => { const iteratePadding = async (afterEach?: () => any, skippedItems?: string[]) => {
await iterate(containerPaddingSelect, afterEach); await iterate(containerPaddingSelect, afterEach, skippedItems);
}; };
const iterateBorder = async (afterEach?: () => any) => { const iterateBorder = async (afterEach?: () => any, skippedItems?: string[]) => {
await iterate(containerBorderSelect, afterEach); await iterate(containerBorderSelect, afterEach, skippedItems);
}; };
/* /*
const iterateMargin = async (afterEach?: () => any) => { const iterateMargin = async (afterEach?: () => any) => {
@@ -500,7 +511,7 @@ const iterateMinMax = async (afterEach?: () => any) => {
await iterate(containerMinMaxSelect, afterEach); await iterate(containerMinMaxSelect, afterEach);
}; };
const overflowTest = async () => { const overflowTest = async (osOptions?: PartialOptions<OSOptions>) => {
const additiveOverflow = () => { const additiveOverflow = () => {
if (isFractionalPixelRatio()) { if (isFractionalPixelRatio()) {
return 1; return 1;
@@ -630,7 +641,7 @@ const overflowTest = async () => {
await checkMetrics(before); await checkMetrics(before);
}; };
const overflowTest = async () => { const iterateOverflow = async () => {
style(targetResize, { boxSizing: 'border-box' }); style(targetResize, { boxSizing: 'border-box' });
style(comparisonResize, { boxSizing: 'border-box' }); style(comparisonResize, { boxSizing: 'border-box' });
style(targetPercent, { display: 'none' }); style(targetPercent, { display: 'none' });
@@ -656,27 +667,45 @@ const overflowTest = async () => {
removeAttr(comparisonEnd, 'style'); removeAttr(comparisonEnd, 'style');
}; };
await iterateMinMax(async () => { if (osOptions) {
await iterateBoxSizing(async () => { osInstance.options(osOptions);
await iterateHeight(async () => {
await iterateWidth(async () => { await iterateMinMax(async () => {
await iterateBorder(async () => { await iterateBoxSizing(async () => {
// assume this part isn't critical await iterateHeight(async () => {
/* await iterateWidth(async () => {
await iterateBorder(async () => {
await iteratePadding(async () => {
await iterateOverflow();
}, ['paddingLarge']);
}, ['borderSmall']);
}, ['widthHundred']);
}, ['heightHundred']);
});
});
} else {
await iterateMinMax(async () => {
await iterateBoxSizing(async () => {
await iterateHeight(async () => {
await iterateWidth(async () => {
await iterateBorder(async () => {
// assume this part isn't critical
/*
await iterateFloat(async () => { await iterateFloat(async () => {
await iterateMargin(); await iterateMargin();
}); });
*/ */
await iteratePadding(async () => { await iteratePadding(async () => {
await overflowTest(); await iterateOverflow();
});
await iterateDirection();
}); });
await iterateDirection();
}); });
}); });
}); });
}); });
}); }
}; };
const start = async () => { const start = async () => {
@@ -685,6 +714,16 @@ const start = async () => {
target?.removeAttribute('style'); target?.removeAttribute('style');
await overflowTest(); await overflowTest();
await overflowTest({ overflow: { x: 'hidden', y: 'scroll' } });
await overflowTest({ overflow: { x: 'scroll', y: 'hidden' } });
await overflowTest({ overflow: { x: 'visible', y: 'scroll' } });
await overflowTest({ overflow: { x: 'scroll', y: 'visible' } });
await overflowTest({ overflow: { x: 'visible', y: 'visible' } });
await overflowTest({ overflow: { x: 'visible-scroll', y: 'visible-hidden' } });
await overflowTest({ overflow: { x: 'visible-hidden', y: 'hidden' } });
await overflowTest({ overflow: { x: 'visible', y: 'visible-scroll' } });
await overflowTest({ overflow: { x: 'scroll', y: 'visible-scroll' } });
setTestResult(true); setTestResult(true);
}; };
@@ -68,6 +68,7 @@
</select> </select>
<br /> <br />
<button id="start">start</button> <button id="start">start</button>
<span>UsedOptions: <span id="options">0</span></span>
<span>Detected updates: <span id="updates">0</span></span> <span>Detected updates: <span id="updates">0</span></span>
</div> </div>
<div id="stage"> <div id="stage">
@@ -1,6 +1,7 @@
body { body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: scroll;
} }
#controls { #controls {
flex: none; flex: none;
+40 -21
View File
@@ -7,25 +7,34 @@ const noop = <T>(): T => {
return {} as T; return {} as T;
}; };
const getSelectOptions = (selectElement: HTMLSelectElement) => Array.from(selectElement.options).map((option) => option.value); const getSelectOptions = (selectElement: HTMLSelectElement) =>
Array.from(selectElement.options).map((option) => option.value);
export const generateSelectCallback = ( export const generateSelectCallback =
targetElms: HTMLElement[] | HTMLElement | null, (
callback: (targetAffectedElm: HTMLElement, possibleValues: string[], selectedValue: string) => any targetElms: HTMLElement[] | HTMLElement | null,
) => (event: Event | HTMLSelectElement | null) => { callback: (
const target: HTMLSelectElement | null = isEvent(event) ? (event.target as HTMLSelectElement) : event; targetAffectedElm: HTMLElement,
if (target) { possibleValues: string[],
const selectedOption = target.value; selectedValue: string
const selectOptions = getSelectOptions(target); ) => any
const elmsArr = Array.isArray(targetElms) ? targetElms : [targetElms]; ) =>
(event: Event | HTMLSelectElement | null) => {
const target: HTMLSelectElement | null = isEvent(event)
? (event.target as HTMLSelectElement)
: event;
if (target) {
const selectedOption = target.value;
const selectOptions = getSelectOptions(target);
const elmsArr = Array.isArray(targetElms) ? targetElms : [targetElms];
elmsArr.forEach((elm) => { elmsArr.forEach((elm) => {
if (elm) { if (elm) {
callback(elm, selectOptions, selectedOption); callback(elm, selectOptions, selectedOption);
} }
}); });
} }
}; };
export const generateClassChangeSelectCallback = (targetElms: HTMLElement[] | HTMLElement | null) => export const generateClassChangeSelectCallback = (targetElms: HTMLElement[] | HTMLElement | null) =>
generateSelectCallback(targetElms, (targetAffectedElm, possibleValues, selectedValue) => { generateSelectCallback(targetElms, (targetAffectedElm, possibleValues, selectedValue) => {
@@ -33,7 +42,10 @@ export const generateClassChangeSelectCallback = (targetElms: HTMLElement[] | HT
targetAffectedElm.classList.add(selectedValue); targetAffectedElm.classList.add(selectedValue);
}); });
export const selectOption = (select: HTMLSelectElement | null, selectedOption: string | number): boolean => { export const selectOption = (
select: HTMLSelectElement | null,
selectedOption: string | number
): boolean => {
if (!select) { if (!select) {
return false; return false;
} }
@@ -47,7 +59,11 @@ export const selectOption = (select: HTMLSelectElement | null, selectedOption: s
if (typeof selectedOption === 'string' && options.includes(selectedOption)) { if (typeof selectedOption === 'string' && options.includes(selectedOption)) {
select.value = selectedOption; select.value = selectedOption;
} else if (typeof selectedOption === 'number' && options.length < selectedOption && selectedOption > -1) { } else if (
typeof selectedOption === 'number' &&
options.length < selectedOption &&
selectedOption > -1
) {
select.selectedIndex = selectedOption; select.selectedIndex = selectedOption;
} }
@@ -66,16 +82,19 @@ export const selectOption = (select: HTMLSelectElement | null, selectedOption: s
export const iterateSelect = async <T>( export const iterateSelect = async <T>(
select: HTMLSelectElement | null, select: HTMLSelectElement | null,
options?: { options?: {
filter?: (value: string, index: number, array: string[]) => boolean;
beforeEach?: () => T | Promise<T>; beforeEach?: () => T | Promise<T>;
check?: (input: T, selectedOptions: string) => void | Promise<void>; check?: (input: T, selectedOptions: string) => void | Promise<void>;
afterEach?: () => void | Promise<void>; afterEach?: () => void | Promise<void>;
} }
) => { ) => {
if (select) { if (select) {
const { beforeEach = noop, check = noop, afterEach = noop } = options || {}; const { beforeEach = noop, check = noop, afterEach = noop, filter } = options || {};
const selectOptions = getSelectOptions(select); const selectOptions = getSelectOptions(select);
const selectOptionsReversed = getSelectOptions(select).reverse(); const selectOptionsReversed = getSelectOptions(select).reverse();
const iterateOptions = [...selectOptions, ...selectOptionsReversed]; const iterateOptions = [...selectOptions, ...selectOptionsReversed].filter(
filter || (() => true)
);
for (let i = 0; i < iterateOptions.length; i++) { for (let i = 0; i < iterateOptions.length; i++) {
const option = iterateOptions[i]; const option = iterateOptions[i];
// eslint-disable-next-line // eslint-disable-next-line