@wdio/reporter 8.15.0 → 8.15.7
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.d.ts.map +1 -1
- package/build/index.js +1 -3
- package/build/supportsColor.d.ts +42 -0
- package/build/supportsColor.d.ts.map +1 -0
- package/build/supportsColor.js +146 -0
- package/build/utils.d.ts.map +1 -1
- package/build/utils.js +1 -1
- package/cjs/constants.js +26 -0
- package/cjs/index.js +263 -0
- package/cjs/package.json +3 -0
- package/cjs/stats/hook.js +36 -0
- package/cjs/stats/runnable.js +32 -0
- package/cjs/stats/runner.js +37 -0
- package/cjs/stats/suite.js +43 -0
- package/cjs/stats/test.js +114 -0
- package/cjs/supportsColor.js +153 -0
- package/cjs/types.js +2 -0
- package/cjs/utils.js +105 -0
- package/package.json +15 -7
- package/tsconfig.cjs.json +9 -0
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAW,MAAM,aAAa,CAAA;AAIrD,OAAO,UAAU,MAAM,kBAAkB,CAAA;AAEzC,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,WAAW,MAAM,mBAAmB,CAAA;AAC3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEjG,KAAK,iBAAiB,GAAG;IAAE,KAAK,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAA;CAAE,CAAA;AAE7D,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,YAAY;IAqB/B,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;IApBtD,YAAY,EAAE,WAAW,GAAG,iBAAiB,CAAA;IAC7C,QAAQ,SAAI;IACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAK;IACvC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAK;IACrC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAI;IACpC,aAAa,EAAE,UAAU,EAAE,CAAK;IAChC,MAAM;;;;;;;MAOL;IACD,OAAO,SAAI;IACX,UAAU,CAAC,EAAE,WAAW,CAAA;IACxB,gBAAgB,UAAQ;IACxB,KAAK,EAAE,MAAM,EAAE,CAAK;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;gBAED,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;IA2LtD;;;OAGG;IACH,IAAI,cAAc,YAEjB;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,GAAG;IASlB,aAAa,CAAC,WAAW,EAAE,WAAW;IAGtC,eAAe,CAAC,WAAW,EAAE,iBAAiB;IAG9C,cAAc,CAAC,WAAW,EAAE,gBAAgB;IAG5C,YAAY,CAAC,UAAU,EAAE,UAAU;IAGnC,WAAW,CAAC,QAAQ,EAAE,SAAS;IAG/B,SAAS,CAAC,SAAS,EAAE,SAAS;IAG9B,WAAW,CAAC,SAAS,EAAE,SAAS;IAGhC,UAAU,CAAC,SAAS,EAAE,SAAS;IAG/B,UAAU,CAAC,SAAS,EAAE,SAAS;IAG/B,WAAW,CAAC,SAAS,EAAE,SAAS;IAGhC,UAAU,CAAC,SAAS,EAAE,SAAS;IAG/B,SAAS,CAAC,SAAS,EAAE,SAAS;IAG9B,UAAU,CAAC,UAAU,EAAE,UAAU;IAGjC,WAAW,CAAC,WAAW,EAAE,WAAW;CACvC;AAED,OAAO,EACH,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,iBAAiB,EACrE,gBAAgB,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAChD,CAAA"}
|
package/build/index.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import { EventEmitter } from 'node:events';
|
|
3
|
-
import logger from '@wdio/logger';
|
|
4
3
|
import { getErrorsFromEvent } from './utils.js';
|
|
5
4
|
import SuiteStats from './stats/suite.js';
|
|
6
5
|
import HookStats from './stats/hook.js';
|
|
7
6
|
import TestStats from './stats/test.js';
|
|
8
7
|
import RunnerStats from './stats/runner.js';
|
|
9
|
-
const log = logger('WDIOReporter');
|
|
10
8
|
export default class WDIOReporter extends EventEmitter {
|
|
11
9
|
options;
|
|
12
10
|
outputStream;
|
|
@@ -37,7 +35,7 @@ export default class WDIOReporter extends EventEmitter {
|
|
|
37
35
|
fs.mkdirSync(this.options.outputDir, { recursive: true });
|
|
38
36
|
}
|
|
39
37
|
catch (err) {
|
|
40
|
-
|
|
38
|
+
throw new Error(`Couldn't create output directory at "${this.options.outputDir}": ${err.stack}`);
|
|
41
39
|
}
|
|
42
40
|
}
|
|
43
41
|
this.outputStream = (this.options.stdout || !this.options.logFile) && this.options.writeStream
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* original source: https://github.com/chalk/supports-color/blob/d4f413efaf8da045c5ab440ed418ef02dbb28bf1/index.js
|
|
3
|
+
*
|
|
4
|
+
* This file was imported due to lacking support of CJS environments in the original package.
|
|
5
|
+
*/
|
|
6
|
+
declare global {
|
|
7
|
+
var Deno: any;
|
|
8
|
+
}
|
|
9
|
+
interface Options {
|
|
10
|
+
/**
|
|
11
|
+
* By default it is `true`, which instructs `supportsColor()` to sniff `process.argv`
|
|
12
|
+
* for the multitude of `--color` flags (see _Info_ below).
|
|
13
|
+
* If `false`, then `process.argv` is not considered when determining color support.
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
16
|
+
sniffFlags?: boolean | undefined;
|
|
17
|
+
isTTY?: boolean | undefined;
|
|
18
|
+
}
|
|
19
|
+
export declare function createSupportsColor(stream: {
|
|
20
|
+
isTTY?: boolean;
|
|
21
|
+
}, options?: Options): false | {
|
|
22
|
+
level: number;
|
|
23
|
+
hasBasic: boolean;
|
|
24
|
+
has256: boolean;
|
|
25
|
+
has16m: boolean;
|
|
26
|
+
};
|
|
27
|
+
declare const supportsColor: {
|
|
28
|
+
stdout: boolean | {
|
|
29
|
+
level: number;
|
|
30
|
+
hasBasic: boolean;
|
|
31
|
+
has256: boolean;
|
|
32
|
+
has16m: boolean;
|
|
33
|
+
};
|
|
34
|
+
stderr: boolean | {
|
|
35
|
+
level: number;
|
|
36
|
+
hasBasic: boolean;
|
|
37
|
+
has256: boolean;
|
|
38
|
+
has16m: boolean;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export default supportsColor;
|
|
42
|
+
//# sourceMappingURL=supportsColor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supportsColor.d.ts","sourceRoot":"","sources":["../src/supportsColor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,CAAC,MAAM,CAAC;IAEX,IAAI,IAAI,EAAE,GAAG,CAAA;CAChB;AAWD,UAAU,OAAO;IACb;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AA4JD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,OAAO,GAAE,OAAY;;;;;EAOrF;AAED,QAAA,MAAM,aAAa;;;;;;;;;;;;;CAGlB,CAAA;AAED,eAAe,aAAa,CAAA"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* original source: https://github.com/chalk/supports-color/blob/d4f413efaf8da045c5ab440ed418ef02dbb28bf1/index.js
|
|
3
|
+
*
|
|
4
|
+
* This file was imported due to lacking support of CJS environments in the original package.
|
|
5
|
+
*/
|
|
6
|
+
import process from 'node:process';
|
|
7
|
+
import os from 'node:os';
|
|
8
|
+
import tty from 'node:tty';
|
|
9
|
+
// From: https://github.com/sindresorhus/has-flag/blob/main/index.js
|
|
10
|
+
/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {
|
|
11
|
+
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {
|
|
12
|
+
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
|
|
13
|
+
const position = argv.indexOf(prefix + flag);
|
|
14
|
+
const terminatorPosition = argv.indexOf('--');
|
|
15
|
+
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
16
|
+
}
|
|
17
|
+
const { env } = process;
|
|
18
|
+
let flagForceColor;
|
|
19
|
+
if (hasFlag('no-color')
|
|
20
|
+
|| hasFlag('no-colors')
|
|
21
|
+
|| hasFlag('color=false')
|
|
22
|
+
|| hasFlag('color=never')) {
|
|
23
|
+
flagForceColor = 0;
|
|
24
|
+
}
|
|
25
|
+
else if (hasFlag('color')
|
|
26
|
+
|| hasFlag('colors')
|
|
27
|
+
|| hasFlag('color=true')
|
|
28
|
+
|| hasFlag('color=always')) {
|
|
29
|
+
flagForceColor = 1;
|
|
30
|
+
}
|
|
31
|
+
function envForceColor() {
|
|
32
|
+
if ('FORCE_COLOR' in env) {
|
|
33
|
+
if (env.FORCE_COLOR === 'true') {
|
|
34
|
+
return 1;
|
|
35
|
+
}
|
|
36
|
+
if (env.FORCE_COLOR === 'false') {
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function translateLevel(level) {
|
|
43
|
+
if (level === 0) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
level,
|
|
48
|
+
hasBasic: true,
|
|
49
|
+
has256: level >= 2,
|
|
50
|
+
has16m: level >= 3,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
54
|
+
const noFlagForceColor = envForceColor();
|
|
55
|
+
if (noFlagForceColor !== undefined) {
|
|
56
|
+
flagForceColor = noFlagForceColor;
|
|
57
|
+
}
|
|
58
|
+
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
59
|
+
if (forceColor === 0) {
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
if (sniffFlags) {
|
|
63
|
+
if (hasFlag('color=16m')
|
|
64
|
+
|| hasFlag('color=full')
|
|
65
|
+
|| hasFlag('color=truecolor')) {
|
|
66
|
+
return 3;
|
|
67
|
+
}
|
|
68
|
+
if (hasFlag('color=256')) {
|
|
69
|
+
return 2;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Check for Azure DevOps pipelines.
|
|
73
|
+
// Has to be above the `!streamIsTTY` check.
|
|
74
|
+
if ('TF_BUILD' in env && 'AGENT_NAME' in env) {
|
|
75
|
+
return 1;
|
|
76
|
+
}
|
|
77
|
+
if (haveStream && !streamIsTTY && forceColor === undefined) {
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
const min = forceColor || 0;
|
|
81
|
+
if (env.TERM === 'dumb') {
|
|
82
|
+
return min;
|
|
83
|
+
}
|
|
84
|
+
if (process.platform === 'win32') {
|
|
85
|
+
// Windows 10 build 10586 is the first Windows release that supports 256 colors.
|
|
86
|
+
// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
|
|
87
|
+
const osRelease = os.release().split('.');
|
|
88
|
+
if (Number(osRelease[0]) >= 10
|
|
89
|
+
&& Number(osRelease[2]) >= 10586) {
|
|
90
|
+
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
91
|
+
}
|
|
92
|
+
return 1;
|
|
93
|
+
}
|
|
94
|
+
if ('CI' in env) {
|
|
95
|
+
if ('GITHUB_ACTIONS' in env || 'GITEA_ACTIONS' in env) {
|
|
96
|
+
return 3;
|
|
97
|
+
}
|
|
98
|
+
if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
|
|
99
|
+
return 1;
|
|
100
|
+
}
|
|
101
|
+
return min;
|
|
102
|
+
}
|
|
103
|
+
if ('TEAMCITY_VERSION' in env) {
|
|
104
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
105
|
+
}
|
|
106
|
+
if (env.COLORTERM === 'truecolor') {
|
|
107
|
+
return 3;
|
|
108
|
+
}
|
|
109
|
+
if (env.TERM === 'xterm-kitty') {
|
|
110
|
+
return 3;
|
|
111
|
+
}
|
|
112
|
+
if ('TERM_PROGRAM' in env) {
|
|
113
|
+
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
|
|
114
|
+
switch (env.TERM_PROGRAM) {
|
|
115
|
+
case 'iTerm.app': {
|
|
116
|
+
return version >= 3 ? 3 : 2;
|
|
117
|
+
}
|
|
118
|
+
case 'Apple_Terminal': {
|
|
119
|
+
return 2;
|
|
120
|
+
}
|
|
121
|
+
// No default
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (env.TERM && /-256(color)?$/i.test(env.TERM)) {
|
|
125
|
+
return 2;
|
|
126
|
+
}
|
|
127
|
+
if (env.TERM && /^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
128
|
+
return 1;
|
|
129
|
+
}
|
|
130
|
+
if ('COLORTERM' in env) {
|
|
131
|
+
return 1;
|
|
132
|
+
}
|
|
133
|
+
return min;
|
|
134
|
+
}
|
|
135
|
+
export function createSupportsColor(stream, options = {}) {
|
|
136
|
+
const level = _supportsColor(stream, {
|
|
137
|
+
streamIsTTY: stream && stream.isTTY,
|
|
138
|
+
...options,
|
|
139
|
+
});
|
|
140
|
+
return translateLevel(level);
|
|
141
|
+
}
|
|
142
|
+
const supportsColor = {
|
|
143
|
+
stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
|
|
144
|
+
stderr: createSupportsColor({ isTTY: tty.isatty(2) }),
|
|
145
|
+
};
|
|
146
|
+
export default supportsColor;
|
package/build/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG/C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAEvC;;;;GAIG;AACH,wBAAgB,cAAc,CAAE,GAAG,CAAC,EAAE,MAAM,UAU3C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAE,IAAI,CAAC,EAAE,YAAY,CAAC,mBAAmB,UA0BpE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,GAAG,CAAA;CAAE,OAQlE;AAED;;;;;;;GAOG;AACH,wBAAgB,GAAG,CAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAE5C;AAED,wBAAgB,KAAK,CAAE,IAAI,EAAE,MAAM,OAAO,MAAM,EAAE,OAAO,EAAE,MAAM,UAKhE;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAE,IAAI,EAAE,MAAM,OAAO,MAAM,EAAE,GAAG,EAAE,MAAM,UAKjE"}
|
package/build/utils.js
CHANGED
package/cjs/constants.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.COLORS = void 0;
|
|
4
|
+
exports.COLORS = {
|
|
5
|
+
pass: 90,
|
|
6
|
+
fail: 31,
|
|
7
|
+
'bright pass': 92,
|
|
8
|
+
'bright fail': 91,
|
|
9
|
+
'bright yellow': 93,
|
|
10
|
+
pending: 36,
|
|
11
|
+
suite: 0,
|
|
12
|
+
'error title': 0,
|
|
13
|
+
'error message': 31,
|
|
14
|
+
'error stack': 90,
|
|
15
|
+
checkmark: 32,
|
|
16
|
+
fast: 90,
|
|
17
|
+
medium: 33,
|
|
18
|
+
slow: 31,
|
|
19
|
+
green: 32,
|
|
20
|
+
light: 90,
|
|
21
|
+
'diff gutter': 90,
|
|
22
|
+
'diff added': 32,
|
|
23
|
+
'diff removed': 31,
|
|
24
|
+
'diff added inline': '30;42',
|
|
25
|
+
'diff removed inline': '30;41'
|
|
26
|
+
};
|
package/cjs/index.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RunnerStats = exports.TestStats = exports.HookStats = exports.SuiteStats = void 0;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_events_1 = require("node:events");
|
|
9
|
+
const utils_js_1 = require("./utils.js");
|
|
10
|
+
const suite_js_1 = __importDefault(require("./stats/suite.js"));
|
|
11
|
+
exports.SuiteStats = suite_js_1.default;
|
|
12
|
+
const hook_js_1 = __importDefault(require("./stats/hook.js"));
|
|
13
|
+
exports.HookStats = hook_js_1.default;
|
|
14
|
+
const test_js_1 = __importDefault(require("./stats/test.js"));
|
|
15
|
+
exports.TestStats = test_js_1.default;
|
|
16
|
+
const runner_js_1 = __importDefault(require("./stats/runner.js"));
|
|
17
|
+
exports.RunnerStats = runner_js_1.default;
|
|
18
|
+
class WDIOReporter extends node_events_1.EventEmitter {
|
|
19
|
+
options;
|
|
20
|
+
outputStream;
|
|
21
|
+
failures = 0;
|
|
22
|
+
suites = {};
|
|
23
|
+
hooks = {};
|
|
24
|
+
tests = {};
|
|
25
|
+
currentSuites = [];
|
|
26
|
+
counts = {
|
|
27
|
+
suites: 0,
|
|
28
|
+
tests: 0,
|
|
29
|
+
hooks: 0,
|
|
30
|
+
passes: 0,
|
|
31
|
+
skipping: 0,
|
|
32
|
+
failures: 0
|
|
33
|
+
};
|
|
34
|
+
retries = 0;
|
|
35
|
+
runnerStat;
|
|
36
|
+
isContentPresent = false;
|
|
37
|
+
specs = [];
|
|
38
|
+
currentSpec;
|
|
39
|
+
constructor(options) {
|
|
40
|
+
super();
|
|
41
|
+
this.options = options;
|
|
42
|
+
// ensure the report directory exists
|
|
43
|
+
if (this.options.outputDir) {
|
|
44
|
+
try {
|
|
45
|
+
node_fs_1.default.mkdirSync(this.options.outputDir, { recursive: true });
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
throw new Error(`Couldn't create output directory at "${this.options.outputDir}": ${err.stack}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
this.outputStream = (this.options.stdout || !this.options.logFile) && this.options.writeStream
|
|
52
|
+
? this.options.writeStream
|
|
53
|
+
: node_fs_1.default.createWriteStream(this.options.logFile);
|
|
54
|
+
let currentTest;
|
|
55
|
+
const rootSuite = new suite_js_1.default({
|
|
56
|
+
title: '(root)',
|
|
57
|
+
fullTitle: '(root)',
|
|
58
|
+
file: ''
|
|
59
|
+
});
|
|
60
|
+
this.currentSuites.push(rootSuite);
|
|
61
|
+
this.on('client:beforeCommand', this.onBeforeCommand.bind(this));
|
|
62
|
+
this.on('client:afterCommand', this.onAfterCommand.bind(this));
|
|
63
|
+
this.on('runner:start', /* istanbul ignore next */ (runner) => {
|
|
64
|
+
rootSuite.cid = runner.cid;
|
|
65
|
+
this.specs.push(...runner.specs);
|
|
66
|
+
this.runnerStat = new runner_js_1.default(runner);
|
|
67
|
+
this.onRunnerStart(this.runnerStat);
|
|
68
|
+
});
|
|
69
|
+
this.on('suite:start', /* istanbul ignore next */ (params) => {
|
|
70
|
+
/**
|
|
71
|
+
* the jasmine framework doesn't give us information about the file
|
|
72
|
+
* therefore we need to propagate these information into params
|
|
73
|
+
*/
|
|
74
|
+
if (!params.file) {
|
|
75
|
+
params.file = !params.parent
|
|
76
|
+
? this.specs.shift() || 'unknown spec file'
|
|
77
|
+
: this.currentSpec;
|
|
78
|
+
this.currentSpec = params.file;
|
|
79
|
+
}
|
|
80
|
+
const suite = new suite_js_1.default(params);
|
|
81
|
+
const currentSuite = this.currentSuites[this.currentSuites.length - 1];
|
|
82
|
+
currentSuite.suites.push(suite);
|
|
83
|
+
this.currentSuites.push(suite);
|
|
84
|
+
this.suites[suite.uid] = suite;
|
|
85
|
+
this.onSuiteStart(suite);
|
|
86
|
+
});
|
|
87
|
+
this.on('hook:start', /* istanbul ignore next */ (hook) => {
|
|
88
|
+
const hookStats = new hook_js_1.default(hook);
|
|
89
|
+
const currentSuite = this.currentSuites[this.currentSuites.length - 1];
|
|
90
|
+
currentSuite.hooks.push(hookStats);
|
|
91
|
+
currentSuite.hooksAndTests.push(hookStats);
|
|
92
|
+
this.hooks[hook.uid] = hookStats;
|
|
93
|
+
this.onHookStart(hookStats);
|
|
94
|
+
});
|
|
95
|
+
this.on('hook:end', /* istanbul ignore next */ (hook) => {
|
|
96
|
+
const hookStats = this.hooks[hook.uid];
|
|
97
|
+
hookStats.complete((0, utils_js_1.getErrorsFromEvent)(hook));
|
|
98
|
+
this.counts.hooks++;
|
|
99
|
+
this.onHookEnd(hookStats);
|
|
100
|
+
});
|
|
101
|
+
this.on('test:start', /* istanbul ignore next */ (test) => {
|
|
102
|
+
test.retries = this.retries;
|
|
103
|
+
currentTest = new test_js_1.default(test);
|
|
104
|
+
const currentSuite = this.currentSuites[this.currentSuites.length - 1];
|
|
105
|
+
currentSuite.tests.push(currentTest);
|
|
106
|
+
currentSuite.hooksAndTests.push(currentTest);
|
|
107
|
+
this.tests[test.uid] = currentTest;
|
|
108
|
+
this.onTestStart(currentTest);
|
|
109
|
+
});
|
|
110
|
+
this.on('test:pass', /* istanbul ignore next */ (test) => {
|
|
111
|
+
const testStat = this.tests[test.uid];
|
|
112
|
+
testStat.pass();
|
|
113
|
+
this.counts.passes++;
|
|
114
|
+
this.counts.tests++;
|
|
115
|
+
this.onTestPass(testStat);
|
|
116
|
+
});
|
|
117
|
+
this.on('test:skip', (test) => {
|
|
118
|
+
const testStat = this.tests[test.uid];
|
|
119
|
+
currentTest.skip(test.pendingReason);
|
|
120
|
+
this.counts.skipping++;
|
|
121
|
+
this.counts.tests++;
|
|
122
|
+
this.onTestSkip(testStat);
|
|
123
|
+
});
|
|
124
|
+
this.on('test:fail', /* istanbul ignore next */ (test) => {
|
|
125
|
+
const testStat = this.tests[test.uid];
|
|
126
|
+
testStat.fail((0, utils_js_1.getErrorsFromEvent)(test));
|
|
127
|
+
this.counts.failures++;
|
|
128
|
+
this.counts.tests++;
|
|
129
|
+
this.onTestFail(testStat);
|
|
130
|
+
});
|
|
131
|
+
this.on('test:retry', (test) => {
|
|
132
|
+
const testStat = this.tests[test.uid];
|
|
133
|
+
testStat.fail((0, utils_js_1.getErrorsFromEvent)(test));
|
|
134
|
+
this.onTestRetry(testStat);
|
|
135
|
+
this.retries++;
|
|
136
|
+
});
|
|
137
|
+
this.on('test:pending', (test) => {
|
|
138
|
+
test.retries = this.retries;
|
|
139
|
+
const currentSuite = this.currentSuites[this.currentSuites.length - 1];
|
|
140
|
+
currentTest = new test_js_1.default(test);
|
|
141
|
+
/**
|
|
142
|
+
* In Mocha: tests that are skipped don't have a start event but a test end.
|
|
143
|
+
* In Jasmine: tests have a start event, therefore we need to replace the
|
|
144
|
+
* test instance with the pending test here
|
|
145
|
+
*/
|
|
146
|
+
if (test.uid in this.tests && this.tests[test.uid].state !== 'pending') {
|
|
147
|
+
currentTest.uid = test.uid in this.tests ? 'skipped-' + this.counts.skipping : currentTest.uid;
|
|
148
|
+
}
|
|
149
|
+
const suiteTests = currentSuite.tests;
|
|
150
|
+
if (!suiteTests.length || currentTest.uid !== suiteTests[suiteTests.length - 1].uid) {
|
|
151
|
+
currentSuite.tests.push(currentTest);
|
|
152
|
+
currentSuite.hooksAndTests.push(currentTest);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
suiteTests[suiteTests.length - 1] = currentTest;
|
|
156
|
+
currentSuite.hooksAndTests[currentSuite.hooksAndTests.length - 1] = currentTest;
|
|
157
|
+
}
|
|
158
|
+
this.tests[currentTest.uid] = currentTest;
|
|
159
|
+
currentTest.skip(test.pendingReason);
|
|
160
|
+
this.counts.skipping++;
|
|
161
|
+
this.counts.tests++;
|
|
162
|
+
this.onTestSkip(currentTest);
|
|
163
|
+
});
|
|
164
|
+
this.on('test:end', /* istanbul ignore next */ (test) => {
|
|
165
|
+
const testStat = this.tests[test.uid];
|
|
166
|
+
this.retries = 0;
|
|
167
|
+
this.onTestEnd(testStat);
|
|
168
|
+
});
|
|
169
|
+
this.on('suite:end', /* istanbul ignore next */ (suite) => {
|
|
170
|
+
const suiteStat = this.suites[suite.uid];
|
|
171
|
+
suiteStat.complete();
|
|
172
|
+
this.currentSuites.pop();
|
|
173
|
+
this.onSuiteEnd(suiteStat);
|
|
174
|
+
});
|
|
175
|
+
this.on('runner:end', /* istanbul ignore next */ (runner) => {
|
|
176
|
+
rootSuite.complete();
|
|
177
|
+
if (this.runnerStat) {
|
|
178
|
+
this.runnerStat.failures = runner.failures;
|
|
179
|
+
this.runnerStat.retries = runner.retries;
|
|
180
|
+
this.runnerStat.complete();
|
|
181
|
+
this.onRunnerEnd(this.runnerStat);
|
|
182
|
+
}
|
|
183
|
+
const logFile = this.options.logFile;
|
|
184
|
+
if (!this.isContentPresent && logFile && node_fs_1.default.existsSync(logFile)) {
|
|
185
|
+
node_fs_1.default.unlinkSync(logFile);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
/**
|
|
189
|
+
* browser client event handlers
|
|
190
|
+
*/
|
|
191
|
+
this.on('client:beforeCommand', /* istanbul ignore next */ (payload) => {
|
|
192
|
+
if (!currentTest) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
currentTest.output.push(Object.assign(payload, { type: 'command' }));
|
|
196
|
+
});
|
|
197
|
+
this.on('client:afterCommand', /* istanbul ignore next */ (payload) => {
|
|
198
|
+
if (!currentTest) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
currentTest.output.push(Object.assign(payload, { type: 'result' }));
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* allows reporter to stale process shutdown process until required sync work
|
|
206
|
+
* is done (e.g. when having to send data to some server or any other async work)
|
|
207
|
+
*/
|
|
208
|
+
get isSynchronised() {
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* function to write to reporters output stream
|
|
213
|
+
*/
|
|
214
|
+
write(content) {
|
|
215
|
+
if (content) {
|
|
216
|
+
this.isContentPresent = true;
|
|
217
|
+
}
|
|
218
|
+
this.outputStream.write(content);
|
|
219
|
+
}
|
|
220
|
+
/* istanbul ignore next */
|
|
221
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
222
|
+
onRunnerStart(runnerStats) { }
|
|
223
|
+
/* istanbul ignore next */
|
|
224
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
225
|
+
onBeforeCommand(commandArgs) { }
|
|
226
|
+
/* istanbul ignore next */
|
|
227
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
228
|
+
onAfterCommand(commandArgs) { }
|
|
229
|
+
/* istanbul ignore next */
|
|
230
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
231
|
+
onSuiteStart(suiteStats) { }
|
|
232
|
+
/* istanbul ignore next */
|
|
233
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
234
|
+
onHookStart(hookStat) { }
|
|
235
|
+
/* istanbul ignore next */
|
|
236
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
237
|
+
onHookEnd(hookStats) { }
|
|
238
|
+
/* istanbul ignore next */
|
|
239
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
240
|
+
onTestStart(testStats) { }
|
|
241
|
+
/* istanbul ignore next */
|
|
242
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
243
|
+
onTestPass(testStats) { }
|
|
244
|
+
/* istanbul ignore next */
|
|
245
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
246
|
+
onTestFail(testStats) { }
|
|
247
|
+
/* istanbul ignore next */
|
|
248
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
249
|
+
onTestRetry(testStats) { }
|
|
250
|
+
/* istanbul ignore next */
|
|
251
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
252
|
+
onTestSkip(testStats) { }
|
|
253
|
+
/* istanbul ignore next */
|
|
254
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
255
|
+
onTestEnd(testStats) { }
|
|
256
|
+
/* istanbul ignore next */
|
|
257
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
258
|
+
onSuiteEnd(suiteStats) { }
|
|
259
|
+
/* istanbul ignore next */
|
|
260
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
261
|
+
onRunnerEnd(runnerStats) { }
|
|
262
|
+
}
|
|
263
|
+
exports.default = WDIOReporter;
|
package/cjs/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const runnable_js_1 = __importDefault(require("./runnable.js"));
|
|
7
|
+
class HookStats extends runnable_js_1.default {
|
|
8
|
+
uid;
|
|
9
|
+
cid;
|
|
10
|
+
title;
|
|
11
|
+
parent;
|
|
12
|
+
// Mocha only
|
|
13
|
+
body;
|
|
14
|
+
errors;
|
|
15
|
+
error;
|
|
16
|
+
state;
|
|
17
|
+
currentTest;
|
|
18
|
+
constructor(runner) {
|
|
19
|
+
super('hook');
|
|
20
|
+
this.uid = runnable_js_1.default.getIdentifier(runner);
|
|
21
|
+
this.cid = runner.cid;
|
|
22
|
+
this.title = runner.title;
|
|
23
|
+
this.parent = runner.parent;
|
|
24
|
+
this.currentTest = runner.currentTest;
|
|
25
|
+
this.body = runner.body;
|
|
26
|
+
}
|
|
27
|
+
complete(errors) {
|
|
28
|
+
this.errors = errors;
|
|
29
|
+
if (errors && errors.length) {
|
|
30
|
+
this.error = errors[0];
|
|
31
|
+
this.state = 'failed';
|
|
32
|
+
}
|
|
33
|
+
super.complete();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.default = HookStats;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Main class for a runnable class (e.g. test, suite or a hook)
|
|
5
|
+
* mainly used to capture its running duration
|
|
6
|
+
*/
|
|
7
|
+
class RunnableStats {
|
|
8
|
+
type;
|
|
9
|
+
start = new Date();
|
|
10
|
+
end;
|
|
11
|
+
_duration = 0;
|
|
12
|
+
constructor(type) {
|
|
13
|
+
this.type = type;
|
|
14
|
+
}
|
|
15
|
+
complete() {
|
|
16
|
+
this.end = new Date();
|
|
17
|
+
this._duration = this.end.getTime() - this.start.getTime();
|
|
18
|
+
}
|
|
19
|
+
get duration() {
|
|
20
|
+
if (this.end) {
|
|
21
|
+
return this._duration;
|
|
22
|
+
}
|
|
23
|
+
return new Date().getTime() - this.start.getTime();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* ToDo: we should always rely on uid
|
|
27
|
+
*/
|
|
28
|
+
static getIdentifier(runner) {
|
|
29
|
+
return runner.uid || runner.title;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.default = RunnableStats;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const runnable_js_1 = __importDefault(require("./runnable.js"));
|
|
7
|
+
const utils_js_1 = require("../utils.js");
|
|
8
|
+
/**
|
|
9
|
+
* Class to capture statistics about a test run. A test run is a single instance that
|
|
10
|
+
* runs one or more spec files
|
|
11
|
+
*/
|
|
12
|
+
class RunnerStats extends runnable_js_1.default {
|
|
13
|
+
cid;
|
|
14
|
+
capabilities;
|
|
15
|
+
sanitizedCapabilities;
|
|
16
|
+
config;
|
|
17
|
+
specs;
|
|
18
|
+
sessionId;
|
|
19
|
+
isMultiremote;
|
|
20
|
+
instanceOptions;
|
|
21
|
+
retry;
|
|
22
|
+
failures;
|
|
23
|
+
retries;
|
|
24
|
+
constructor(runner) {
|
|
25
|
+
super('runner');
|
|
26
|
+
this.cid = runner.cid;
|
|
27
|
+
this.capabilities = runner.capabilities;
|
|
28
|
+
this.sanitizedCapabilities = (0, utils_js_1.sanitizeCaps)(runner.capabilities);
|
|
29
|
+
this.config = runner.config;
|
|
30
|
+
this.specs = runner.specs;
|
|
31
|
+
this.sessionId = runner.sessionId;
|
|
32
|
+
this.isMultiremote = runner.isMultiremote;
|
|
33
|
+
this.instanceOptions = runner.instanceOptions;
|
|
34
|
+
this.retry = runner.retry;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.default = RunnerStats;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const runnable_js_1 = __importDefault(require("./runnable.js"));
|
|
7
|
+
/**
|
|
8
|
+
* Class describing statistics about a single suite.
|
|
9
|
+
*/
|
|
10
|
+
class SuiteStats extends runnable_js_1.default {
|
|
11
|
+
uid;
|
|
12
|
+
cid;
|
|
13
|
+
file;
|
|
14
|
+
title;
|
|
15
|
+
fullTitle;
|
|
16
|
+
tags;
|
|
17
|
+
tests = [];
|
|
18
|
+
hooks = [];
|
|
19
|
+
suites = [];
|
|
20
|
+
parent;
|
|
21
|
+
/**
|
|
22
|
+
* an array of hooks and tests stored in order as they happen
|
|
23
|
+
*/
|
|
24
|
+
hooksAndTests = [];
|
|
25
|
+
description;
|
|
26
|
+
rule;
|
|
27
|
+
constructor(suite) {
|
|
28
|
+
super(suite.type || 'suite');
|
|
29
|
+
this.uid = runnable_js_1.default.getIdentifier(suite);
|
|
30
|
+
this.cid = suite.cid;
|
|
31
|
+
this.file = suite.file;
|
|
32
|
+
this.title = suite.title;
|
|
33
|
+
this.fullTitle = suite.fullTitle;
|
|
34
|
+
this.tags = suite.tags;
|
|
35
|
+
this.parent = suite.parent;
|
|
36
|
+
/**
|
|
37
|
+
* only Cucumber
|
|
38
|
+
*/
|
|
39
|
+
this.description = suite.description;
|
|
40
|
+
this.rule = suite.rule;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.default = SuiteStats;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_util_1 = require("node:util");
|
|
7
|
+
const diff_1 = require("diff");
|
|
8
|
+
const object_inspect_1 = __importDefault(require("object-inspect"));
|
|
9
|
+
const runnable_js_1 = __importDefault(require("./runnable.js"));
|
|
10
|
+
const utils_js_1 = require("../utils.js");
|
|
11
|
+
const maxStringLength = 2048;
|
|
12
|
+
/**
|
|
13
|
+
* TestStats class
|
|
14
|
+
* captures data on a test.
|
|
15
|
+
*/
|
|
16
|
+
class TestStats extends runnable_js_1.default {
|
|
17
|
+
uid;
|
|
18
|
+
cid;
|
|
19
|
+
title;
|
|
20
|
+
currentTest;
|
|
21
|
+
fullTitle;
|
|
22
|
+
output;
|
|
23
|
+
argument;
|
|
24
|
+
retries;
|
|
25
|
+
parent;
|
|
26
|
+
/**
|
|
27
|
+
* initial test state is pending
|
|
28
|
+
* the state can change to the following: passed, skipped, failed
|
|
29
|
+
*/
|
|
30
|
+
state;
|
|
31
|
+
pendingReason;
|
|
32
|
+
errors;
|
|
33
|
+
error;
|
|
34
|
+
body;
|
|
35
|
+
constructor(test) {
|
|
36
|
+
super('test');
|
|
37
|
+
this.uid = runnable_js_1.default.getIdentifier(test);
|
|
38
|
+
this.cid = test.cid;
|
|
39
|
+
this.title = test.title;
|
|
40
|
+
this.fullTitle = test.fullTitle;
|
|
41
|
+
this.output = [];
|
|
42
|
+
this.argument = test.argument;
|
|
43
|
+
this.retries = test.retries;
|
|
44
|
+
this.parent = test.parent;
|
|
45
|
+
// Mocha only
|
|
46
|
+
this.body = test.body;
|
|
47
|
+
/**
|
|
48
|
+
* initial test state is pending
|
|
49
|
+
* the state can change to the following: passed, skipped, failed
|
|
50
|
+
*/
|
|
51
|
+
this.state = 'pending';
|
|
52
|
+
}
|
|
53
|
+
pass() {
|
|
54
|
+
this.complete();
|
|
55
|
+
this.state = 'passed';
|
|
56
|
+
}
|
|
57
|
+
skip(reason) {
|
|
58
|
+
this.pendingReason = reason;
|
|
59
|
+
this.state = 'skipped';
|
|
60
|
+
}
|
|
61
|
+
fail(errors) {
|
|
62
|
+
this.complete();
|
|
63
|
+
this.state = 'failed';
|
|
64
|
+
/**
|
|
65
|
+
* Iterates through all errors to check if they're a type of 'AssertionError',
|
|
66
|
+
* and formats it if so. Otherwise, just leaves error as is
|
|
67
|
+
*/
|
|
68
|
+
const formattedErrors = errors?.map((err) => (
|
|
69
|
+
/**
|
|
70
|
+
* only format if error object has either an "expected" or "actual" property set
|
|
71
|
+
*/
|
|
72
|
+
((err.expected || err.actual) && !node_util_1.types.isProxy(err.actual)) &&
|
|
73
|
+
/**
|
|
74
|
+
* and if they aren't already formated, e.g. in Jasmine
|
|
75
|
+
*/
|
|
76
|
+
(err.message && !err.message.includes('Expected: ') && !err.message.includes('Received: '))
|
|
77
|
+
? this._stringifyDiffObjs(err)
|
|
78
|
+
: err));
|
|
79
|
+
this.errors = formattedErrors;
|
|
80
|
+
if (formattedErrors && formattedErrors.length) {
|
|
81
|
+
this.error = formattedErrors[0];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
_stringifyDiffObjs(err) {
|
|
85
|
+
const inspectOpts = { maxStringLength };
|
|
86
|
+
const expected = (0, object_inspect_1.default)(err.expected, inspectOpts);
|
|
87
|
+
const actual = (0, object_inspect_1.default)(err.actual, inspectOpts);
|
|
88
|
+
let msg = (0, diff_1.diffWordsWithSpace)(actual, expected)
|
|
89
|
+
.map((str) => (str.added
|
|
90
|
+
? (0, utils_js_1.colorLines)('diff added inline', str.value)
|
|
91
|
+
: str.removed
|
|
92
|
+
? (0, utils_js_1.colorLines)('diff removed inline', str.value)
|
|
93
|
+
: str.value))
|
|
94
|
+
.join('');
|
|
95
|
+
// linenos
|
|
96
|
+
const lines = msg.split('\n');
|
|
97
|
+
if (lines.length > 4) {
|
|
98
|
+
const width = String(lines.length).length;
|
|
99
|
+
msg = lines
|
|
100
|
+
.map(function (str, i) {
|
|
101
|
+
return (0, utils_js_1.pad)(String(++i), width) + ' |' + ' ' + str;
|
|
102
|
+
})
|
|
103
|
+
.join('\n');
|
|
104
|
+
}
|
|
105
|
+
// legend
|
|
106
|
+
msg = `\n${(0, utils_js_1.color)('diff removed inline', 'actual')} ${(0, utils_js_1.color)('diff added inline', 'expected')}\n\n${msg}\n`;
|
|
107
|
+
// indent
|
|
108
|
+
msg = msg.replace(/^/gm, ' ');
|
|
109
|
+
const newError = new Error(err.message + msg);
|
|
110
|
+
newError.stack = err.stack;
|
|
111
|
+
return newError;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.default = TestStats;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* original source: https://github.com/chalk/supports-color/blob/d4f413efaf8da045c5ab440ed418ef02dbb28bf1/index.js
|
|
4
|
+
*
|
|
5
|
+
* This file was imported due to lacking support of CJS environments in the original package.
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.createSupportsColor = void 0;
|
|
12
|
+
const node_process_1 = __importDefault(require("node:process"));
|
|
13
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
14
|
+
const node_tty_1 = __importDefault(require("node:tty"));
|
|
15
|
+
// From: https://github.com/sindresorhus/has-flag/blob/main/index.js
|
|
16
|
+
/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {
|
|
17
|
+
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : node_process_1.default.argv) {
|
|
18
|
+
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
|
|
19
|
+
const position = argv.indexOf(prefix + flag);
|
|
20
|
+
const terminatorPosition = argv.indexOf('--');
|
|
21
|
+
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
22
|
+
}
|
|
23
|
+
const { env } = node_process_1.default;
|
|
24
|
+
let flagForceColor;
|
|
25
|
+
if (hasFlag('no-color')
|
|
26
|
+
|| hasFlag('no-colors')
|
|
27
|
+
|| hasFlag('color=false')
|
|
28
|
+
|| hasFlag('color=never')) {
|
|
29
|
+
flagForceColor = 0;
|
|
30
|
+
}
|
|
31
|
+
else if (hasFlag('color')
|
|
32
|
+
|| hasFlag('colors')
|
|
33
|
+
|| hasFlag('color=true')
|
|
34
|
+
|| hasFlag('color=always')) {
|
|
35
|
+
flagForceColor = 1;
|
|
36
|
+
}
|
|
37
|
+
function envForceColor() {
|
|
38
|
+
if ('FORCE_COLOR' in env) {
|
|
39
|
+
if (env.FORCE_COLOR === 'true') {
|
|
40
|
+
return 1;
|
|
41
|
+
}
|
|
42
|
+
if (env.FORCE_COLOR === 'false') {
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function translateLevel(level) {
|
|
49
|
+
if (level === 0) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
level,
|
|
54
|
+
hasBasic: true,
|
|
55
|
+
has256: level >= 2,
|
|
56
|
+
has16m: level >= 3,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
60
|
+
const noFlagForceColor = envForceColor();
|
|
61
|
+
if (noFlagForceColor !== undefined) {
|
|
62
|
+
flagForceColor = noFlagForceColor;
|
|
63
|
+
}
|
|
64
|
+
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
65
|
+
if (forceColor === 0) {
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
if (sniffFlags) {
|
|
69
|
+
if (hasFlag('color=16m')
|
|
70
|
+
|| hasFlag('color=full')
|
|
71
|
+
|| hasFlag('color=truecolor')) {
|
|
72
|
+
return 3;
|
|
73
|
+
}
|
|
74
|
+
if (hasFlag('color=256')) {
|
|
75
|
+
return 2;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Check for Azure DevOps pipelines.
|
|
79
|
+
// Has to be above the `!streamIsTTY` check.
|
|
80
|
+
if ('TF_BUILD' in env && 'AGENT_NAME' in env) {
|
|
81
|
+
return 1;
|
|
82
|
+
}
|
|
83
|
+
if (haveStream && !streamIsTTY && forceColor === undefined) {
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
const min = forceColor || 0;
|
|
87
|
+
if (env.TERM === 'dumb') {
|
|
88
|
+
return min;
|
|
89
|
+
}
|
|
90
|
+
if (node_process_1.default.platform === 'win32') {
|
|
91
|
+
// Windows 10 build 10586 is the first Windows release that supports 256 colors.
|
|
92
|
+
// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
|
|
93
|
+
const osRelease = node_os_1.default.release().split('.');
|
|
94
|
+
if (Number(osRelease[0]) >= 10
|
|
95
|
+
&& Number(osRelease[2]) >= 10586) {
|
|
96
|
+
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
97
|
+
}
|
|
98
|
+
return 1;
|
|
99
|
+
}
|
|
100
|
+
if ('CI' in env) {
|
|
101
|
+
if ('GITHUB_ACTIONS' in env || 'GITEA_ACTIONS' in env) {
|
|
102
|
+
return 3;
|
|
103
|
+
}
|
|
104
|
+
if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
|
|
105
|
+
return 1;
|
|
106
|
+
}
|
|
107
|
+
return min;
|
|
108
|
+
}
|
|
109
|
+
if ('TEAMCITY_VERSION' in env) {
|
|
110
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
111
|
+
}
|
|
112
|
+
if (env.COLORTERM === 'truecolor') {
|
|
113
|
+
return 3;
|
|
114
|
+
}
|
|
115
|
+
if (env.TERM === 'xterm-kitty') {
|
|
116
|
+
return 3;
|
|
117
|
+
}
|
|
118
|
+
if ('TERM_PROGRAM' in env) {
|
|
119
|
+
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
|
|
120
|
+
switch (env.TERM_PROGRAM) {
|
|
121
|
+
case 'iTerm.app': {
|
|
122
|
+
return version >= 3 ? 3 : 2;
|
|
123
|
+
}
|
|
124
|
+
case 'Apple_Terminal': {
|
|
125
|
+
return 2;
|
|
126
|
+
}
|
|
127
|
+
// No default
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (env.TERM && /-256(color)?$/i.test(env.TERM)) {
|
|
131
|
+
return 2;
|
|
132
|
+
}
|
|
133
|
+
if (env.TERM && /^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
134
|
+
return 1;
|
|
135
|
+
}
|
|
136
|
+
if ('COLORTERM' in env) {
|
|
137
|
+
return 1;
|
|
138
|
+
}
|
|
139
|
+
return min;
|
|
140
|
+
}
|
|
141
|
+
function createSupportsColor(stream, options = {}) {
|
|
142
|
+
const level = _supportsColor(stream, {
|
|
143
|
+
streamIsTTY: stream && stream.isTTY,
|
|
144
|
+
...options,
|
|
145
|
+
});
|
|
146
|
+
return translateLevel(level);
|
|
147
|
+
}
|
|
148
|
+
exports.createSupportsColor = createSupportsColor;
|
|
149
|
+
const supportsColor = {
|
|
150
|
+
stdout: createSupportsColor({ isTTY: node_tty_1.default.isatty(1) }),
|
|
151
|
+
stderr: createSupportsColor({ isTTY: node_tty_1.default.isatty(2) }),
|
|
152
|
+
};
|
|
153
|
+
exports.default = supportsColor;
|
package/cjs/types.js
ADDED
package/cjs/utils.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.colorLines = exports.color = exports.pad = exports.getErrorsFromEvent = exports.sanitizeCaps = exports.sanitizeString = void 0;
|
|
7
|
+
const supportsColor_js_1 = __importDefault(require("./supportsColor.js"));
|
|
8
|
+
const constants_js_1 = require("./constants.js");
|
|
9
|
+
/**
|
|
10
|
+
* replaces whitespaces with underscore and removes dots
|
|
11
|
+
* @param {string} str variable to sanitize
|
|
12
|
+
* @return {String} sanitized variable
|
|
13
|
+
*/
|
|
14
|
+
function sanitizeString(str) {
|
|
15
|
+
if (!str) {
|
|
16
|
+
return '';
|
|
17
|
+
}
|
|
18
|
+
return String(str)
|
|
19
|
+
.replace(/^.*\/([^/]+)\/?$/, '$1')
|
|
20
|
+
.replace(/\./g, '_')
|
|
21
|
+
.replace(/\s/g, '')
|
|
22
|
+
.toLowerCase();
|
|
23
|
+
}
|
|
24
|
+
exports.sanitizeString = sanitizeString;
|
|
25
|
+
/**
|
|
26
|
+
* formats capability object into sanitized string for e.g.filenames
|
|
27
|
+
* @param {object} caps Selenium capabilities
|
|
28
|
+
*/
|
|
29
|
+
function sanitizeCaps(caps) {
|
|
30
|
+
if (!caps) {
|
|
31
|
+
return '';
|
|
32
|
+
}
|
|
33
|
+
let result;
|
|
34
|
+
/**
|
|
35
|
+
* mobile caps
|
|
36
|
+
*/
|
|
37
|
+
result = caps.deviceName
|
|
38
|
+
? [
|
|
39
|
+
sanitizeString(caps.platformName),
|
|
40
|
+
sanitizeString(caps.deviceName || caps['appium:deviceName']),
|
|
41
|
+
sanitizeString(caps['appium:platformVersion']),
|
|
42
|
+
sanitizeString(caps['appium:app'])
|
|
43
|
+
]
|
|
44
|
+
: [
|
|
45
|
+
sanitizeString(caps.browserName),
|
|
46
|
+
sanitizeString(caps.version || caps.browserVersion),
|
|
47
|
+
sanitizeString(caps.platform || caps.platformName),
|
|
48
|
+
sanitizeString(caps['appium:app'])
|
|
49
|
+
];
|
|
50
|
+
result = result.filter(n => n !== undefined && n !== '');
|
|
51
|
+
return result.join('.');
|
|
52
|
+
}
|
|
53
|
+
exports.sanitizeCaps = sanitizeCaps;
|
|
54
|
+
/**
|
|
55
|
+
* Takes a event emitted by a framework and extracts
|
|
56
|
+
* an array of errors representing test or hook failures.
|
|
57
|
+
* This exists to maintain compatibility between frameworks
|
|
58
|
+
* with have a soft assertion model (Jasmine) and those that
|
|
59
|
+
* have a hard assertion model (Mocha)
|
|
60
|
+
* @param {*} e An event emitted by a framework adapter
|
|
61
|
+
*/
|
|
62
|
+
function getErrorsFromEvent(e) {
|
|
63
|
+
if (e.errors) {
|
|
64
|
+
return e.errors;
|
|
65
|
+
}
|
|
66
|
+
if (e.error) {
|
|
67
|
+
return [e.error];
|
|
68
|
+
}
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
exports.getErrorsFromEvent = getErrorsFromEvent;
|
|
72
|
+
/**
|
|
73
|
+
* Pads the given `str` to `len`.
|
|
74
|
+
*
|
|
75
|
+
* @private
|
|
76
|
+
* @param {string} str
|
|
77
|
+
* @param {number} len
|
|
78
|
+
* @return {string}
|
|
79
|
+
*/
|
|
80
|
+
function pad(str, len) {
|
|
81
|
+
return Array(len - str.length + 1).join(' ') + str;
|
|
82
|
+
}
|
|
83
|
+
exports.pad = pad;
|
|
84
|
+
function color(type, content) {
|
|
85
|
+
if (!supportsColor_js_1.default.stdout) {
|
|
86
|
+
return String(content);
|
|
87
|
+
}
|
|
88
|
+
return `\u001b[${constants_js_1.COLORS[type]}m${content}\u001b[0m`;
|
|
89
|
+
}
|
|
90
|
+
exports.color = color;
|
|
91
|
+
/**
|
|
92
|
+
* Colors lines for `str`, using the color `name`.
|
|
93
|
+
*
|
|
94
|
+
* @private
|
|
95
|
+
* @param {string} name
|
|
96
|
+
* @param {string} str
|
|
97
|
+
* @return {string}
|
|
98
|
+
*/
|
|
99
|
+
function colorLines(name, str) {
|
|
100
|
+
return str
|
|
101
|
+
.split('\n')
|
|
102
|
+
.map((str) => color(name, str))
|
|
103
|
+
.join('\n');
|
|
104
|
+
}
|
|
105
|
+
exports.colorLines = colorLines;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/reporter",
|
|
3
|
-
"version": "8.15.
|
|
3
|
+
"version": "8.15.7",
|
|
4
4
|
"description": "A WebdriverIO utility to help reporting all events",
|
|
5
5
|
"author": "Christian Bromann <mail@bromann.dev>",
|
|
6
6
|
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-reporter",
|
|
@@ -25,19 +25,27 @@
|
|
|
25
25
|
"access": "public"
|
|
26
26
|
},
|
|
27
27
|
"type": "module",
|
|
28
|
+
"main": "./cjs/index.js",
|
|
29
|
+
"module": "./build/index.js",
|
|
28
30
|
"types": "./build/index.d.ts",
|
|
29
31
|
"exports": {
|
|
30
|
-
".": "./
|
|
31
|
-
"
|
|
32
|
+
"./package.json": "./package.json",
|
|
33
|
+
".": [
|
|
34
|
+
{
|
|
35
|
+
"types": "./build/index.d.ts",
|
|
36
|
+
"import": "./build/index.js",
|
|
37
|
+
"require": "./cjs/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./cjs/index.js"
|
|
40
|
+
]
|
|
32
41
|
},
|
|
33
42
|
"typeScriptVersion": "3.8.3",
|
|
34
43
|
"dependencies": {
|
|
35
44
|
"@types/node": "^20.1.0",
|
|
36
45
|
"@wdio/logger": "8.11.0",
|
|
37
|
-
"@wdio/types": "8.15.
|
|
46
|
+
"@wdio/types": "8.15.7",
|
|
38
47
|
"diff": "^5.0.0",
|
|
39
|
-
"object-inspect": "^1.12.0"
|
|
40
|
-
"supports-color": "9.4.0"
|
|
48
|
+
"object-inspect": "^1.12.0"
|
|
41
49
|
},
|
|
42
50
|
"devDependencies": {
|
|
43
51
|
"@types/diff": "^5.0.2",
|
|
@@ -46,5 +54,5 @@
|
|
|
46
54
|
"@types/tmp": "^0.2.3",
|
|
47
55
|
"tmp": "^0.2.1"
|
|
48
56
|
},
|
|
49
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "24d8f0dccf54e6e19779094d73eb90ae9086ee86"
|
|
50
58
|
}
|