-
Notifications
You must be signed in to change notification settings - Fork 94
Expand file tree
/
Copy pathtest-runner.mjs
More file actions
110 lines (91 loc) · 3.48 KB
/
test-runner.mjs
File metadata and controls
110 lines (91 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { TEST_INVOKER_LOOKUP } from "./test-invoker.mjs";
export class TestRunner {
#frame;
#page;
#params;
#suite;
#test;
#callback;
#type;
constructor(frame, page, params, suite, test, callback, type = "default") {
this.#suite = suite;
this.#test = test;
this.#params = params;
this.#callback = callback;
this.#page = page;
this.#frame = frame;
this.#type = type;
console.assert(type in TEST_RUNNER_LOOKUP);
}
get page() {
return this.#page;
}
get test() {
return this.#test;
}
_runSyncStep(test, page) {
test.run(page);
}
async runTest() {
// Prepare all mark labels outside the measuring loop.
const suiteName = this.#suite.name;
const testName = this.#test.name;
const syncStartLabel = `${suiteName}.${testName}-start`;
const syncEndLabel = `${suiteName}.${testName}-sync-end`;
const asyncEndLabel = `${suiteName}.${testName}-async-end`;
let syncTime;
let asyncStartTime;
let asyncTime;
const runSync = async () => {
if (this.#params.warmupBeforeSync) {
performance.mark("warmup-start");
const startTime = performance.now();
// Infinite loop for the specified ms.
while (performance.now() - startTime < this.#params.warmupBeforeSync)
continue;
performance.mark("warmup-end");
}
performance.mark(syncStartLabel);
const syncStartTime = performance.now();
if (this.#type === "async")
await this._runSyncStep(this.test, this.page);
else
this._runSyncStep(this.test, this.page);
const mark = performance.mark(syncEndLabel);
const syncEndTime = mark.startTime;
syncTime = syncEndTime - syncStartTime;
asyncStartTime = syncEndTime;
};
const measureAsync = () => {
// Some browsers don't immediately update the layout for paint.
// Force the layout here to ensure we're measuring the layout time.
this.page?.layout();
const asyncEndTime = performance.now();
performance.mark(asyncEndLabel);
asyncTime = asyncEndTime - asyncStartTime;
if (this.#params.warmupBeforeSync)
performance.measure("warmup", "warmup-start", "warmup-end");
performance.measure(`${suiteName}.${testName}-sync`, syncStartLabel, syncEndLabel);
performance.measure(`${suiteName}.${testName}-async`, syncEndLabel, asyncEndLabel);
};
const report = () => this.#callback(this.#test, syncTime, asyncTime);
const invokerType = this.#suite.type === "async" || this.#params.useAsyncSteps ? "async" : this.#params.measurementMethod;
const invokerClass = TEST_INVOKER_LOOKUP[invokerType];
const invoker = new invokerClass(runSync, measureAsync, report, this.#params);
return invoker.start();
}
}
export class AsyncTestRunner extends TestRunner {
constructor(frame, page, params, suite, test, callback) {
super(frame, page, params, suite, test, callback, "async");
}
async _runSyncStep(test, page) {
await test.run(page);
}
}
export const TEST_RUNNER_LOOKUP = Object.freeze({
__proto__: null,
default: TestRunner,
async: AsyncTestRunner,
remote: TestRunner,
});