@wdio/reporter 9.0.0-alpha.78 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.cjs +752 -0
- package/build/index.d.ts +1 -3
- package/build/index.d.ts.map +1 -1
- package/build/index.js +709 -257
- package/build/stats/runner.d.ts +1 -1
- package/build/stats/runner.d.ts.map +1 -1
- package/build/utils.d.ts +1 -2
- package/build/utils.d.ts.map +1 -1
- package/package.json +10 -14
- package/build/constants.js +0 -23
- package/build/stats/hook.js +0 -30
- package/build/stats/runnable.js +0 -29
- package/build/stats/runner.js +0 -31
- package/build/stats/suite.js +0 -37
- package/build/stats/test.js +0 -108
- package/build/supportsColor.js +0 -146
- package/build/types.js +0 -1
- package/build/utils.js +0 -93
- package/cjs/constants.js +0 -26
- package/cjs/index.js +0 -271
- package/cjs/package.json +0 -5
- package/cjs/stats/hook.js +0 -36
- package/cjs/stats/runnable.js +0 -32
- package/cjs/stats/runner.js +0 -37
- package/cjs/stats/suite.js +0 -43
- package/cjs/stats/test.js +0 -114
- package/cjs/supportsColor.js +0 -153
- package/cjs/types.js +0 -2
- package/cjs/utils.js +0 -105
- package/tsconfig.cjs.json +0 -10
- /package/{LICENSE-MIT → LICENSE} +0 -0
package/build/index.js
CHANGED
|
@@ -1,261 +1,713 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
isContentPresent = false;
|
|
27
|
-
specs = [];
|
|
28
|
-
currentSpec;
|
|
29
|
-
constructor(options) {
|
|
30
|
-
super();
|
|
31
|
-
this.options = options;
|
|
32
|
-
// ensure the report directory exists
|
|
33
|
-
if (this.options.outputDir) {
|
|
34
|
-
try {
|
|
35
|
-
fs.mkdirSync(this.options.outputDir, { recursive: true });
|
|
36
|
-
}
|
|
37
|
-
catch (err) {
|
|
38
|
-
throw new Error(`Couldn't create output directory at "${this.options.outputDir}": ${err.stack}`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
this.outputStream = (this.options.stdout || !this.options.logFile) && this.options.writeStream
|
|
42
|
-
? this.options.writeStream
|
|
43
|
-
: fs.createWriteStream(this.options.logFile);
|
|
44
|
-
let currentTest;
|
|
45
|
-
const rootSuite = new SuiteStats({
|
|
46
|
-
title: '(root)',
|
|
47
|
-
fullTitle: '(root)',
|
|
48
|
-
file: ''
|
|
49
|
-
});
|
|
50
|
-
this.currentSuites.push(rootSuite);
|
|
51
|
-
this.on('client:beforeCommand', this.onBeforeCommand.bind(this));
|
|
52
|
-
this.on('client:afterCommand', this.onAfterCommand.bind(this));
|
|
53
|
-
this.on('client:beforeAssertion', this.onBeforeAssertion.bind(this));
|
|
54
|
-
this.on('client:afterAssertion', this.onAfterAssertion.bind(this));
|
|
55
|
-
this.on('runner:start', /* istanbul ignore next */ (runner) => {
|
|
56
|
-
rootSuite.cid = runner.cid;
|
|
57
|
-
this.specs.push(...runner.specs);
|
|
58
|
-
this.runnerStat = new RunnerStats(runner);
|
|
59
|
-
this.onRunnerStart(this.runnerStat);
|
|
60
|
-
});
|
|
61
|
-
this.on('suite:start', /* istanbul ignore next */ (params) => {
|
|
62
|
-
/**
|
|
63
|
-
* the jasmine framework doesn't give us information about the file
|
|
64
|
-
* therefore we need to propagate these information into params
|
|
65
|
-
*/
|
|
66
|
-
if (!params.file) {
|
|
67
|
-
params.file = !params.parent
|
|
68
|
-
? this.specs.shift() || 'unknown spec file'
|
|
69
|
-
: this.currentSpec;
|
|
70
|
-
this.currentSpec = params.file;
|
|
71
|
-
}
|
|
72
|
-
const suite = new SuiteStats(params);
|
|
73
|
-
const currentSuite = this.currentSuites[this.currentSuites.length - 1];
|
|
74
|
-
currentSuite.suites.push(suite);
|
|
75
|
-
this.currentSuites.push(suite);
|
|
76
|
-
this.suites[suite.uid] = suite;
|
|
77
|
-
this.onSuiteStart(suite);
|
|
78
|
-
});
|
|
79
|
-
this.on('hook:start', /* istanbul ignore next */ (hook) => {
|
|
80
|
-
const hookStats = new HookStats(hook);
|
|
81
|
-
const currentSuite = this.currentSuites[this.currentSuites.length - 1];
|
|
82
|
-
currentSuite.hooks.push(hookStats);
|
|
83
|
-
currentSuite.hooksAndTests.push(hookStats);
|
|
84
|
-
this.hooks[hook.uid] = hookStats;
|
|
85
|
-
this.onHookStart(hookStats);
|
|
86
|
-
});
|
|
87
|
-
this.on('hook:end', /* istanbul ignore next */ (hook) => {
|
|
88
|
-
const hookStats = this.hooks[hook.uid];
|
|
89
|
-
hookStats.complete(getErrorsFromEvent(hook));
|
|
90
|
-
this.counts.hooks++;
|
|
91
|
-
this.onHookEnd(hookStats);
|
|
92
|
-
});
|
|
93
|
-
this.on('test:start', /* istanbul ignore next */ (test) => {
|
|
94
|
-
test.retries = this.retries;
|
|
95
|
-
currentTest = new TestStats(test);
|
|
96
|
-
const currentSuite = this.currentSuites[this.currentSuites.length - 1];
|
|
97
|
-
currentSuite.tests.push(currentTest);
|
|
98
|
-
currentSuite.hooksAndTests.push(currentTest);
|
|
99
|
-
this.tests[test.uid] = currentTest;
|
|
100
|
-
this.onTestStart(currentTest);
|
|
101
|
-
});
|
|
102
|
-
this.on('test:pass', /* istanbul ignore next */ (test) => {
|
|
103
|
-
const testStat = this.tests[test.uid];
|
|
104
|
-
testStat.pass();
|
|
105
|
-
this.counts.passes++;
|
|
106
|
-
this.counts.tests++;
|
|
107
|
-
this.onTestPass(testStat);
|
|
108
|
-
});
|
|
109
|
-
this.on('test:skip', (test) => {
|
|
110
|
-
const testStat = this.tests[test.uid];
|
|
111
|
-
currentTest.skip(test.pendingReason);
|
|
112
|
-
this.counts.skipping++;
|
|
113
|
-
this.counts.tests++;
|
|
114
|
-
this.onTestSkip(testStat);
|
|
115
|
-
});
|
|
116
|
-
this.on('test:fail', /* istanbul ignore next */ (test) => {
|
|
117
|
-
const testStat = this.tests[test.uid];
|
|
118
|
-
testStat.fail(getErrorsFromEvent(test));
|
|
119
|
-
this.counts.failures++;
|
|
120
|
-
this.counts.tests++;
|
|
121
|
-
this.onTestFail(testStat);
|
|
122
|
-
});
|
|
123
|
-
this.on('test:retry', (test) => {
|
|
124
|
-
const testStat = this.tests[test.uid];
|
|
125
|
-
testStat.fail(getErrorsFromEvent(test));
|
|
126
|
-
this.onTestRetry(testStat);
|
|
127
|
-
this.retries++;
|
|
128
|
-
});
|
|
129
|
-
this.on('test:pending', (test) => {
|
|
130
|
-
test.retries = this.retries;
|
|
131
|
-
const currentSuite = this.currentSuites[this.currentSuites.length - 1];
|
|
132
|
-
currentTest = new TestStats(test);
|
|
133
|
-
/**
|
|
134
|
-
* In Mocha: tests that are skipped don't have a start event but a test end.
|
|
135
|
-
* In Jasmine: tests have a start event, therefore we need to replace the
|
|
136
|
-
* test instance with the pending test here
|
|
137
|
-
*/
|
|
138
|
-
if (test.uid in this.tests && this.tests[test.uid].state !== 'pending') {
|
|
139
|
-
currentTest.uid = test.uid in this.tests ? 'skipped-' + this.counts.skipping : currentTest.uid;
|
|
140
|
-
}
|
|
141
|
-
const suiteTests = currentSuite.tests;
|
|
142
|
-
if (!suiteTests.length || currentTest.uid !== suiteTests[suiteTests.length - 1].uid) {
|
|
143
|
-
currentSuite.tests.push(currentTest);
|
|
144
|
-
currentSuite.hooksAndTests.push(currentTest);
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
suiteTests[suiteTests.length - 1] = currentTest;
|
|
148
|
-
currentSuite.hooksAndTests[currentSuite.hooksAndTests.length - 1] = currentTest;
|
|
149
|
-
}
|
|
150
|
-
this.tests[currentTest.uid] = currentTest;
|
|
151
|
-
currentTest.skip(test.pendingReason);
|
|
152
|
-
this.counts.skipping++;
|
|
153
|
-
this.counts.tests++;
|
|
154
|
-
this.onTestSkip(currentTest);
|
|
155
|
-
});
|
|
156
|
-
this.on('test:end', /* istanbul ignore next */ (test) => {
|
|
157
|
-
const testStat = this.tests[test.uid];
|
|
158
|
-
this.retries = 0;
|
|
159
|
-
this.onTestEnd(testStat);
|
|
160
|
-
});
|
|
161
|
-
this.on('suite:end', /* istanbul ignore next */ (suite) => {
|
|
162
|
-
const suiteStat = this.suites[suite.uid];
|
|
163
|
-
suiteStat.complete();
|
|
164
|
-
this.currentSuites.pop();
|
|
165
|
-
this.onSuiteEnd(suiteStat);
|
|
166
|
-
});
|
|
167
|
-
this.on('runner:end', /* istanbul ignore next */ (runner) => {
|
|
168
|
-
rootSuite.complete();
|
|
169
|
-
if (this.runnerStat) {
|
|
170
|
-
this.runnerStat.failures = runner.failures;
|
|
171
|
-
this.runnerStat.retries = runner.retries;
|
|
172
|
-
this.runnerStat.complete();
|
|
173
|
-
this.onRunnerEnd(this.runnerStat);
|
|
174
|
-
}
|
|
175
|
-
const logFile = this.options.logFile;
|
|
176
|
-
if (!this.isContentPresent && logFile && fs.existsSync(logFile)) {
|
|
177
|
-
fs.unlinkSync(logFile);
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
/**
|
|
181
|
-
* browser client event handlers
|
|
182
|
-
*/
|
|
183
|
-
this.on('client:beforeCommand', /* istanbul ignore next */ (payload) => {
|
|
184
|
-
if (!currentTest) {
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
currentTest.output.push(Object.assign(payload, { type: 'command' }));
|
|
188
|
-
});
|
|
189
|
-
this.on('client:afterCommand', /* istanbul ignore next */ (payload) => {
|
|
190
|
-
if (!currentTest) {
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
currentTest.output.push(Object.assign(payload, { type: 'result' }));
|
|
194
|
-
});
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import { EventEmitter } from "node:events";
|
|
4
|
+
|
|
5
|
+
// src/supportsColor.ts
|
|
6
|
+
import process from "node:process";
|
|
7
|
+
import os from "node:os";
|
|
8
|
+
import tty from "node:tty";
|
|
9
|
+
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {
|
|
10
|
+
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
11
|
+
const position = argv.indexOf(prefix + flag);
|
|
12
|
+
const terminatorPosition = argv.indexOf("--");
|
|
13
|
+
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
14
|
+
}
|
|
15
|
+
var { env } = process;
|
|
16
|
+
var flagForceColor;
|
|
17
|
+
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
|
|
18
|
+
flagForceColor = 0;
|
|
19
|
+
} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
|
|
20
|
+
flagForceColor = 1;
|
|
21
|
+
}
|
|
22
|
+
function envForceColor() {
|
|
23
|
+
if ("FORCE_COLOR" in env) {
|
|
24
|
+
if (env.FORCE_COLOR === "true") {
|
|
25
|
+
return 1;
|
|
195
26
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
* is done (e.g. when having to send data to some server or any other async work)
|
|
199
|
-
*/
|
|
200
|
-
get isSynchronised() {
|
|
201
|
-
return true;
|
|
27
|
+
if (env.FORCE_COLOR === "false") {
|
|
28
|
+
return 0;
|
|
202
29
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
30
|
+
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function translateLevel(level) {
|
|
34
|
+
if (level === 0) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
level,
|
|
39
|
+
hasBasic: true,
|
|
40
|
+
has256: level >= 2,
|
|
41
|
+
has16m: level >= 3
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
45
|
+
const noFlagForceColor = envForceColor();
|
|
46
|
+
if (noFlagForceColor !== void 0) {
|
|
47
|
+
flagForceColor = noFlagForceColor;
|
|
48
|
+
}
|
|
49
|
+
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
50
|
+
if (forceColor === 0) {
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
if (sniffFlags) {
|
|
54
|
+
if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
|
|
55
|
+
return 3;
|
|
56
|
+
}
|
|
57
|
+
if (hasFlag("color=256")) {
|
|
58
|
+
return 2;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if ("TF_BUILD" in env && "AGENT_NAME" in env) {
|
|
62
|
+
return 1;
|
|
63
|
+
}
|
|
64
|
+
if (haveStream && !streamIsTTY && forceColor === void 0) {
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
const min = forceColor || 0;
|
|
68
|
+
if (env.TERM === "dumb") {
|
|
69
|
+
return min;
|
|
70
|
+
}
|
|
71
|
+
if (process.platform === "win32") {
|
|
72
|
+
const osRelease = os.release().split(".");
|
|
73
|
+
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
74
|
+
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
211
75
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
76
|
+
return 1;
|
|
77
|
+
}
|
|
78
|
+
if ("CI" in env) {
|
|
79
|
+
if ("GITHUB_ACTIONS" in env || "GITEA_ACTIONS" in env) {
|
|
80
|
+
return 3;
|
|
81
|
+
}
|
|
82
|
+
if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
|
|
83
|
+
return 1;
|
|
84
|
+
}
|
|
85
|
+
return min;
|
|
86
|
+
}
|
|
87
|
+
if ("TEAMCITY_VERSION" in env) {
|
|
88
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
89
|
+
}
|
|
90
|
+
if (env.COLORTERM === "truecolor") {
|
|
91
|
+
return 3;
|
|
92
|
+
}
|
|
93
|
+
if (env.TERM === "xterm-kitty") {
|
|
94
|
+
return 3;
|
|
95
|
+
}
|
|
96
|
+
if ("TERM_PROGRAM" in env) {
|
|
97
|
+
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
|
|
98
|
+
switch (env.TERM_PROGRAM) {
|
|
99
|
+
case "iTerm.app": {
|
|
100
|
+
return version >= 3 ? 3 : 2;
|
|
101
|
+
}
|
|
102
|
+
case "Apple_Terminal": {
|
|
103
|
+
return 2;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (env.TERM && /-256(color)?$/i.test(env.TERM)) {
|
|
108
|
+
return 2;
|
|
109
|
+
}
|
|
110
|
+
if (env.TERM && /^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
111
|
+
return 1;
|
|
112
|
+
}
|
|
113
|
+
if ("COLORTERM" in env) {
|
|
114
|
+
return 1;
|
|
115
|
+
}
|
|
116
|
+
return min;
|
|
117
|
+
}
|
|
118
|
+
function createSupportsColor(stream, options = {}) {
|
|
119
|
+
const level = _supportsColor(stream, {
|
|
120
|
+
streamIsTTY: stream && stream.isTTY,
|
|
121
|
+
...options
|
|
122
|
+
});
|
|
123
|
+
return translateLevel(level);
|
|
124
|
+
}
|
|
125
|
+
var supportsColor = {
|
|
126
|
+
stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
|
|
127
|
+
stderr: createSupportsColor({ isTTY: tty.isatty(2) })
|
|
128
|
+
};
|
|
129
|
+
var supportsColor_default = supportsColor;
|
|
130
|
+
|
|
131
|
+
// src/constants.ts
|
|
132
|
+
var COLORS = {
|
|
133
|
+
pass: 90,
|
|
134
|
+
fail: 31,
|
|
135
|
+
"bright pass": 92,
|
|
136
|
+
"bright fail": 91,
|
|
137
|
+
"bright yellow": 93,
|
|
138
|
+
pending: 36,
|
|
139
|
+
suite: 0,
|
|
140
|
+
"error title": 0,
|
|
141
|
+
"error message": 31,
|
|
142
|
+
"error stack": 90,
|
|
143
|
+
checkmark: 32,
|
|
144
|
+
fast: 90,
|
|
145
|
+
medium: 33,
|
|
146
|
+
slow: 31,
|
|
147
|
+
green: 32,
|
|
148
|
+
light: 90,
|
|
149
|
+
"diff gutter": 90,
|
|
150
|
+
"diff added": 32,
|
|
151
|
+
"diff removed": 31,
|
|
152
|
+
"diff added inline": "30;42",
|
|
153
|
+
"diff removed inline": "30;41"
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// src/utils.ts
|
|
157
|
+
function sanitizeString(str) {
|
|
158
|
+
if (!str) {
|
|
159
|
+
return "";
|
|
160
|
+
}
|
|
161
|
+
return String(str).replace(/^.*\/([^/]+)\/?$/, "$1").replace(/\./g, "_").replace(/\s/g, "").toLowerCase();
|
|
162
|
+
}
|
|
163
|
+
function sanitizeCaps(caps) {
|
|
164
|
+
if (!caps) {
|
|
165
|
+
return "";
|
|
166
|
+
}
|
|
167
|
+
let result;
|
|
168
|
+
result = caps["appium:deviceName"] || caps.deviceName ? [
|
|
169
|
+
sanitizeString(caps.platformName),
|
|
170
|
+
// @ts-expect-error outdated JSONWP capabilities
|
|
171
|
+
sanitizeString(caps["appium:deviceName"] || caps.deviceName),
|
|
172
|
+
sanitizeString(caps["appium:platformVersion"]),
|
|
173
|
+
sanitizeString(caps["appium:app"])
|
|
174
|
+
] : [
|
|
175
|
+
sanitizeString(caps.browserName),
|
|
176
|
+
// @ts-expect-error outdated JSONWP capabilities
|
|
177
|
+
sanitizeString(caps.version || caps.browserVersion),
|
|
178
|
+
// @ts-expect-error outdated JSONWP capabilities
|
|
179
|
+
sanitizeString(caps.platform || caps.platformName),
|
|
180
|
+
sanitizeString(caps["appium:app"])
|
|
181
|
+
];
|
|
182
|
+
result = result.filter((n) => n !== void 0 && n !== "");
|
|
183
|
+
return result.join(".");
|
|
184
|
+
}
|
|
185
|
+
function getErrorsFromEvent(e) {
|
|
186
|
+
if (e.errors) {
|
|
187
|
+
return e.errors;
|
|
188
|
+
}
|
|
189
|
+
if (e.error) {
|
|
190
|
+
return [e.error];
|
|
191
|
+
}
|
|
192
|
+
return [];
|
|
260
193
|
}
|
|
261
|
-
|
|
194
|
+
function pad(str, len) {
|
|
195
|
+
return Array(len - str.length + 1).join(" ") + str;
|
|
196
|
+
}
|
|
197
|
+
function color(type, content) {
|
|
198
|
+
if (!supportsColor_default.stdout) {
|
|
199
|
+
return String(content);
|
|
200
|
+
}
|
|
201
|
+
return `\x1B[${COLORS[type]}m${content}\x1B[0m`;
|
|
202
|
+
}
|
|
203
|
+
function colorLines(name, str) {
|
|
204
|
+
return str.split("\n").map((str2) => color(name, str2)).join("\n");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// src/stats/runnable.ts
|
|
208
|
+
var RunnableStats = class {
|
|
209
|
+
constructor(type) {
|
|
210
|
+
this.type = type;
|
|
211
|
+
}
|
|
212
|
+
start = /* @__PURE__ */ new Date();
|
|
213
|
+
end;
|
|
214
|
+
_duration = 0;
|
|
215
|
+
complete() {
|
|
216
|
+
this.end = /* @__PURE__ */ new Date();
|
|
217
|
+
this._duration = this.end.getTime() - this.start.getTime();
|
|
218
|
+
}
|
|
219
|
+
get duration() {
|
|
220
|
+
if (this.end) {
|
|
221
|
+
return this._duration;
|
|
222
|
+
}
|
|
223
|
+
return (/* @__PURE__ */ new Date()).getTime() - this.start.getTime();
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* ToDo: we should always rely on uid
|
|
227
|
+
*/
|
|
228
|
+
static getIdentifier(runner) {
|
|
229
|
+
return runner.uid || runner.title;
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// src/stats/suite.ts
|
|
234
|
+
var SuiteStats = class extends RunnableStats {
|
|
235
|
+
uid;
|
|
236
|
+
cid;
|
|
237
|
+
file;
|
|
238
|
+
title;
|
|
239
|
+
fullTitle;
|
|
240
|
+
tags;
|
|
241
|
+
tests = [];
|
|
242
|
+
hooks = [];
|
|
243
|
+
suites = [];
|
|
244
|
+
parent;
|
|
245
|
+
/**
|
|
246
|
+
* an array of hooks and tests stored in order as they happen
|
|
247
|
+
*/
|
|
248
|
+
hooksAndTests = [];
|
|
249
|
+
description;
|
|
250
|
+
rule;
|
|
251
|
+
constructor(suite) {
|
|
252
|
+
super(suite.type || "suite");
|
|
253
|
+
this.uid = RunnableStats.getIdentifier(suite);
|
|
254
|
+
this.cid = suite.cid;
|
|
255
|
+
this.file = suite.file;
|
|
256
|
+
this.title = suite.title;
|
|
257
|
+
this.fullTitle = suite.fullTitle;
|
|
258
|
+
this.tags = suite.tags;
|
|
259
|
+
this.parent = suite.parent;
|
|
260
|
+
this.description = suite.description;
|
|
261
|
+
this.rule = suite.rule;
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
// src/stats/hook.ts
|
|
266
|
+
var HookStats = class extends RunnableStats {
|
|
267
|
+
uid;
|
|
268
|
+
cid;
|
|
269
|
+
title;
|
|
270
|
+
parent;
|
|
271
|
+
// Mocha only
|
|
272
|
+
body;
|
|
273
|
+
errors;
|
|
274
|
+
error;
|
|
275
|
+
state;
|
|
276
|
+
currentTest;
|
|
277
|
+
constructor(runner) {
|
|
278
|
+
super("hook");
|
|
279
|
+
this.uid = RunnableStats.getIdentifier(runner);
|
|
280
|
+
this.cid = runner.cid;
|
|
281
|
+
this.title = runner.title;
|
|
282
|
+
this.parent = runner.parent;
|
|
283
|
+
this.currentTest = runner.currentTest;
|
|
284
|
+
this.body = runner.body;
|
|
285
|
+
}
|
|
286
|
+
complete(errors) {
|
|
287
|
+
this.errors = errors;
|
|
288
|
+
if (errors && errors.length) {
|
|
289
|
+
this.error = errors[0];
|
|
290
|
+
this.state = "failed";
|
|
291
|
+
}
|
|
292
|
+
super.complete();
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
// src/stats/test.ts
|
|
297
|
+
import { types as nodeUtilTypes } from "node:util";
|
|
298
|
+
import { diffWordsWithSpace } from "diff";
|
|
299
|
+
import objectInspect from "object-inspect";
|
|
300
|
+
var maxStringLength = 2048;
|
|
301
|
+
var TestStats = class extends RunnableStats {
|
|
302
|
+
uid;
|
|
303
|
+
cid;
|
|
304
|
+
title;
|
|
305
|
+
currentTest;
|
|
306
|
+
fullTitle;
|
|
307
|
+
output;
|
|
308
|
+
argument;
|
|
309
|
+
retries;
|
|
310
|
+
parent;
|
|
311
|
+
/**
|
|
312
|
+
* initial test state is pending
|
|
313
|
+
* the state can change to the following: passed, skipped, failed
|
|
314
|
+
*/
|
|
315
|
+
state;
|
|
316
|
+
pendingReason;
|
|
317
|
+
errors;
|
|
318
|
+
error;
|
|
319
|
+
body;
|
|
320
|
+
constructor(test) {
|
|
321
|
+
super("test");
|
|
322
|
+
this.uid = RunnableStats.getIdentifier(test);
|
|
323
|
+
this.cid = test.cid;
|
|
324
|
+
this.title = test.title;
|
|
325
|
+
this.fullTitle = test.fullTitle;
|
|
326
|
+
this.output = [];
|
|
327
|
+
this.argument = test.argument;
|
|
328
|
+
this.retries = test.retries;
|
|
329
|
+
this.parent = test.parent;
|
|
330
|
+
this.body = test.body;
|
|
331
|
+
this.state = "pending";
|
|
332
|
+
}
|
|
333
|
+
pass() {
|
|
334
|
+
this.complete();
|
|
335
|
+
this.state = "passed";
|
|
336
|
+
}
|
|
337
|
+
skip(reason) {
|
|
338
|
+
this.pendingReason = reason;
|
|
339
|
+
this.state = "skipped";
|
|
340
|
+
}
|
|
341
|
+
fail(errors) {
|
|
342
|
+
this.complete();
|
|
343
|
+
this.state = "failed";
|
|
344
|
+
const formattedErrors = errors?.map((err) => (
|
|
345
|
+
/**
|
|
346
|
+
* only format if error object has either an "expected" or "actual" property set
|
|
347
|
+
*/
|
|
348
|
+
(err.expected || err.actual) && !nodeUtilTypes.isProxy(err.actual) && /**
|
|
349
|
+
* and if they aren't already formated, e.g. in Jasmine
|
|
350
|
+
*/
|
|
351
|
+
(err.message && !err.message.includes("Expected: ") && !err.message.includes("Received: ")) ? this._stringifyDiffObjs(err) : err
|
|
352
|
+
));
|
|
353
|
+
this.errors = formattedErrors;
|
|
354
|
+
if (formattedErrors && formattedErrors.length) {
|
|
355
|
+
this.error = formattedErrors[0];
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
_stringifyDiffObjs(err) {
|
|
359
|
+
const inspectOpts = { maxStringLength };
|
|
360
|
+
const expected = objectInspect(err.expected, inspectOpts);
|
|
361
|
+
const actual = objectInspect(err.actual, inspectOpts);
|
|
362
|
+
let msg = diffWordsWithSpace(actual, expected).map((str) => str.added ? colorLines("diff added inline", str.value) : str.removed ? colorLines("diff removed inline", str.value) : str.value).join("");
|
|
363
|
+
const lines = msg.split("\n");
|
|
364
|
+
if (lines.length > 4) {
|
|
365
|
+
const width = String(lines.length).length;
|
|
366
|
+
msg = lines.map(function(str, i) {
|
|
367
|
+
return pad(String(++i), width) + " | " + str;
|
|
368
|
+
}).join("\n");
|
|
369
|
+
}
|
|
370
|
+
msg = `
|
|
371
|
+
${color("diff removed inline", "actual")} ${color("diff added inline", "expected")}
|
|
372
|
+
|
|
373
|
+
${msg}
|
|
374
|
+
`;
|
|
375
|
+
msg = msg.replace(/^/gm, " ");
|
|
376
|
+
const newError = new Error(err.message + msg);
|
|
377
|
+
newError.stack = err.stack;
|
|
378
|
+
return newError;
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
// src/stats/runner.ts
|
|
383
|
+
var RunnerStats = class extends RunnableStats {
|
|
384
|
+
cid;
|
|
385
|
+
capabilities;
|
|
386
|
+
sanitizedCapabilities;
|
|
387
|
+
config;
|
|
388
|
+
specs;
|
|
389
|
+
sessionId;
|
|
390
|
+
isMultiremote;
|
|
391
|
+
instanceOptions;
|
|
392
|
+
retry;
|
|
393
|
+
failures;
|
|
394
|
+
retries;
|
|
395
|
+
constructor(runner) {
|
|
396
|
+
super("runner");
|
|
397
|
+
this.cid = runner.cid;
|
|
398
|
+
this.capabilities = runner.capabilities;
|
|
399
|
+
this.sanitizedCapabilities = sanitizeCaps(runner.capabilities);
|
|
400
|
+
this.config = runner.config;
|
|
401
|
+
this.specs = runner.specs;
|
|
402
|
+
this.sessionId = runner.sessionId;
|
|
403
|
+
this.isMultiremote = runner.isMultiremote;
|
|
404
|
+
this.instanceOptions = runner.instanceOptions;
|
|
405
|
+
this.retry = runner.retry;
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
// src/index.ts
|
|
410
|
+
var WDIOReporter = class extends EventEmitter {
|
|
411
|
+
constructor(options) {
|
|
412
|
+
super();
|
|
413
|
+
this.options = options;
|
|
414
|
+
if (this.options.outputDir) {
|
|
415
|
+
try {
|
|
416
|
+
fs.mkdirSync(this.options.outputDir, { recursive: true });
|
|
417
|
+
} catch (err) {
|
|
418
|
+
throw new Error(`Couldn't create output directory at "${this.options.outputDir}": ${err.stack}`);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
this.outputStream = (this.options.stdout || !this.options.logFile) && this.options.writeStream ? this.options.writeStream : fs.createWriteStream(this.options.logFile);
|
|
422
|
+
let currentTest;
|
|
423
|
+
const rootSuite = new SuiteStats({
|
|
424
|
+
title: "(root)",
|
|
425
|
+
fullTitle: "(root)",
|
|
426
|
+
file: ""
|
|
427
|
+
});
|
|
428
|
+
this.currentSuites.push(rootSuite);
|
|
429
|
+
this.on("client:beforeCommand", this.onBeforeCommand.bind(this));
|
|
430
|
+
this.on("client:afterCommand", this.onAfterCommand.bind(this));
|
|
431
|
+
this.on("client:beforeAssertion", this.onBeforeAssertion.bind(this));
|
|
432
|
+
this.on("client:afterAssertion", this.onAfterAssertion.bind(this));
|
|
433
|
+
this.on(
|
|
434
|
+
"runner:start",
|
|
435
|
+
/* istanbul ignore next */
|
|
436
|
+
(runner) => {
|
|
437
|
+
rootSuite.cid = runner.cid;
|
|
438
|
+
this.specs.push(...runner.specs);
|
|
439
|
+
this.runnerStat = new RunnerStats(runner);
|
|
440
|
+
this.onRunnerStart(this.runnerStat);
|
|
441
|
+
}
|
|
442
|
+
);
|
|
443
|
+
this.on(
|
|
444
|
+
"suite:start",
|
|
445
|
+
/* istanbul ignore next */
|
|
446
|
+
(params) => {
|
|
447
|
+
if (!params.file) {
|
|
448
|
+
params.file = !params.parent ? this.specs.shift() || "unknown spec file" : this.currentSpec;
|
|
449
|
+
this.currentSpec = params.file;
|
|
450
|
+
}
|
|
451
|
+
const suite = new SuiteStats(params);
|
|
452
|
+
const currentSuite = this.currentSuites[this.currentSuites.length - 1];
|
|
453
|
+
currentSuite.suites.push(suite);
|
|
454
|
+
this.currentSuites.push(suite);
|
|
455
|
+
this.suites[suite.uid] = suite;
|
|
456
|
+
this.onSuiteStart(suite);
|
|
457
|
+
}
|
|
458
|
+
);
|
|
459
|
+
this.on(
|
|
460
|
+
"hook:start",
|
|
461
|
+
/* istanbul ignore next */
|
|
462
|
+
(hook) => {
|
|
463
|
+
const hookStats = new HookStats(hook);
|
|
464
|
+
const currentSuite = this.currentSuites[this.currentSuites.length - 1];
|
|
465
|
+
currentSuite.hooks.push(hookStats);
|
|
466
|
+
currentSuite.hooksAndTests.push(hookStats);
|
|
467
|
+
this.hooks[hook.uid] = hookStats;
|
|
468
|
+
this.onHookStart(hookStats);
|
|
469
|
+
}
|
|
470
|
+
);
|
|
471
|
+
this.on(
|
|
472
|
+
"hook:end",
|
|
473
|
+
/* istanbul ignore next */
|
|
474
|
+
(hook) => {
|
|
475
|
+
const hookStats = this.hooks[hook.uid];
|
|
476
|
+
hookStats.complete(getErrorsFromEvent(hook));
|
|
477
|
+
this.counts.hooks++;
|
|
478
|
+
this.onHookEnd(hookStats);
|
|
479
|
+
}
|
|
480
|
+
);
|
|
481
|
+
this.on(
|
|
482
|
+
"test:start",
|
|
483
|
+
/* istanbul ignore next */
|
|
484
|
+
(test) => {
|
|
485
|
+
test.retries = this.retries;
|
|
486
|
+
currentTest = new TestStats(test);
|
|
487
|
+
const currentSuite = this.currentSuites[this.currentSuites.length - 1];
|
|
488
|
+
currentSuite.tests.push(currentTest);
|
|
489
|
+
currentSuite.hooksAndTests.push(currentTest);
|
|
490
|
+
this.tests[test.uid] = currentTest;
|
|
491
|
+
this.onTestStart(currentTest);
|
|
492
|
+
}
|
|
493
|
+
);
|
|
494
|
+
this.on(
|
|
495
|
+
"test:pass",
|
|
496
|
+
/* istanbul ignore next */
|
|
497
|
+
(test) => {
|
|
498
|
+
const testStat = this.tests[test.uid];
|
|
499
|
+
testStat.pass();
|
|
500
|
+
this.counts.passes++;
|
|
501
|
+
this.counts.tests++;
|
|
502
|
+
this.onTestPass(testStat);
|
|
503
|
+
}
|
|
504
|
+
);
|
|
505
|
+
this.on("test:skip", (test) => {
|
|
506
|
+
const testStat = this.tests[test.uid];
|
|
507
|
+
currentTest.skip(test.pendingReason);
|
|
508
|
+
this.counts.skipping++;
|
|
509
|
+
this.counts.tests++;
|
|
510
|
+
this.onTestSkip(testStat);
|
|
511
|
+
});
|
|
512
|
+
this.on(
|
|
513
|
+
"test:fail",
|
|
514
|
+
/* istanbul ignore next */
|
|
515
|
+
(test) => {
|
|
516
|
+
const testStat = this.tests[test.uid];
|
|
517
|
+
testStat.fail(getErrorsFromEvent(test));
|
|
518
|
+
this.counts.failures++;
|
|
519
|
+
this.counts.tests++;
|
|
520
|
+
this.onTestFail(testStat);
|
|
521
|
+
}
|
|
522
|
+
);
|
|
523
|
+
this.on("test:retry", (test) => {
|
|
524
|
+
const testStat = this.tests[test.uid];
|
|
525
|
+
testStat.fail(getErrorsFromEvent(test));
|
|
526
|
+
this.onTestRetry(testStat);
|
|
527
|
+
this.retries++;
|
|
528
|
+
});
|
|
529
|
+
this.on("test:pending", (test) => {
|
|
530
|
+
test.retries = this.retries;
|
|
531
|
+
const currentSuite = this.currentSuites[this.currentSuites.length - 1];
|
|
532
|
+
currentTest = new TestStats(test);
|
|
533
|
+
if (test.uid in this.tests && this.tests[test.uid].state !== "pending") {
|
|
534
|
+
currentTest.uid = test.uid in this.tests ? "skipped-" + this.counts.skipping : currentTest.uid;
|
|
535
|
+
}
|
|
536
|
+
const suiteTests = currentSuite.tests;
|
|
537
|
+
if (!suiteTests.length || currentTest.uid !== suiteTests[suiteTests.length - 1].uid) {
|
|
538
|
+
currentSuite.tests.push(currentTest);
|
|
539
|
+
currentSuite.hooksAndTests.push(currentTest);
|
|
540
|
+
} else {
|
|
541
|
+
suiteTests[suiteTests.length - 1] = currentTest;
|
|
542
|
+
currentSuite.hooksAndTests[currentSuite.hooksAndTests.length - 1] = currentTest;
|
|
543
|
+
}
|
|
544
|
+
this.tests[currentTest.uid] = currentTest;
|
|
545
|
+
currentTest.skip(test.pendingReason);
|
|
546
|
+
this.counts.skipping++;
|
|
547
|
+
this.counts.tests++;
|
|
548
|
+
this.onTestSkip(currentTest);
|
|
549
|
+
});
|
|
550
|
+
this.on(
|
|
551
|
+
"test:end",
|
|
552
|
+
/* istanbul ignore next */
|
|
553
|
+
(test) => {
|
|
554
|
+
const testStat = this.tests[test.uid];
|
|
555
|
+
this.retries = 0;
|
|
556
|
+
this.onTestEnd(testStat);
|
|
557
|
+
}
|
|
558
|
+
);
|
|
559
|
+
this.on(
|
|
560
|
+
"suite:end",
|
|
561
|
+
/* istanbul ignore next */
|
|
562
|
+
(suite) => {
|
|
563
|
+
const suiteStat = this.suites[suite.uid];
|
|
564
|
+
suiteStat.complete();
|
|
565
|
+
this.currentSuites.pop();
|
|
566
|
+
this.onSuiteEnd(suiteStat);
|
|
567
|
+
}
|
|
568
|
+
);
|
|
569
|
+
this.on(
|
|
570
|
+
"runner:end",
|
|
571
|
+
/* istanbul ignore next */
|
|
572
|
+
(runner) => {
|
|
573
|
+
rootSuite.complete();
|
|
574
|
+
if (this.runnerStat) {
|
|
575
|
+
this.runnerStat.failures = runner.failures;
|
|
576
|
+
this.runnerStat.retries = runner.retries;
|
|
577
|
+
this.runnerStat.complete();
|
|
578
|
+
this.onRunnerEnd(this.runnerStat);
|
|
579
|
+
}
|
|
580
|
+
const logFile = this.options.logFile;
|
|
581
|
+
if (!this.isContentPresent && logFile && fs.existsSync(logFile)) {
|
|
582
|
+
fs.unlinkSync(logFile);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
);
|
|
586
|
+
this.on(
|
|
587
|
+
"client:beforeCommand",
|
|
588
|
+
/* istanbul ignore next */
|
|
589
|
+
(payload) => {
|
|
590
|
+
if (!currentTest) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
currentTest.output.push(Object.assign(payload, { type: "command" }));
|
|
594
|
+
}
|
|
595
|
+
);
|
|
596
|
+
this.on(
|
|
597
|
+
"client:afterCommand",
|
|
598
|
+
/* istanbul ignore next */
|
|
599
|
+
(payload) => {
|
|
600
|
+
if (!currentTest) {
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
currentTest.output.push(Object.assign(payload, { type: "result" }));
|
|
604
|
+
}
|
|
605
|
+
);
|
|
606
|
+
}
|
|
607
|
+
outputStream;
|
|
608
|
+
failures = 0;
|
|
609
|
+
suites = {};
|
|
610
|
+
hooks = {};
|
|
611
|
+
tests = {};
|
|
612
|
+
currentSuites = [];
|
|
613
|
+
counts = {
|
|
614
|
+
suites: 0,
|
|
615
|
+
tests: 0,
|
|
616
|
+
hooks: 0,
|
|
617
|
+
passes: 0,
|
|
618
|
+
skipping: 0,
|
|
619
|
+
failures: 0
|
|
620
|
+
};
|
|
621
|
+
retries = 0;
|
|
622
|
+
runnerStat;
|
|
623
|
+
isContentPresent = false;
|
|
624
|
+
specs = [];
|
|
625
|
+
currentSpec;
|
|
626
|
+
/**
|
|
627
|
+
* allows reporter to stale process shutdown process until required sync work
|
|
628
|
+
* is done (e.g. when having to send data to some server or any other async work)
|
|
629
|
+
*/
|
|
630
|
+
get isSynchronised() {
|
|
631
|
+
return true;
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* function to write to reporters output stream
|
|
635
|
+
*/
|
|
636
|
+
write(content) {
|
|
637
|
+
if (content) {
|
|
638
|
+
this.isContentPresent = true;
|
|
639
|
+
}
|
|
640
|
+
this.outputStream.write(content);
|
|
641
|
+
}
|
|
642
|
+
/* istanbul ignore next */
|
|
643
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
644
|
+
onRunnerStart(runnerStats) {
|
|
645
|
+
}
|
|
646
|
+
/* istanbul ignore next */
|
|
647
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
648
|
+
onBeforeCommand(commandArgs) {
|
|
649
|
+
}
|
|
650
|
+
/* istanbul ignore next */
|
|
651
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
652
|
+
onAfterCommand(commandArgs) {
|
|
653
|
+
}
|
|
654
|
+
/* istanbul ignore next */
|
|
655
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
656
|
+
onBeforeAssertion(assertionArgs) {
|
|
657
|
+
}
|
|
658
|
+
/* istanbul ignore next */
|
|
659
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
660
|
+
onAfterAssertion(assertionArgs) {
|
|
661
|
+
}
|
|
662
|
+
/* istanbul ignore next */
|
|
663
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
664
|
+
onSuiteStart(suiteStats) {
|
|
665
|
+
}
|
|
666
|
+
/* istanbul ignore next */
|
|
667
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
668
|
+
onHookStart(hookStat) {
|
|
669
|
+
}
|
|
670
|
+
/* istanbul ignore next */
|
|
671
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
672
|
+
onHookEnd(hookStats) {
|
|
673
|
+
}
|
|
674
|
+
/* istanbul ignore next */
|
|
675
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
676
|
+
onTestStart(testStats) {
|
|
677
|
+
}
|
|
678
|
+
/* istanbul ignore next */
|
|
679
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
680
|
+
onTestPass(testStats) {
|
|
681
|
+
}
|
|
682
|
+
/* istanbul ignore next */
|
|
683
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
684
|
+
onTestFail(testStats) {
|
|
685
|
+
}
|
|
686
|
+
/* istanbul ignore next */
|
|
687
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
688
|
+
onTestRetry(testStats) {
|
|
689
|
+
}
|
|
690
|
+
/* istanbul ignore next */
|
|
691
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
692
|
+
onTestSkip(testStats) {
|
|
693
|
+
}
|
|
694
|
+
/* istanbul ignore next */
|
|
695
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
696
|
+
onTestEnd(testStats) {
|
|
697
|
+
}
|
|
698
|
+
/* istanbul ignore next */
|
|
699
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
700
|
+
onSuiteEnd(suiteStats) {
|
|
701
|
+
}
|
|
702
|
+
/* istanbul ignore next */
|
|
703
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
704
|
+
onRunnerEnd(runnerStats) {
|
|
705
|
+
}
|
|
706
|
+
};
|
|
707
|
+
export {
|
|
708
|
+
HookStats,
|
|
709
|
+
RunnerStats,
|
|
710
|
+
SuiteStats,
|
|
711
|
+
TestStats,
|
|
712
|
+
WDIOReporter as default
|
|
713
|
+
};
|