Add development watch mode to puppeteer jest tests

This commit is contained in:
Rene
2021-01-08 21:50:14 +01:00
parent 67c412bc55
commit 6810865045
17 changed files with 613 additions and 52 deletions
+1
View File
@@ -7,6 +7,7 @@
"test": "jest --coverage --runInBand --detectOpenHandles",
"test:jsdom": "jest --coverage --runInBand --detectOpenHandles --selectProjects jsdom --testPathPattern",
"test:pptr": "jest --coverage --runInBand --detectOpenHandles --selectProjects puppeteer --testPathPattern",
"test:pptr-dev": "jest --coverage --runInBand --detectOpenHandles --selectProjects puppeteer-dev --testPathPattern",
"build": "rollup -c"
}
}
@@ -6,7 +6,7 @@ describe('Environment', () => {
await page.goto(url);
});
it('should be titled "Environment"', async () => {
test('page should be titled "Environment"', async () => {
// @ts-ignore
const a: Environment = await page.evaluate(() => window.environment.envInstance);
console.log(a);
@@ -6,7 +6,7 @@ describe('StructureLifecycle', () => {
await page.goto(url);
});
it('should be titled "Environment"', async () => {
test('page should be titled "Environment"', async () => {
// @ts-ignore
const a: Environment = await page.evaluate(() => window.structureLifecycle.envInstance);
console.log(a);
@@ -0,0 +1,185 @@
import 'overlayscrollbars.scss';
import './index.scss';
import should from 'should';
import { waitFor } from '@testing-library/dom';
import { generateSelectCallback, iterateSelect } from '@/testing-browser/Select';
import { setTestResult } from '@/testing-browser/TestResult';
import { hasDimensions, offsetSize, WH, style } from 'support';
import { createSizeObserver } from 'observers/sizeObserver';
let sizeIterations = 0;
let directionIterations = 0;
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)),
};
}
return { w: 0, h: 0 };
};
const targetElm = document.querySelector('#target');
const heightSelect: HTMLSelectElement | null = document.querySelector('#height');
const widthSelect: HTMLSelectElement | null = document.querySelector('#width');
const paddingSelect: HTMLSelectElement | null = document.querySelector('#padding');
const borderSelect: HTMLSelectElement | null = document.querySelector('#border');
const boxSizingSelect: HTMLSelectElement | null = document.querySelector('#boxSizing');
const displaySelect: HTMLSelectElement | null = document.querySelector('#display');
const directionSelect: HTMLSelectElement | null = document.querySelector('#direction');
const startBtn: HTMLButtonElement | null = document.querySelector('#start');
const resizesSlot: HTMLButtonElement | null = document.querySelector('#resizes');
const selectCallback = generateSelectCallback(targetElm as HTMLElement);
const iterate = async (select: HTMLSelectElement | null, afterEach?: () => any) => {
interface IterateSelect {
currSizeIterations: number;
currDirectionIterations: number;
currOffsetSize: WH<number>;
currContentSize: WH<number>;
currDir: string;
}
await iterateSelect<IterateSelect>(select, {
beforeEach() {
const currSizeIterations = sizeIterations;
const currDirectionIterations = directionIterations;
const currOffsetSize = offsetSize(targetElm as HTMLElement);
const currContentSize = contentBox(targetElm as HTMLElement);
const currDir = style(targetElm as HTMLElement, 'direction');
return {
currSizeIterations,
currDirectionIterations,
currOffsetSize,
currContentSize,
currDir,
};
},
async check({ currSizeIterations, currDirectionIterations, currOffsetSize, currContentSize, currDir }) {
const newOffsetSize = offsetSize(targetElm as HTMLElement);
const newContentSize = contentBox(targetElm as HTMLElement);
const newDir = style(targetElm as HTMLElement, 'direction');
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 dimensions = hasDimensions(targetElm as HTMLElement);
const observerElm = targetElm?.firstElementChild as HTMLElement;
// no overflow if not needed
if (targetElm && newContentSize.w > 0) {
should.ok(observerElm.getBoundingClientRect().right <= targetElm.getBoundingClientRect().right);
}
if (targetElm && newContentSize.h > 0) {
should.ok(observerElm.getBoundingClientRect().bottom <= targetElm.getBoundingClientRect().bottom);
}
if (dimensions && (offsetSizeChanged || contentSizeChanged || dirChanged)) {
await waitFor(
() => {
if (offsetSizeChanged || contentSizeChanged) {
should.equal(sizeIterations, currSizeIterations + 1);
}
if (dirChanged) {
should.equal(directionIterations, currDirectionIterations + 1);
}
},
{
onTimeout(error): Error {
setTestResult(false);
return error;
},
}
);
}
},
afterEach,
});
};
heightSelect?.addEventListener('change', selectCallback);
widthSelect?.addEventListener('change', selectCallback);
paddingSelect?.addEventListener('change', selectCallback);
borderSelect?.addEventListener('change', selectCallback);
boxSizingSelect?.addEventListener('change', selectCallback);
displaySelect?.addEventListener('change', selectCallback);
directionSelect?.addEventListener('change', selectCallback);
selectCallback(heightSelect);
selectCallback(widthSelect);
selectCallback(paddingSelect);
selectCallback(borderSelect);
selectCallback(boxSizingSelect);
selectCallback(displaySelect);
selectCallback(directionSelect);
const iteratePadding = async (afterEach?: () => any) => {
await iterate(paddingSelect, afterEach);
};
const iterateBorder = async (afterEach?: () => any) => {
await iterate(borderSelect, afterEach);
};
const iterateHeight = async (afterEach?: () => any) => {
await iterate(heightSelect, afterEach);
};
const iterateWidth = async (afterEach?: () => any) => {
await iterate(widthSelect, afterEach);
};
const iterateBoxSizing = async (afterEach?: () => any) => {
await iterate(boxSizingSelect, afterEach);
};
const iterateDisplay = async (afterEach?: () => any) => {
await iterate(displaySelect, afterEach);
};
const iterateDirection = async (afterEach?: () => any) => {
await iterate(directionSelect, afterEach);
};
const start = async () => {
setTestResult(null);
console.log('init direction changes:', directionIterations);
console.log('init size changes:', sizeIterations);
should.ok(directionIterations > 0);
should.ok(sizeIterations > 0);
targetElm?.removeAttribute('style');
await iterateDisplay();
await iterateDirection();
await iterateBoxSizing(async () => {
await iterateHeight(async () => {
await iterateWidth(async () => {
await iterateBorder(async () => {
await iterateDirection();
await iteratePadding();
});
});
});
});
setTestResult(true);
};
startBtn?.addEventListener('click', start);
createSizeObserver(
targetElm as HTMLElement,
(directionCache?: any) => {
if (directionCache) {
directionIterations += 1;
} else {
sizeIterations += 1;
}
requestAnimationFrame(() => {
if (resizesSlot) {
resizesSlot.textContent = (directionIterations + sizeIterations).toString();
}
});
},
{ _direction: true, _appear: true }
);
console.log('h1');
export { start };
@@ -0,0 +1,49 @@
<div id="controls">
<label for="height">height</label>
<select name="height" id="height">
<option value="heightAuto">auto</option>
<option value="heightHundred">100%</option>
<option value="height200">200px</option>
</select>
<label for="width">width</label>
<select name="width" id="width">
<option value="widthAuto">auto</option>
<option value="widthHundred">100%</option>
<option value="width200">200px</option>
</select>
<label for="padding">padding</label>
<select name="padding" id="padding">
<option value="padding0">0</option>
<option value="padding10">10px</option>
<option value="padding50">50px</option>
</select>
<label for="border">border</label>
<select name="border" id="border">
<option value="border2">2px</option>
<option value="border10">10px</option>
<option value="border0">0</option>
</select>
<label for="boxSizing">boxSizing</label>
<select name="boxSizing" id="boxSizing">
<option value="boxSizingBorderBox">border-box</option>
<option value="boxSizingContentBox">content-box</option>
</select>
<label for="display">display</label>
<select name="display" id="display">
<option value="displayBlock">block</option>
<option value="displayNone">none</option>
</select>
<label for="direction">direction</label>
<select name="direction" id="direction">
<option value="directionLTR">ltr</option>
<option value="directionRTL">rtl</option>
</select>
<button id="start">start</button>
<span>Detected resizes: <span id="resizes">0</span></span>
</div>
<div id="stage">
<div>
<div id="target"></div>
</div>
</div>
@@ -0,0 +1,99 @@
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;
}
#target {
overflow: hidden;
resize: both;
position: relative;
// prevent container from reaching 0x0 dimensions for testing purposes
min-width: 50px;
min-height: 50px;
}
.padding0 {
padding: 0;
}
.padding10 {
padding: 10px;
}
.padding50 {
padding: 50px;
}
.border2 {
border: 2px solid red;
}
.border10 {
border: 10px solid red;
}
.border0 {
border: none;
}
.heightAuto {
height: auto;
}
.height200 {
height: 200px;
}
.heightHundred {
height: 100%;
}
.widthAuto {
width: auto;
float: left;
}
.width200 {
width: 200px;
}
.widthHundred {
width: 100%;
}
.boxSizingBorderBox {
box-sizing: border-box;
}
.boxSizingContentBox {
box-sizing: content-box;
}
.displayNone {
display: none;
}
.displayBlock {
display: block;
}
.directionltr {
direction: ltr;
}
.directionRTL {
direction: rtl;
}
@@ -0,0 +1,13 @@
import expectPuppeteer from 'expect-puppeteer';
import url from './.build/build.html';
describe('DOMObserver', () => {
beforeAll(async () => {
await page.goto(url);
});
test('test', async () => {
await expectPuppeteer(page).toClick('#start');
await expectPuppeteer(page).toMatchElement('#testResult.passed');
});
});
@@ -1,15 +1,13 @@
import expectPuppeteer from 'expect-puppeteer';
import url from './.build/build.html';
describe('Environment', () => {
describe('SizeObserver', () => {
beforeAll(async () => {
await page.goto(url);
});
it('test', async () => {
test('test', async () => {
await expectPuppeteer(page).toClick('#start');
await expectPuppeteer(page).toMatchElement('#testResult.passed', {
timeout: 60000,
});
}, 60000);
await expectPuppeteer(page).toMatchElement('#testResult.passed');
});
});
@@ -1,15 +1,13 @@
import expectPuppeteer from 'expect-puppeteer';
import url from './.build/build.html';
describe('Environment', () => {
describe('TrinsicObserver', () => {
beforeAll(async () => {
await page.goto(url);
});
it('test', async () => {
test('test', async () => {
await expectPuppeteer(page).toClick('#start');
await expectPuppeteer(page).toMatchElement('#testResult.passed', {
timeout: 60000,
});
}, 60000);
await expectPuppeteer(page).toMatchElement('#testResult.passed');
});
});