@wdio/runner 7.16.16 → 7.17.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wdio/runner",
3
- "version": "7.16.16",
3
+ "version": "7.17.0",
4
4
  "description": "A WebdriverIO service that runs tests in arbitrary environments",
5
5
  "author": "Christian Bromann <christian@saucelabs.com>",
6
6
  "homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-runner",
@@ -25,14 +25,14 @@
25
25
  "@wdio/config": "7.16.16",
26
26
  "@wdio/logger": "7.16.0",
27
27
  "@wdio/types": "7.16.14",
28
- "@wdio/utils": "7.16.14",
28
+ "@wdio/utils": "7.17.0",
29
29
  "deepmerge": "^4.0.0",
30
30
  "gaze": "^1.1.2",
31
- "webdriver": "7.16.16",
32
- "webdriverio": "7.16.16"
31
+ "webdriver": "7.17.0",
32
+ "webdriverio": "7.17.0"
33
33
  },
34
34
  "publishConfig": {
35
35
  "access": "public"
36
36
  },
37
- "gitHead": "10597a2afe43b2f64ed9bf0ddae3f3f77d280047"
37
+ "gitHead": "e18d2cde6ff979758830bdff4c3bc82ca9818b24"
38
38
  }
package/build/index.d.ts DELETED
@@ -1,86 +0,0 @@
1
- /// <reference types="node" />
2
- import { EventEmitter } from 'events';
3
- import type { Options, Capabilities } from '@wdio/types';
4
- /**
5
- * user types for globals are set in webdriverio
6
- * putting this here to make compiler happy
7
- */
8
- declare global {
9
- namespace NodeJS {
10
- interface Global {
11
- $: any;
12
- $$: any;
13
- browser: any;
14
- driver: any;
15
- multiremotebrowser: any;
16
- }
17
- }
18
- }
19
- interface Args extends Partial<Options.Testrunner> {
20
- ignoredWorkerServices?: string[];
21
- watch?: boolean;
22
- }
23
- declare type RunParams = {
24
- cid: string;
25
- args: Args;
26
- specs: string[];
27
- caps: Capabilities.RemoteCapability;
28
- configFile: string;
29
- retries: number;
30
- };
31
- declare global {
32
- var _HAS_FIBER_CONTEXT: boolean;
33
- }
34
- export default class Runner extends EventEmitter {
35
- private _configParser;
36
- private _sigintWasCalled;
37
- private _isMultiremote;
38
- private _specFileRetryAttempts;
39
- private _reporter?;
40
- private _framework?;
41
- private _config?;
42
- private _cid?;
43
- private _specs?;
44
- private _caps?;
45
- /**
46
- * run test suite
47
- * @param {String} cid worker id (e.g. `0-0`)
48
- * @param {Object} args config arguments passed into worker process
49
- * @param {String[]} specs list of spec files to run
50
- * @param {Object} caps capabilities to run session with
51
- * @param {String} configFile path to config file to get config from
52
- * @param {Number} retries number of retries remaining
53
- * @return {Promise} resolves in number of failures for testrun
54
- */
55
- run({ cid, args, specs, caps, configFile, retries }: RunParams): Promise<number>;
56
- /**
57
- * init protocol session
58
- * @param {object} config configuration of sessions
59
- * @param {Object} caps desired capabilities of session
60
- * @param {Object} browserStub stubbed `browser` object with only capabilities, config and env flags
61
- * @return {Promise} resolves with browser object or null if session couldn't get established
62
- */
63
- private _initSession;
64
- /**
65
- * start protocol session
66
- * @param {object} config configuration of sessions
67
- * @param {Object} caps desired capabilities of session
68
- * @return {Promise} resolves with browser object or null if session couldn't get established
69
- */
70
- private _startSession;
71
- /**
72
- * fetch logs provided by browser driver
73
- */
74
- private _fetchDriverLogs;
75
- /**
76
- * kill worker session
77
- */
78
- private _shutdown;
79
- /**
80
- * end WebDriver session, a config object can be applied if object has changed
81
- * within a hook by the user
82
- */
83
- endSession(): Promise<void>;
84
- }
85
- export {};
86
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAKrC,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAY,MAAM,aAAa,CAAA;AAalE;;;GAGG;AACH,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM,CAAC;QACb,UAAU,MAAM;YACZ,CAAC,EAAE,GAAG,CAAA;YACN,EAAE,EAAE,GAAG,CAAA;YACP,OAAO,EAAE,GAAG,CAAA;YACZ,MAAM,EAAE,GAAG,CAAA;YACX,kBAAkB,EAAE,GAAG,CAAA;SAC1B;KACJ;CACJ;AAED,UAAU,IAAK,SAAQ,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC;IAC9C,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAA;IAChC,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,aAAK,SAAS,GAAG;IACb,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,IAAI,CAAA;IACV,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAA;IACnC,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;CAClB,CAAA;AAmBD,OAAO,CAAC,MAAM,CAAC;IACX,IAAI,kBAAkB,EAAE,OAAO,CAAA;CAClC;AAED,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,YAAY;IAC5C,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,sBAAsB,CAAI;IAElC,OAAO,CAAC,SAAS,CAAC,CAAc;IAChC,OAAO,CAAC,UAAU,CAAC,CAAe;IAClC,OAAO,CAAC,OAAO,CAAC,CAAoB;IACpC,OAAO,CAAC,IAAI,CAAC,CAAQ;IACrB,OAAO,CAAC,MAAM,CAAC,CAAU;IACzB,OAAO,CAAC,KAAK,CAAC,CAA+B;IAE7C;;;;;;;;;OASG;IACG,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,SAAS;IA0JpE;;;;;;OAMG;YACW,YAAY;IA+C1B;;;;;OAKG;YACW,aAAa;IA0B3B;;OAEG;YACW,gBAAgB;IAoE9B;;OAEG;YACW,SAAS;IAkBvB;;;OAGG;IACG,UAAU;CAmDnB"}
package/build/index.js DELETED
@@ -1,366 +0,0 @@
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 fs_1 = __importDefault(require("fs"));
7
- const path_1 = __importDefault(require("path"));
8
- const util_1 = __importDefault(require("util"));
9
- const events_1 = require("events");
10
- const logger_1 = __importDefault(require("@wdio/logger"));
11
- const utils_1 = require("@wdio/utils");
12
- const config_1 = require("@wdio/config");
13
- const reporter_1 = __importDefault(require("./reporter"));
14
- const utils_2 = require("./utils");
15
- const log = (0, logger_1.default)('@wdio/runner');
16
- class Runner extends events_1.EventEmitter {
17
- constructor() {
18
- super(...arguments);
19
- this._configParser = new config_1.ConfigParser();
20
- this._sigintWasCalled = false;
21
- this._isMultiremote = false;
22
- this._specFileRetryAttempts = 0;
23
- }
24
- /**
25
- * run test suite
26
- * @param {String} cid worker id (e.g. `0-0`)
27
- * @param {Object} args config arguments passed into worker process
28
- * @param {String[]} specs list of spec files to run
29
- * @param {Object} caps capabilities to run session with
30
- * @param {String} configFile path to config file to get config from
31
- * @param {Number} retries number of retries remaining
32
- * @return {Promise} resolves in number of failures for testrun
33
- */
34
- async run({ cid, args, specs, caps, configFile, retries }) {
35
- var _a;
36
- this._cid = cid;
37
- this._specs = specs;
38
- this._caps = caps;
39
- /**
40
- * autocompile after parsing configs so we support ES6 features in tests with config driven by users
41
- */
42
- if ((_a = args.autoCompileOpts) === null || _a === void 0 ? void 0 : _a.autoCompile) {
43
- this._configParser.merge({ autoCompileOpts: args.autoCompileOpts });
44
- this._configParser.autoCompile();
45
- }
46
- /**
47
- * add config file
48
- */
49
- try {
50
- this._configParser.addConfigFile(configFile);
51
- }
52
- catch (err) {
53
- return this._shutdown(1, retries);
54
- }
55
- /**
56
- * merge cli arguments again as some might have been overwritten by the config
57
- */
58
- this._configParser.merge(args);
59
- this._config = this._configParser.getConfig();
60
- this._specFileRetryAttempts = (this._config.specFileRetries || 0) - (retries || 0);
61
- logger_1.default.setLogLevelsConfig(this._config.logLevels, this._config.logLevel);
62
- const isMultiremote = this._isMultiremote = !Array.isArray(this._configParser.getCapabilities());
63
- /**
64
- * create `browser` stub only if `specFiltering` feature is enabled
65
- */
66
- let browser = await this._startSession({
67
- ...this._config,
68
- // @ts-ignore used in `/packages/webdriverio/src/protocol-stub.ts`
69
- _automationProtocol: this._config.automationProtocol,
70
- automationProtocol: './protocol-stub'
71
- }, caps);
72
- /**
73
- * run `beforeSession` command before framework and browser are initiated
74
- */
75
- (0, utils_1.initialiseWorkerService)(this._config, caps, args.ignoredWorkerServices).map(this._configParser.addService.bind(this._configParser));
76
- const beforeSessionParams = [this._config, this._caps, this._specs, this._cid];
77
- await (0, utils_1.executeHooksWithArgs)('beforeSession', this._config.beforeSession, beforeSessionParams);
78
- this._reporter = new reporter_1.default(this._config, this._cid, { ...caps });
79
- /**
80
- * initialise framework
81
- */
82
- this._framework = (0, utils_1.initialisePlugin)(this._config.framework, 'framework').default;
83
- this._framework = await this._framework.init(cid, this._config, specs, caps, this._reporter);
84
- process.send({ name: 'testFrameworkInit', content: { cid, caps, specs, hasTests: this._framework.hasTests() } });
85
- if (!this._framework.hasTests()) {
86
- return this._shutdown(0, retries);
87
- }
88
- browser = await this._initSession(this._config, this._caps, browser);
89
- /**
90
- * return if session initialisation failed
91
- */
92
- if (!browser) {
93
- const afterArgs = [1, this._caps, this._specs];
94
- await (0, utils_1.executeHooksWithArgs)('after', this._config.after, afterArgs);
95
- return this._shutdown(1, retries);
96
- }
97
- this._reporter.caps = browser.capabilities;
98
- const beforeArgs = [this._caps, this._specs, browser];
99
- await (0, utils_1.executeHooksWithArgs)('before', this._config.before, beforeArgs);
100
- /**
101
- * kill session of SIGINT signal showed up while trying to
102
- * get a session ID
103
- */
104
- if (this._sigintWasCalled) {
105
- log.info('SIGINT signal detected while starting session, shutting down...');
106
- await this.endSession();
107
- return this._shutdown(0, retries);
108
- }
109
- /**
110
- * initialisation successful, send start message
111
- */
112
- const multiRemoteBrowser = browser;
113
- this._reporter.emit('runner:start', {
114
- cid,
115
- specs,
116
- config: browser.options,
117
- isMultiremote,
118
- instanceOptions: isMultiremote
119
- ? multiRemoteBrowser.instances.reduce((prev, browserName) => {
120
- prev[multiRemoteBrowser[browserName].sessionId] = multiRemoteBrowser[browserName].options;
121
- return prev;
122
- }, {})
123
- : {
124
- [browser.sessionId]: browser.options
125
- },
126
- sessionId: browser.sessionId,
127
- capabilities: isMultiremote
128
- ? multiRemoteBrowser.instances.reduce((caps, browserName) => {
129
- caps[browserName] = multiRemoteBrowser[browserName].capabilities;
130
- caps[browserName].sessionId = multiRemoteBrowser[browserName].sessionId;
131
- return caps;
132
- }, {})
133
- : { ...browser.capabilities, sessionId: browser.sessionId },
134
- retry: this._specFileRetryAttempts
135
- });
136
- /**
137
- * report sessionId and target connection information to worker
138
- */
139
- const { protocol, hostname, port, path, queryParams } = browser.options;
140
- const { isW3C, sessionId } = browser;
141
- const instances = (0, utils_2.getInstancesData)(browser, isMultiremote);
142
- process.send({
143
- origin: 'worker',
144
- name: 'sessionStarted',
145
- content: { sessionId, isW3C, protocol, hostname, port, path, queryParams, isMultiremote, instances }
146
- });
147
- /**
148
- * kick off tests in framework
149
- */
150
- let failures = 0;
151
- try {
152
- failures = await this._framework.run();
153
- await this._fetchDriverLogs(this._config, caps.excludeDriverLogs);
154
- }
155
- catch (err) {
156
- log.error(err);
157
- this.emit('error', err);
158
- failures = 1;
159
- }
160
- /**
161
- * in watch mode we don't close the session and leave current page opened
162
- */
163
- if (!args.watch) {
164
- await this.endSession();
165
- }
166
- return this._shutdown(failures, retries);
167
- }
168
- /**
169
- * init protocol session
170
- * @param {object} config configuration of sessions
171
- * @param {Object} caps desired capabilities of session
172
- * @param {Object} browserStub stubbed `browser` object with only capabilities, config and env flags
173
- * @return {Promise} resolves with browser object or null if session couldn't get established
174
- */
175
- async _initSession(config, caps, browserStub) {
176
- const browser = await this._startSession(config, caps);
177
- // return null if session couldn't get established
178
- if (!browser) {
179
- return;
180
- }
181
- // add flags declared by user to browser object
182
- if (browserStub) {
183
- Object.entries(browserStub).forEach(([key, value]) => {
184
- if (typeof browser[key] === 'undefined') {
185
- // @ts-ignore allow to set value for undefined props
186
- browser[key] = value;
187
- }
188
- });
189
- }
190
- /**
191
- * register global helper method to fetch elements
192
- */
193
- // @ts-ignore
194
- global.$ = (selector) => browser.$(selector);
195
- // @ts-ignore
196
- global.$$ = (selector) => browser.$$(selector);
197
- /**
198
- * register command event
199
- */
200
- browser.on('command', (command) => {
201
- var _a;
202
- return (_a = this._reporter) === null || _a === void 0 ? void 0 : _a.emit('client:beforeCommand', Object.assign(command, { sessionId: browser.sessionId }));
203
- });
204
- /**
205
- * register result event
206
- */
207
- browser.on('result', (result) => {
208
- var _a;
209
- return (_a = this._reporter) === null || _a === void 0 ? void 0 : _a.emit('client:afterCommand', Object.assign(result, { sessionId: browser.sessionId }));
210
- });
211
- return browser;
212
- }
213
- /**
214
- * start protocol session
215
- * @param {object} config configuration of sessions
216
- * @param {Object} caps desired capabilities of session
217
- * @return {Promise} resolves with browser object or null if session couldn't get established
218
- */
219
- async _startSession(config, caps) {
220
- let browser;
221
- try {
222
- // @ts-ignore
223
- browser = global.browser = global.driver = await (0, utils_2.initialiseInstance)(config, caps, this._isMultiremote);
224
- /**
225
- * attach browser to `multiremotebrowser` so user have better typing support
226
- */
227
- if (this._isMultiremote) {
228
- // @ts-ignore
229
- global.multiremotebrowser = browser;
230
- }
231
- }
232
- catch (err) {
233
- log.error(err);
234
- return;
235
- }
236
- browser.config = config;
237
- return browser;
238
- }
239
- /**
240
- * fetch logs provided by browser driver
241
- */
242
- async _fetchDriverLogs(config, excludeDriverLogs) {
243
- /**
244
- * only fetch logs if
245
- */
246
- if (
247
- /**
248
- * a log directory is given in config
249
- */
250
- !config.outputDir ||
251
- /**
252
- * the session wasn't killed during start up phase
253
- */
254
- !global.browser.sessionId ||
255
- /**
256
- * driver supports it
257
- */
258
- typeof global.browser.getLogs === 'undefined') {
259
- return;
260
- }
261
- /**
262
- * suppress @wdio/sync warnings of not running commands inside of
263
- * a Fibers context
264
- */
265
- global._HAS_FIBER_CONTEXT = true;
266
- let logTypes;
267
- try {
268
- logTypes = await global.browser.getLogTypes();
269
- }
270
- catch (errIgnored) {
271
- /**
272
- * getLogTypes is not supported by browser
273
- */
274
- return;
275
- }
276
- logTypes = (0, utils_2.filterLogTypes)(excludeDriverLogs, logTypes);
277
- log.debug(`Fetching logs for ${logTypes.join(', ')}`);
278
- return Promise.all(logTypes.map(async (logType) => {
279
- let logs;
280
- try {
281
- logs = await global.browser.getLogs(logType);
282
- }
283
- catch (e) {
284
- return log.warn(`Couldn't fetch logs for ${logType}: ${e.message}`);
285
- }
286
- /**
287
- * don't write to file if no logs were captured
288
- */
289
- if (logs.length === 0) {
290
- return;
291
- }
292
- const stringLogs = logs.map((log) => JSON.stringify(log)).join('\n');
293
- return util_1.default.promisify(fs_1.default.writeFile)(path_1.default.join(config.outputDir, `wdio-${this._cid}-${logType}.log`), stringLogs, 'utf-8');
294
- }));
295
- }
296
- /**
297
- * kill worker session
298
- */
299
- async _shutdown(failures, retries) {
300
- this._reporter.emit('runner:end', {
301
- failures,
302
- cid: this._cid,
303
- retries
304
- });
305
- try {
306
- await this._reporter.waitForSync();
307
- }
308
- catch (err) {
309
- log.error(err);
310
- }
311
- this.emit('exit', failures === 0 ? 0 : 1);
312
- return failures;
313
- }
314
- /**
315
- * end WebDriver session, a config object can be applied if object has changed
316
- * within a hook by the user
317
- */
318
- async endSession() {
319
- /**
320
- * make sure instance(s) exist and have `sessionId`
321
- */
322
- const multiremoteBrowser = global.browser;
323
- const hasSessionId = Boolean(global.browser) && (this._isMultiremote
324
- /**
325
- * every multiremote instance should exist and should have `sessionId`
326
- */
327
- ? !multiremoteBrowser.instances.some(i => multiremoteBrowser[i] && !multiremoteBrowser[i].sessionId)
328
- /**
329
- * browser object should have `sessionId` in regular mode
330
- */
331
- : global.browser.sessionId);
332
- /**
333
- * don't do anything if test framework returns after SIGINT
334
- * if endSession is called without payload we expect a session id
335
- */
336
- if (!hasSessionId) {
337
- return;
338
- }
339
- /**
340
- * store capabilities for afterSession hook
341
- */
342
- const capabilities = global.browser.capabilities || {};
343
- if (this._isMultiremote) {
344
- multiremoteBrowser.instances.forEach((browserName) => {
345
- capabilities[browserName] = multiremoteBrowser[browserName].capabilities;
346
- });
347
- }
348
- await global.browser.deleteSession();
349
- /**
350
- * delete session(s)
351
- */
352
- if (this._isMultiremote) {
353
- multiremoteBrowser.instances.forEach(i => {
354
- // @ts-ignore sessionId is usually required
355
- delete multiremoteBrowser[i].sessionId;
356
- });
357
- }
358
- else {
359
- // @ts-ignore sessionId is usually required
360
- delete global.browser.sessionId;
361
- }
362
- const afterSessionArgs = [this._config, capabilities, this._specs];
363
- await (0, utils_1.executeHooksWithArgs)('afterSession', global.browser.config.afterSession, afterSessionArgs);
364
- }
365
- }
366
- exports.default = Runner;
@@ -1,37 +0,0 @@
1
- import type { Options, Capabilities, Reporters } from '@wdio/types';
2
- /**
3
- * BaseReporter
4
- * responsible for initialising reporters for every testrun and propagating events
5
- * to all these reporters
6
- */
7
- export default class BaseReporter {
8
- private _config;
9
- private _cid;
10
- caps: Capabilities.RemoteCapability;
11
- private _reporters;
12
- constructor(_config: Options.Testrunner, _cid: string, caps: Capabilities.RemoteCapability);
13
- /**
14
- * emit events to all registered reporter and wdio launcer
15
- *
16
- * @param {String} e event name
17
- * @param {object} payload event payload
18
- */
19
- emit(e: string, payload: any): void;
20
- getLogFile(name: string): string | undefined;
21
- /**
22
- * return write stream object based on reporter name
23
- */
24
- getWriteStreamObject(reporter: string): {
25
- write: (content: unknown) => boolean;
26
- };
27
- /**
28
- * wait for reporter to finish synchronization, e.g. when sending data asynchronous
29
- * to a server (e.g. sumo reporter)
30
- */
31
- waitForSync(): Promise<unknown>;
32
- /**
33
- * initialise reporters
34
- */
35
- initReporter(reporter: Reporters.ReporterEntry): Reporters.ReporterInstance;
36
- }
37
- //# sourceMappingURL=reporter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAMnE;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;IAIzB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,IAAI;IACL,IAAI,EAAE,YAAY,CAAC,gBAAgB;IAL9C,OAAO,CAAC,UAAU,CAA8B;gBAGpC,OAAO,EAAE,OAAO,CAAC,UAAU,EAC3B,IAAI,EAAE,MAAM,EACb,IAAI,EAAE,YAAY,CAAC,gBAAgB;IAM9C;;;;;OAKG;IACH,IAAI,CAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAW7B,UAAU,CAAE,IAAI,EAAE,MAAM;IAoCxB;;OAEG;IACH,oBAAoB,CAAE,QAAQ,EAAE,MAAM;yBAEc,OAAO;;IAQ3D;;;OAGG;IACH,WAAW;IA2BX;;OAEG;IACH,YAAY,CAAE,QAAQ,EAAE,SAAS,CAAC,aAAa;CAgElD"}
package/build/reporter.js DELETED
@@ -1,165 +0,0 @@
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 path_1 = __importDefault(require("path"));
7
- const logger_1 = __importDefault(require("@wdio/logger"));
8
- const utils_1 = require("@wdio/utils");
9
- const utils_2 = require("./utils");
10
- const log = (0, logger_1.default)('@wdio/runner');
11
- /**
12
- * BaseReporter
13
- * responsible for initialising reporters for every testrun and propagating events
14
- * to all these reporters
15
- */
16
- class BaseReporter {
17
- constructor(_config, _cid, caps) {
18
- this._config = _config;
19
- this._cid = _cid;
20
- this.caps = caps;
21
- // ensure all properties are set before initializing the reporters
22
- this._reporters = this._config.reporters.map(this.initReporter.bind(this));
23
- }
24
- /**
25
- * emit events to all registered reporter and wdio launcer
26
- *
27
- * @param {String} e event name
28
- * @param {object} payload event payload
29
- */
30
- emit(e, payload) {
31
- payload.cid = this._cid;
32
- /**
33
- * Send failure message (only once) in case of test or hook failure
34
- */
35
- (0, utils_2.sendFailureMessage)(e, payload);
36
- this._reporters.forEach((reporter) => reporter.emit(e, payload));
37
- }
38
- getLogFile(name) {
39
- // clone the config to avoid changing original properties
40
- let options = Object.assign({}, this._config);
41
- let filename = `wdio-${this._cid}-${name}-reporter.log`;
42
- const reporterOptions = this._config.reporters.find((reporter) => (Array.isArray(reporter) &&
43
- (reporter[0] === name ||
44
- typeof reporter[0] === 'function' && reporter[0].name === name)));
45
- if (reporterOptions) {
46
- const fileformat = reporterOptions[1].outputFileFormat;
47
- options.cid = this._cid;
48
- options.capabilities = this.caps;
49
- Object.assign(options, reporterOptions[1]);
50
- if (fileformat) {
51
- if (typeof fileformat !== 'function') {
52
- throw new Error('outputFileFormat must be a function');
53
- }
54
- filename = fileformat(options);
55
- }
56
- }
57
- if (!options.outputDir) {
58
- return;
59
- }
60
- return path_1.default.join(options.outputDir, filename);
61
- }
62
- /**
63
- * return write stream object based on reporter name
64
- */
65
- getWriteStreamObject(reporter) {
66
- return {
67
- write: /* istanbul ignore next */ (content) => process.send({
68
- origin: 'reporter',
69
- name: reporter,
70
- content
71
- })
72
- };
73
- }
74
- /**
75
- * wait for reporter to finish synchronization, e.g. when sending data asynchronous
76
- * to a server (e.g. sumo reporter)
77
- */
78
- waitForSync() {
79
- const startTime = Date.now();
80
- return new Promise((resolve, reject) => {
81
- const interval = setInterval(() => {
82
- const unsyncedReporter = this._reporters
83
- .filter((reporter) => !reporter.isSynchronised)
84
- .map((reporter) => reporter.constructor.name);
85
- if ((Date.now() - startTime) > this._config.reporterSyncTimeout && unsyncedReporter.length) {
86
- clearInterval(interval);
87
- return reject(new Error(`Some reporters are still unsynced: ${unsyncedReporter.join(', ')}`));
88
- }
89
- /**
90
- * no reporter are in need to sync anymore, continue
91
- */
92
- if (!unsyncedReporter.length) {
93
- clearInterval(interval);
94
- return resolve(true);
95
- }
96
- log.info(`Wait for ${unsyncedReporter.length} reporter to synchronise`);
97
- // wait otherwise
98
- }, this._config.reporterSyncInterval);
99
- });
100
- }
101
- /**
102
- * initialise reporters
103
- */
104
- initReporter(reporter) {
105
- let ReporterClass;
106
- let options = {};
107
- /**
108
- * check if reporter has custom options
109
- */
110
- if (Array.isArray(reporter)) {
111
- options = Object.assign({}, options, reporter[1]);
112
- reporter = reporter[0];
113
- }
114
- /**
115
- * check if reporter was passed in from a file, e.g.
116
- *
117
- * ```js
118
- * const MyCustomReporter = require('/some/path/MyCustomReporter.js')
119
- * export.config = {
120
- * //...
121
- * reporters: [
122
- * MyCustomReporter, // or
123
- * [MyCustomReporter, { custom: 'option' }]
124
- * ]
125
- * //...
126
- * }
127
- * ```
128
- */
129
- if (typeof reporter === 'function') {
130
- ReporterClass = reporter;
131
- options.logFile = options.setLogFile
132
- ? options.setLogFile(this._cid, ReporterClass.name)
133
- : this.getLogFile(ReporterClass.name);
134
- options.writeStream = this.getWriteStreamObject(ReporterClass.name);
135
- return new ReporterClass(options);
136
- }
137
- /**
138
- * check if reporter is a node package, e.g. wdio-dot reporter
139
- *
140
- * ```js
141
- * export.config = {
142
- * //...
143
- * reporters: [
144
- * 'dot', // or
145
- * ['dot', { custom: 'option' }]
146
- * ]
147
- * //...
148
- * }
149
- * ```
150
- */
151
- if (typeof reporter === 'string') {
152
- ReporterClass = (0, utils_1.initialisePlugin)(reporter, 'reporter').default;
153
- options.logFile = options.setLogFile
154
- ? options.setLogFile(this._cid, reporter)
155
- : this.getLogFile(reporter);
156
- options.writeStream = this.getWriteStreamObject(reporter);
157
- return new ReporterClass(options);
158
- }
159
- /**
160
- * throw error if reporter property was invalid
161
- */
162
- throw new Error('Invalid reporters config');
163
- }
164
- }
165
- exports.default = BaseReporter;
package/build/utils.d.ts DELETED
@@ -1,51 +0,0 @@
1
- import type { Options, Capabilities } from '@wdio/types';
2
- import type { Browser, MultiRemoteBrowser } from 'webdriverio';
3
- export interface ConfigWithSessionId extends Omit<Options.Testrunner, 'capabilities'> {
4
- sessionId?: string;
5
- capabilities: Capabilities.RemoteCapability;
6
- }
7
- /**
8
- * sanitizes wdio config from capability properties
9
- * @param {Object} caps desired session capabilities
10
- * @return {Object} sanitized caps
11
- */
12
- export declare function sanitizeCaps(caps: Capabilities.RemoteCapability, filterOut?: boolean): Omit<Capabilities.RemoteCapability, 'logLevel'>;
13
- /**
14
- * initialise browser instance depending whether remote or multiremote is requested
15
- * @param {Object} config configuration of sessions
16
- * @param {Object} capabilities desired session capabilities
17
- * @param {boolean} isMultiremote isMultiremote
18
- * @return {Promise} resolves with browser object
19
- */
20
- export declare function initialiseInstance(config: ConfigWithSessionId, capabilities: Capabilities.RemoteCapability, isMultiremote?: boolean): Promise<Browser<'async'> | MultiRemoteBrowser<'async'>>;
21
- /**
22
- * Filter logTypes based on filter
23
- * @param {string[]} excludeDriverLogs logTypes filter
24
- * @param {string[]} driverLogTypes available driver log types
25
- * @return {string[]} logTypes
26
- */
27
- export declare function filterLogTypes(excludeDriverLogs: string[], driverLogTypes: string[]): string[];
28
- /**
29
- * Send event to WDIOCLInterface if test or before/after all hook failed
30
- * @param {string} e event
31
- * @param {object} payload payload
32
- */
33
- export declare function sendFailureMessage(e: string, payload: any): void;
34
- declare type BrowserData = {
35
- sessionId: string;
36
- isW3C: boolean;
37
- protocol: string;
38
- hostname: string;
39
- port: number;
40
- path: string;
41
- queryParams: Record<string, string>;
42
- };
43
- /**
44
- * Gets { sessionId, isW3C, protocol, hostname, port, path, queryParams } of every Multiremote instance
45
- * @param {object} browser browser
46
- * @param {boolean} isMultiremote isMultiremote
47
- * @return {object}
48
- */
49
- export declare function getInstancesData(browser: Browser<'async'> | MultiRemoteBrowser<'async'>, isMultiremote: boolean): Record<string, Partial<BrowserData>> | undefined;
50
- export {};
51
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAO9D,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC,gBAAgB,CAAA;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CACxB,IAAI,EAAE,YAAY,CAAC,gBAAgB,EACnC,SAAS,CAAC,EAAE,OAAO,GACpB,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAoBjD;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACpC,MAAM,EAAE,mBAAmB,EAC3B,YAAY,EAAE,YAAY,CAAC,gBAAgB,EAC3C,aAAa,CAAC,EAAE,OAAO,GACxB,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC,CA4CzD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC1B,iBAAiB,EAAE,MAAM,EAAE,EAC3B,cAAc,EAAE,MAAM,EAAE,YAiB3B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,QAezD;AAED,aAAK,WAAW,GAAG;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACtC,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC5B,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,EACvD,aAAa,EAAE,OAAO,oDAgBzB"}
package/build/utils.js DELETED
@@ -1,139 +0,0 @@
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.getInstancesData = exports.sendFailureMessage = exports.filterLogTypes = exports.initialiseInstance = exports.sanitizeCaps = void 0;
7
- const deepmerge_1 = __importDefault(require("deepmerge"));
8
- const logger_1 = __importDefault(require("@wdio/logger"));
9
- const webdriverio_1 = require("webdriverio");
10
- const webdriver_1 = require("webdriver");
11
- const config_1 = require("@wdio/config");
12
- const log = (0, logger_1.default)('@wdio/local-runner:utils');
13
- const MERGE_OPTIONS = { clone: false };
14
- const mochaAllHooks = ['"before all" hook', '"after all" hook'];
15
- /**
16
- * sanitizes wdio config from capability properties
17
- * @param {Object} caps desired session capabilities
18
- * @return {Object} sanitized caps
19
- */
20
- function sanitizeCaps(caps, filterOut) {
21
- const defaultConfigsKeys = [
22
- // WDIO config keys
23
- ...Object.keys((0, config_1.DEFAULT_CONFIGS)()),
24
- // WebDriver config keys
25
- ...Object.keys(webdriver_1.DEFAULTS)
26
- ];
27
- return Object.keys(caps).filter((key) => (
28
- /**
29
- * filter out all wdio config keys
30
- */
31
- !defaultConfigsKeys.includes(key) === !filterOut)).reduce((obj, key) => {
32
- obj[key] = caps[key];
33
- return obj;
34
- }, {});
35
- }
36
- exports.sanitizeCaps = sanitizeCaps;
37
- /**
38
- * initialise browser instance depending whether remote or multiremote is requested
39
- * @param {Object} config configuration of sessions
40
- * @param {Object} capabilities desired session capabilities
41
- * @param {boolean} isMultiremote isMultiremote
42
- * @return {Promise} resolves with browser object
43
- */
44
- async function initialiseInstance(config, capabilities, isMultiremote) {
45
- /**
46
- * check if config has sessionId and attach it to a running session if so
47
- */
48
- if (config.sessionId) {
49
- log.debug(`attach to session with id ${config.sessionId}`);
50
- config.capabilities = sanitizeCaps(capabilities);
51
- /**
52
- * propagate connection details defined by services or user in capabilities
53
- */
54
- const { protocol, hostname, port, path } = capabilities;
55
- return (0, webdriverio_1.attach)({ ...config, ...{ protocol, hostname, port, path } });
56
- }
57
- if (!isMultiremote) {
58
- log.debug('init remote session');
59
- const sessionConfig = {
60
- ...config,
61
- ...sanitizeCaps(capabilities, true),
62
- capabilities: sanitizeCaps(capabilities)
63
- };
64
- return (0, webdriverio_1.remote)(sessionConfig);
65
- }
66
- const options = {};
67
- log.debug('init multiremote session');
68
- // @ts-expect-error ToDo(Christian): can be removed?
69
- delete config.capabilities;
70
- for (let browserName of Object.keys(capabilities)) {
71
- options[browserName] = (0, deepmerge_1.default)(config, capabilities[browserName], MERGE_OPTIONS);
72
- }
73
- const browser = await (0, webdriverio_1.multiremote)(options, config);
74
- for (let browserName of Object.keys(capabilities)) {
75
- // @ts-ignore allow random global browser names
76
- global[browserName] = browser[browserName];
77
- }
78
- return browser;
79
- }
80
- exports.initialiseInstance = initialiseInstance;
81
- /**
82
- * Filter logTypes based on filter
83
- * @param {string[]} excludeDriverLogs logTypes filter
84
- * @param {string[]} driverLogTypes available driver log types
85
- * @return {string[]} logTypes
86
- */
87
- function filterLogTypes(excludeDriverLogs, driverLogTypes) {
88
- let logTypes = [...driverLogTypes];
89
- if (Array.isArray(excludeDriverLogs)) {
90
- log.debug('filtering logTypes', logTypes);
91
- if (excludeDriverLogs.length === 1 && excludeDriverLogs[0] === '*') { // exclude all logTypes
92
- logTypes = [];
93
- }
94
- else {
95
- logTypes = logTypes.filter(x => !excludeDriverLogs.includes(x)); // exclude specific logTypes
96
- }
97
- log.debug('filtered logTypes', logTypes);
98
- }
99
- return logTypes;
100
- }
101
- exports.filterLogTypes = filterLogTypes;
102
- /**
103
- * Send event to WDIOCLInterface if test or before/after all hook failed
104
- * @param {string} e event
105
- * @param {object} payload payload
106
- */
107
- function sendFailureMessage(e, payload) {
108
- if (e === 'test:fail' ||
109
- (e === 'hook:end' &&
110
- payload.error &&
111
- mochaAllHooks.some(hook => payload.title.startsWith(hook)))) {
112
- process.send({
113
- origin: 'reporter',
114
- name: 'printFailureMessage',
115
- content: payload
116
- });
117
- }
118
- }
119
- exports.sendFailureMessage = sendFailureMessage;
120
- /**
121
- * Gets { sessionId, isW3C, protocol, hostname, port, path, queryParams } of every Multiremote instance
122
- * @param {object} browser browser
123
- * @param {boolean} isMultiremote isMultiremote
124
- * @return {object}
125
- */
126
- function getInstancesData(browser, isMultiremote) {
127
- if (!isMultiremote) {
128
- return;
129
- }
130
- const multiRemoteBrowser = browser;
131
- const instances = {};
132
- multiRemoteBrowser.instances.forEach((browserName) => {
133
- const { protocol, hostname, port, path, queryParams } = multiRemoteBrowser[browserName].options;
134
- const { isW3C, sessionId } = multiRemoteBrowser[browserName];
135
- instances[browserName] = { sessionId, isW3C, protocol, hostname, port, path, queryParams };
136
- });
137
- return instances;
138
- }
139
- exports.getInstancesData = getInstancesData;