@wdio/runner 7.20.7 → 7.20.8-alpha.504

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.
@@ -0,0 +1,29 @@
1
+ import type { Capabilities } from '@wdio/types';
2
+ import type BaseReporter from './reporter';
3
+ import type { TestFramework } from './types';
4
+ declare type WDIOErrorEvent = Pick<ErrorEvent, 'filename' | 'message'>;
5
+ declare global {
6
+ interface Window {
7
+ __wdioErrors__: WDIOErrorEvent[];
8
+ __wdioEvents__: any[];
9
+ __wdioFailures__: number;
10
+ }
11
+ }
12
+ export default class BrowserFramework implements Omit<TestFramework, 'init'> {
13
+ #private;
14
+ private _cid;
15
+ private _config;
16
+ private _specs;
17
+ private _capabilities;
18
+ private _reporter;
19
+ constructor(_cid: string, _config: unknown, _specs: string[], _capabilities: Capabilities.RemoteCapability, _reporter: BaseReporter);
20
+ /**
21
+ * always return true as it is unrelevant for component testing
22
+ */
23
+ hasTests(): boolean;
24
+ init(): TestFramework;
25
+ run(): Promise<number>;
26
+ static init(cid: string, config: unknown, specs: string[], caps: Capabilities.RemoteCapability, reporter: BaseReporter): BrowserFramework;
27
+ }
28
+ export {};
29
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C,OAAO,KAAK,YAAY,MAAM,YAAY,CAAA;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAK5C,aAAK,cAAc,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,CAAC,CAAA;AAE9D,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,cAAc,EAAE,cAAc,EAAE,CAAA;QAChC,cAAc,EAAE,GAAG,EAAE,CAAA;QACrB,gBAAgB,EAAE,MAAM,CAAA;KAC3B;CACJ;AAED,MAAM,CAAC,OAAO,OAAO,gBAAiB,YAAW,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC;;IAEpE,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,SAAS;gBAJT,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,aAAa,EAAE,YAAY,CAAC,gBAAgB,EAC5C,SAAS,EAAE,YAAY;IAGnC;;OAEG;IACH,QAAQ;IAIR,IAAI;IAIE,GAAG;IAiFT,MAAM,CAAC,IAAI,CAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,gBAAgB,EAAE,QAAQ,EAAE,YAAY;CAI1H"}
@@ -0,0 +1,104 @@
1
+ import url from 'node:url';
2
+ import path from 'node:path';
3
+ import logger from '@wdio/logger';
4
+ import { browser } from '@wdio/globals';
5
+ const log = logger('@wdio/runner');
6
+ const sep = '\n - ';
7
+ export default class BrowserFramework {
8
+ _cid;
9
+ _config;
10
+ _specs;
11
+ _capabilities;
12
+ _reporter;
13
+ constructor(_cid, _config, _specs, _capabilities, _reporter) {
14
+ this._cid = _cid;
15
+ this._config = _config;
16
+ this._specs = _specs;
17
+ this._capabilities = _capabilities;
18
+ this._reporter = _reporter;
19
+ }
20
+ /**
21
+ * always return true as it is unrelevant for component testing
22
+ */
23
+ hasTests() {
24
+ return true;
25
+ }
26
+ init() {
27
+ return undefined;
28
+ }
29
+ async run() {
30
+ try {
31
+ const failures = await this.#loop();
32
+ return failures;
33
+ }
34
+ catch (err) {
35
+ log.error(`Failed to run browser tests with cid ${this._cid}: ${err.stack}`);
36
+ return 1;
37
+ }
38
+ }
39
+ async #loop() {
40
+ /**
41
+ * start tests
42
+ */
43
+ let failures = 0;
44
+ for (const spec of this._specs) {
45
+ log.info(`Run spec file ${spec} for cid ${this._cid}`);
46
+ console.log(`Run spec file ${spec} for cid ${this._cid}`);
47
+ await browser.url(`/${this._cid}/test.html?spec=${url.fileURLToPath(spec)}`);
48
+ // await browser.debug()
49
+ /**
50
+ * fetch page errors that are thrown during rendering and let spec file fail
51
+ */
52
+ const jsErrors = (await browser.execute(() => window.__wdioErrors__)) || ([]);
53
+ if (jsErrors.length) {
54
+ const errors = jsErrors.map((ev) => `${path.basename(ev.filename)}: ${ev.message}`);
55
+ const envError = new Error(`Test failed due to following error(s):${sep}${errors.join(sep)}`);
56
+ this._reporter.emit('error', {
57
+ cid: this._cid,
58
+ name: 'error',
59
+ content: envError.message
60
+ });
61
+ failures += 1;
62
+ continue;
63
+ }
64
+ failures += await this.#fetchEvents(browser, spec);
65
+ }
66
+ return failures;
67
+ }
68
+ async #fetchEvents(browser, spec) {
69
+ /**
70
+ * wait until tests have finished and results are emitted to the window scope
71
+ */
72
+ let failures = null;
73
+ await browser.waitUntil(async () => {
74
+ while (typeof failures !== 'number') {
75
+ failures = await browser?.execute(() => (window.__wdioEvents__.length > 0
76
+ ? window.__wdioFailures__
77
+ : null));
78
+ }
79
+ return true;
80
+ }, {
81
+ timeoutMsg: 'browser test timed out'
82
+ });
83
+ /**
84
+ * populate events to the reporter
85
+ */
86
+ const events = await browser.execute(() => window.__wdioEvents__);
87
+ for (const ev of events) {
88
+ if ((ev.type === 'suite:start' || ev.type === 'suite:end') && ev.title === '') {
89
+ continue;
90
+ }
91
+ this._reporter.emit(ev.type, {
92
+ ...ev,
93
+ file: spec,
94
+ uid: this._cid,
95
+ cid: this._cid
96
+ });
97
+ }
98
+ return failures;
99
+ }
100
+ static init(cid, config, specs, caps, reporter) {
101
+ const framework = new BrowserFramework(cid, config, specs, caps, reporter);
102
+ return framework;
103
+ }
104
+ }
package/build/index.d.ts CHANGED
@@ -1,37 +1,9 @@
1
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
- }
2
+ import { EventEmitter } from 'node:events';
3
+ import type { RunParams } from './types';
34
4
  export default class Runner extends EventEmitter {
5
+ #private;
6
+ private _browser?;
35
7
  private _configParser;
36
8
  private _sigintWasCalled;
37
9
  private _isMultiremote;
@@ -82,5 +54,6 @@ export default class Runner extends EventEmitter {
82
54
  */
83
55
  endSession(): Promise<void>;
84
56
  }
85
- export {};
57
+ export { default as BaseReporter } from './reporter.js';
58
+ export * from './types.js';
86
59
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAa1C,OAAO,KAAK,EACoD,SAAS,EAGxE,MAAM,SAAS,CAAA;AAIhB,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,YAAY;;IAC5C,OAAO,CAAC,QAAQ,CAAC,CAAgD;IACjE,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;IA4LpE;;;;;;OAMG;YACW,YAAY;IA6C1B;;;;;OAKG;YACW,aAAa;IAiC3B;;OAEG;YACW,gBAAgB;IA8D9B;;OAEG;YACW,SAAS;IAmCvB;;;OAGG;IACG,UAAU;CA2DnB;AAED,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,eAAe,CAAA;AACvD,cAAc,YAAY,CAAA"}
package/build/index.js CHANGED
@@ -1,26 +1,27 @@
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
- }
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { EventEmitter } from 'node:events';
4
+ import logger from '@wdio/logger';
5
+ import { initialiseWorkerService, initialisePlugin, executeHooksWithArgs } from '@wdio/utils';
6
+ import { ConfigParser } from '@wdio/config';
7
+ import { _setGlobal } from '@wdio/globals';
8
+ import { expect, setOptions } from 'expect-webdriverio';
9
+ import BrowserFramework from './browser.js';
10
+ import BaseReporter from './reporter.js';
11
+ import { initialiseInstance, filterLogTypes, getInstancesData } from './utils.js';
12
+ const log = logger('@wdio/runner');
13
+ export default class Runner extends EventEmitter {
14
+ _browser;
15
+ _configParser = new ConfigParser();
16
+ _sigintWasCalled = false;
17
+ _isMultiremote = false;
18
+ _specFileRetryAttempts = 0;
19
+ _reporter;
20
+ _framework;
21
+ _config;
22
+ _cid;
23
+ _specs;
24
+ _caps;
24
25
  /**
25
26
  * run test suite
26
27
  * @param {String} cid worker id (e.g. `0-0`)
@@ -32,14 +33,13 @@ class Runner extends events_1.EventEmitter {
32
33
  * @return {Promise} resolves in number of failures for testrun
33
34
  */
34
35
  async run({ cid, args, specs, caps, configFile, retries }) {
35
- var _a;
36
36
  this._cid = cid;
37
37
  this._specs = specs;
38
38
  this._caps = caps;
39
39
  /**
40
40
  * autocompile after parsing configs so we support ES6 features in tests with config driven by users
41
41
  */
42
- if ((_a = args.autoCompileOpts) === null || _a === void 0 ? void 0 : _a.autoCompile) {
42
+ if (args.autoCompileOpts?.autoCompile) {
43
43
  this._configParser.merge({ autoCompileOpts: args.autoCompileOpts });
44
44
  this._configParser.autoCompile();
45
45
  }
@@ -47,10 +47,11 @@ class Runner extends events_1.EventEmitter {
47
47
  * add config file
48
48
  */
49
49
  try {
50
- this._configParser.addConfigFile(configFile);
50
+ await this._configParser.addConfigFile(configFile);
51
51
  }
52
52
  catch (err) {
53
- return this._shutdown(1, retries);
53
+ log.error(`Failed to read config file: ${err.stack}`);
54
+ return this._shutdown(1, retries, true);
54
55
  }
55
56
  /**
56
57
  * merge cli arguments again as some might have been overwritten by the config
@@ -58,7 +59,7 @@ class Runner extends events_1.EventEmitter {
58
59
  this._configParser.merge(args);
59
60
  this._config = this._configParser.getConfig();
60
61
  this._specFileRetryAttempts = (this._config.specFileRetries || 0) - (retries || 0);
61
- logger_1.default.setLogLevelsConfig(this._config.logLevels, this._config.logLevel);
62
+ logger.setLogLevelsConfig(this._config.logLevels, this._config.logLevel);
62
63
  const isMultiremote = this._isMultiremote = !Array.isArray(this._configParser.getCapabilities());
63
64
  /**
64
65
  * create `browser` stub only if `specFiltering` feature is enabled
@@ -67,23 +68,20 @@ class Runner extends events_1.EventEmitter {
67
68
  ...this._config,
68
69
  // @ts-ignore used in `/packages/webdriverio/src/protocol-stub.ts`
69
70
  _automationProtocol: this._config.automationProtocol,
70
- automationProtocol: './protocol-stub'
71
+ automationProtocol: './protocol-stub.js'
71
72
  }, 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));
73
+ (await initialiseWorkerService(this._config, caps, args.ignoredWorkerServices)).map(this._configParser.addService.bind(this._configParser));
76
74
  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 });
75
+ await executeHooksWithArgs('beforeSession', this._config.beforeSession, beforeSessionParams);
76
+ this._reporter = new BaseReporter(this._config, this._cid, { ...caps });
77
+ await this._reporter.initReporters();
79
78
  /**
80
79
  * initialise framework
81
80
  */
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);
81
+ this._framework = await this.#initFramework(cid, this._config, caps, this._reporter, specs);
84
82
  process.send({ name: 'testFrameworkInit', content: { cid, caps, specs, hasTests: this._framework.hasTests() } });
85
83
  if (!this._framework.hasTests()) {
86
- return this._shutdown(0, retries);
84
+ return this._shutdown(0, retries, true);
87
85
  }
88
86
  browser = await this._initSession(this._config, this._caps, browser);
89
87
  /**
@@ -91,12 +89,12 @@ class Runner extends events_1.EventEmitter {
91
89
  */
92
90
  if (!browser) {
93
91
  const afterArgs = [1, this._caps, this._specs];
94
- await (0, utils_1.executeHooksWithArgs)('after', this._config.after, afterArgs);
95
- return this._shutdown(1, retries);
92
+ await executeHooksWithArgs('after', this._config.after, afterArgs);
93
+ return this._shutdown(1, retries, true);
96
94
  }
97
95
  this._reporter.caps = browser.capabilities;
98
96
  const beforeArgs = [this._caps, this._specs, browser];
99
- await (0, utils_1.executeHooksWithArgs)('before', this._config.before, beforeArgs);
97
+ await executeHooksWithArgs('before', this._config.before, beforeArgs);
100
98
  /**
101
99
  * kill session of SIGINT signal showed up while trying to
102
100
  * get a session ID
@@ -104,7 +102,7 @@ class Runner extends events_1.EventEmitter {
104
102
  if (this._sigintWasCalled) {
105
103
  log.info('SIGINT signal detected while starting session, shutting down...');
106
104
  await this.endSession();
107
- return this._shutdown(0, retries);
105
+ return this._shutdown(0, retries, true);
108
106
  }
109
107
  /**
110
108
  * initialisation successful, send start message
@@ -138,11 +136,15 @@ class Runner extends events_1.EventEmitter {
138
136
  */
139
137
  const { protocol, hostname, port, path, queryParams } = browser.options;
140
138
  const { isW3C, sessionId } = browser;
141
- const instances = (0, utils_2.getInstancesData)(browser, isMultiremote);
139
+ const instances = getInstancesData(browser, isMultiremote);
142
140
  process.send({
143
141
  origin: 'worker',
144
142
  name: 'sessionStarted',
145
- content: { sessionId, isW3C, protocol, hostname, port, path, queryParams, isMultiremote, instances }
143
+ content: {
144
+ sessionId, isW3C, protocol, hostname, port, path, queryParams, isMultiremote, instances,
145
+ capabilities: browser.capabilities,
146
+ injectGlobals: this._config.injectGlobals
147
+ }
146
148
  });
147
149
  /**
148
150
  * kick off tests in framework
@@ -165,6 +167,24 @@ class Runner extends events_1.EventEmitter {
165
167
  }
166
168
  return this._shutdown(failures, retries);
167
169
  }
170
+ async #initFramework(cid, config, capabilities, reporter, specs) {
171
+ const runner = Array.isArray(config.runner) ? config.runner[0] : config.runner;
172
+ /**
173
+ * initialise framework adapter when running remote browser tests
174
+ */
175
+ if (runner === 'local') {
176
+ const framework = (await initialisePlugin(config.framework, 'framework')).default;
177
+ return framework.init(cid, config, specs, capabilities, reporter);
178
+ }
179
+ /**
180
+ * for embedded browser tests the `@wdio/browser-runner` already has the environment
181
+ * setup so we can just run through the tests
182
+ */
183
+ if (runner === 'browser') {
184
+ return BrowserFramework.init(cid, config, specs, capabilities, reporter);
185
+ }
186
+ throw new Error(`Unknown runner "${runner}"`);
187
+ }
168
188
  /**
169
189
  * init protocol session
170
190
  * @param {object} config configuration of sessions
@@ -190,24 +210,16 @@ class Runner extends events_1.EventEmitter {
190
210
  /**
191
211
  * register global helper method to fetch elements
192
212
  */
193
- // @ts-ignore
194
- global.$ = (selector) => browser.$(selector);
195
- // @ts-ignore
196
- global.$$ = (selector) => browser.$$(selector);
213
+ _setGlobal('$', (selector) => browser.$(selector), config.injectGlobals);
214
+ _setGlobal('$$', (selector) => browser.$$(selector), config.injectGlobals);
197
215
  /**
198
216
  * register command event
199
217
  */
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
- });
218
+ browser.on('command', (command) => this._reporter?.emit('client:beforeCommand', Object.assign(command, { sessionId: browser.sessionId })));
204
219
  /**
205
220
  * register result event
206
221
  */
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
- });
222
+ browser.on('result', (result) => this._reporter?.emit('client:afterCommand', Object.assign(result, { sessionId: browser.sessionId })));
211
223
  return browser;
212
224
  }
213
225
  /**
@@ -217,24 +229,31 @@ class Runner extends events_1.EventEmitter {
217
229
  * @return {Promise} resolves with browser object or null if session couldn't get established
218
230
  */
219
231
  async _startSession(config, caps) {
220
- let browser;
221
232
  try {
222
- // @ts-ignore
223
- browser = global.browser = global.driver = await (0, utils_2.initialiseInstance)(config, caps, this._isMultiremote);
233
+ this._browser = await initialiseInstance(config, caps, this._isMultiremote);
234
+ _setGlobal('browser', this._browser, config.injectGlobals);
235
+ _setGlobal('driver', this._browser, config.injectGlobals);
236
+ _setGlobal('expect', expect, config.injectGlobals);
237
+ /**
238
+ * import and set options for `expect-webdriverio` assertion lib once
239
+ * the browser was initiated
240
+ */
241
+ setOptions({
242
+ wait: config.waitforTimeout,
243
+ interval: config.waitforInterval, // interval between attempts
244
+ });
224
245
  /**
225
246
  * attach browser to `multiremotebrowser` so user have better typing support
226
247
  */
227
248
  if (this._isMultiremote) {
228
- // @ts-ignore
229
- global.multiremotebrowser = browser;
249
+ _setGlobal('multiremotebrowser', this._browser, config.injectGlobals);
230
250
  }
231
251
  }
232
252
  catch (err) {
233
253
  log.error(err);
234
254
  return;
235
255
  }
236
- browser.config = config;
237
- return browser;
256
+ return this._browser;
238
257
  }
239
258
  /**
240
259
  * fetch logs provided by browser driver
@@ -251,21 +270,16 @@ class Runner extends events_1.EventEmitter {
251
270
  /**
252
271
  * the session wasn't killed during start up phase
253
272
  */
254
- !global.browser.sessionId ||
273
+ !this._browser?.sessionId ||
255
274
  /**
256
275
  * driver supports it
257
276
  */
258
- typeof global.browser.getLogs === 'undefined') {
277
+ typeof this._browser.getLogs === 'undefined') {
259
278
  return;
260
279
  }
261
- /**
262
- * suppress @wdio/sync warnings of not running commands inside of
263
- * a Fibers context
264
- */
265
- global._HAS_FIBER_CONTEXT = true;
266
280
  let logTypes;
267
281
  try {
268
- logTypes = await global.browser.getLogTypes();
282
+ logTypes = await this._browser.getLogTypes();
269
283
  }
270
284
  catch (errIgnored) {
271
285
  /**
@@ -273,12 +287,12 @@ class Runner extends events_1.EventEmitter {
273
287
  */
274
288
  return;
275
289
  }
276
- logTypes = (0, utils_2.filterLogTypes)(excludeDriverLogs, logTypes);
290
+ logTypes = filterLogTypes(excludeDriverLogs, logTypes);
277
291
  log.debug(`Fetching logs for ${logTypes.join(', ')}`);
278
292
  return Promise.all(logTypes.map(async (logType) => {
279
293
  let logs;
280
294
  try {
281
- logs = await global.browser.getLogs(logType);
295
+ logs = await this._browser?.getLogs(logType);
282
296
  }
283
297
  catch (e) {
284
298
  return log.warn(`Couldn't fetch logs for ${logType}: ${e.message}`);
@@ -286,17 +300,32 @@ class Runner extends events_1.EventEmitter {
286
300
  /**
287
301
  * don't write to file if no logs were captured
288
302
  */
289
- if (logs.length === 0) {
303
+ if (!logs || logs.length === 0) {
290
304
  return;
291
305
  }
292
306
  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');
307
+ return fs.writeFile(path.join(config.outputDir, `wdio-${this._cid}-${logType}.log`), stringLogs, 'utf-8');
294
308
  }));
295
309
  }
296
310
  /**
297
311
  * kill worker session
298
312
  */
299
- async _shutdown(failures, retries) {
313
+ async _shutdown(failures, retries, initiationFailed = false) {
314
+ /**
315
+ * In case of initialisation failed, the sessionId is undefined and the runner:start is not triggered.
316
+ * So, to be able to perform the runner:end into the reporters, we need to launch the runner:start just before the runner:end.
317
+ */
318
+ if (this._reporter && initiationFailed) {
319
+ this._reporter.emit('runner:start', {
320
+ cid: this._cid,
321
+ specs: this._specs,
322
+ config: this._config,
323
+ isMultiremote: this._isMultiremote,
324
+ instanceOptions: {},
325
+ capabilities: { ...this._configParser.getCapabilities() },
326
+ retry: this._specFileRetryAttempts
327
+ });
328
+ }
300
329
  this._reporter.emit('runner:end', {
301
330
  failures,
302
331
  cid: this._cid,
@@ -319,16 +348,17 @@ class Runner extends events_1.EventEmitter {
319
348
  /**
320
349
  * make sure instance(s) exist and have `sessionId`
321
350
  */
322
- const multiremoteBrowser = global.browser;
323
- const hasSessionId = Boolean(global.browser) && (this._isMultiremote
351
+ const multiremoteBrowser = this._browser;
352
+ const hasSessionId = Boolean(this._browser) && (this._isMultiremote
324
353
  /**
325
354
  * every multiremote instance should exist and should have `sessionId`
326
355
  */
327
- ? !multiremoteBrowser.instances.some(i => multiremoteBrowser[i] && !multiremoteBrowser[i].sessionId)
356
+ ? !multiremoteBrowser.instances.some((browserName) => (multiremoteBrowser[browserName] &&
357
+ !multiremoteBrowser[browserName].sessionId))
328
358
  /**
329
359
  * browser object should have `sessionId` in regular mode
330
360
  */
331
- : global.browser.sessionId);
361
+ : this._browser?.sessionId);
332
362
  /**
333
363
  * don't do anything if test framework returns after SIGINT
334
364
  * if endSession is called without payload we expect a session id
@@ -339,28 +369,33 @@ class Runner extends events_1.EventEmitter {
339
369
  /**
340
370
  * store capabilities for afterSession hook
341
371
  */
342
- const capabilities = global.browser.capabilities || {};
372
+ const capabilities = this._browser?.capabilities || {};
343
373
  if (this._isMultiremote) {
344
374
  multiremoteBrowser.instances.forEach((browserName) => {
345
375
  capabilities[browserName] = multiremoteBrowser[browserName].capabilities;
346
376
  });
347
377
  }
348
- await global.browser.deleteSession();
378
+ await this._browser?.deleteSession();
379
+ process.send({
380
+ origin: 'worker',
381
+ name: 'sessionEnded',
382
+ cid: this._cid
383
+ });
349
384
  /**
350
385
  * delete session(s)
351
386
  */
352
387
  if (this._isMultiremote) {
353
- multiremoteBrowser.instances.forEach(i => {
388
+ multiremoteBrowser.instances.forEach((browserName) => {
354
389
  // @ts-ignore sessionId is usually required
355
- delete multiremoteBrowser[i].sessionId;
390
+ delete multiremoteBrowser[browserName].sessionId;
356
391
  });
357
392
  }
358
- else {
359
- // @ts-ignore sessionId is usually required
360
- delete global.browser.sessionId;
393
+ else if (this._browser) {
394
+ this._browser.sessionId = undefined;
361
395
  }
362
396
  const afterSessionArgs = [this._config, capabilities, this._specs];
363
- await (0, utils_1.executeHooksWithArgs)('afterSession', global.browser.config.afterSession, afterSessionArgs);
397
+ await executeHooksWithArgs('afterSession', this._config.afterSession, afterSessionArgs);
364
398
  }
365
399
  }
366
- exports.default = Runner;
400
+ export { default as BaseReporter } from './reporter.js';
401
+ export * from './types.js';
@@ -1,15 +1,18 @@
1
- import type { Options, Capabilities, Reporters } from '@wdio/types';
1
+ import type { Options, Capabilities } from '@wdio/types';
2
2
  /**
3
3
  * BaseReporter
4
4
  * responsible for initialising reporters for every testrun and propagating events
5
5
  * to all these reporters
6
6
  */
7
7
  export default class BaseReporter {
8
+ #private;
8
9
  private _config;
9
10
  private _cid;
10
11
  caps: Capabilities.RemoteCapability;
11
12
  private _reporters;
13
+ private listeners;
12
14
  constructor(_config: Options.Testrunner, _cid: string, caps: Capabilities.RemoteCapability);
15
+ initReporters(): Promise<void>;
13
16
  /**
14
17
  * emit events to all registered reporter and wdio launcer
15
18
  *
@@ -17,6 +20,7 @@ export default class BaseReporter {
17
20
  * @param {object} payload event payload
18
21
  */
19
22
  emit(e: string, payload: any): void;
23
+ onMessage(listener: (ev: any) => void): void;
20
24
  getLogFile(name: string): string | undefined;
21
25
  /**
22
26
  * return write stream object based on reporter name
@@ -32,6 +36,6 @@ export default class BaseReporter {
32
36
  /**
33
37
  * initialise reporters
34
38
  */
35
- initReporter(reporter: Reporters.ReporterEntry): Reporters.ReporterInstance;
39
+ private _loadReporter;
36
40
  }
37
41
  //# sourceMappingURL=reporter.d.ts.map
@@ -1 +1 @@
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;CAoElD"}
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAa,MAAM,aAAa,CAAA;AAKnE;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;;IAKzB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,IAAI;IACL,IAAI,EAAE,YAAY,CAAC,gBAAgB;IAN9C,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,SAAS,CAA4B;gBAGjC,OAAO,EAAE,OAAO,CAAC,UAAU,EAC3B,IAAI,EAAE,MAAM,EACb,IAAI,EAAE,YAAY,CAAC,gBAAgB;IAGxC,aAAa;IAMnB;;;;;OAKG;IACH,IAAI,CAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAuB7B,SAAS,CAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI;IAItC,UAAU,CAAE,IAAI,EAAE,MAAM;IAoCxB;;OAEG;IACH,oBAAoB,CAAE,QAAQ,EAAE,MAAM;yBAEc,OAAO;;IAoB3D;;;OAGG;IACH,WAAW;IA2BX;;OAEG;YACW,aAAa;CAoE9B"}
package/build/reporter.js CHANGED
@@ -1,25 +1,26 @@
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');
1
+ import path from 'node:path';
2
+ import logger from '@wdio/logger';
3
+ import { initialisePlugin } from '@wdio/utils';
4
+ const log = logger('@wdio/runner');
5
+ const mochaAllHooks = ['"before all" hook', '"after all" hook'];
11
6
  /**
12
7
  * BaseReporter
13
8
  * responsible for initialising reporters for every testrun and propagating events
14
9
  * to all these reporters
15
10
  */
16
- class BaseReporter {
11
+ export default class BaseReporter {
12
+ _config;
13
+ _cid;
14
+ caps;
15
+ _reporters = [];
16
+ listeners = [];
17
17
  constructor(_config, _cid, caps) {
18
18
  this._config = _config;
19
19
  this._cid = _cid;
20
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));
21
+ }
22
+ async initReporters() {
23
+ this._reporters = await Promise.all(this._config.reporters.map(this._loadReporter.bind(this)));
23
24
  }
24
25
  /**
25
26
  * emit events to all registered reporter and wdio launcer
@@ -32,9 +33,22 @@ class BaseReporter {
32
33
  /**
33
34
  * Send failure message (only once) in case of test or hook failure
34
35
  */
35
- (0, utils_2.sendFailureMessage)(e, payload);
36
+ const isTestError = e === 'test:fail';
37
+ const isHookError = (e === 'hook:end' &&
38
+ payload.error &&
39
+ mochaAllHooks.some(hook => payload.title.startsWith(hook)));
40
+ if (isTestError || isHookError) {
41
+ this.#emitData({
42
+ origin: 'reporter',
43
+ name: 'printFailureMessage',
44
+ content: payload
45
+ });
46
+ }
36
47
  this._reporters.forEach((reporter) => reporter.emit(e, payload));
37
48
  }
49
+ onMessage(listener) {
50
+ this.listeners.push(listener);
51
+ }
38
52
  getLogFile(name) {
39
53
  // clone the config to avoid changing original properties
40
54
  let options = Object.assign({}, this._config);
@@ -57,20 +71,30 @@ class BaseReporter {
57
71
  if (!options.outputDir) {
58
72
  return;
59
73
  }
60
- return path_1.default.join(options.outputDir, filename);
74
+ return path.join(options.outputDir, filename);
61
75
  }
62
76
  /**
63
77
  * return write stream object based on reporter name
64
78
  */
65
79
  getWriteStreamObject(reporter) {
66
80
  return {
67
- write: /* istanbul ignore next */ (content) => process.send({
81
+ write: /* istanbul ignore next */ (content) => this.#emitData({
68
82
  origin: 'reporter',
69
83
  name: reporter,
70
84
  content
71
85
  })
72
86
  };
73
87
  }
88
+ /**
89
+ * emit data either through process or listener
90
+ */
91
+ #emitData(payload) {
92
+ if (typeof process.send === 'function') {
93
+ return process.send(payload);
94
+ }
95
+ this.listeners.forEach((fn) => fn(payload));
96
+ return true;
97
+ }
74
98
  /**
75
99
  * wait for reporter to finish synchronization, e.g. when sending data asynchronous
76
100
  * to a server (e.g. sumo reporter)
@@ -101,7 +125,7 @@ class BaseReporter {
101
125
  /**
102
126
  * initialise reporters
103
127
  */
104
- initReporter(reporter) {
128
+ async _loadReporter(reporter) {
105
129
  let ReporterClass;
106
130
  let options = {};
107
131
  /**
@@ -115,7 +139,7 @@ class BaseReporter {
115
139
  * check if reporter was passed in from a file, e.g.
116
140
  *
117
141
  * ```js
118
- * const MyCustomReporter = require('/some/path/MyCustomReporter.js')
142
+ * import MyCustomReporter from '/some/path/MyCustomReporter.js'
119
143
  * exports.config
120
144
  * //...
121
145
  * reporters: [
@@ -151,7 +175,7 @@ class BaseReporter {
151
175
  * ```
152
176
  */
153
177
  if (typeof reporter === 'string') {
154
- ReporterClass = (0, utils_1.initialisePlugin)(reporter, 'reporter').default;
178
+ ReporterClass = (await initialisePlugin(reporter, 'reporter')).default;
155
179
  options.logFile = options.setLogFile
156
180
  ? options.setLogFile(this._cid, reporter)
157
181
  : typeof options.logFile === 'string'
@@ -166,4 +190,3 @@ class BaseReporter {
166
190
  throw new Error('Invalid reporters config');
167
191
  }
168
192
  }
169
- exports.default = BaseReporter;
@@ -0,0 +1,54 @@
1
+ import type { Options, Capabilities, Services } from '@wdio/types';
2
+ import BaseReporter from './reporter.js';
3
+ export declare type BeforeArgs = Parameters<Required<Services.HookFunctions>['before']>;
4
+ export declare type AfterArgs = Parameters<Required<Services.HookFunctions>['after']>;
5
+ export declare type BeforeSessionArgs = Parameters<Required<Services.HookFunctions>['beforeSession']>;
6
+ export declare type AfterSessionArgs = Parameters<Required<Services.HookFunctions>['afterSession']>;
7
+ interface Args extends Partial<Options.Testrunner> {
8
+ ignoredWorkerServices?: string[];
9
+ watch?: boolean;
10
+ }
11
+ export declare type RunParams = {
12
+ cid: string;
13
+ args: Args;
14
+ specs: string[];
15
+ caps: Capabilities.RemoteCapability;
16
+ configFile: string;
17
+ retries: number;
18
+ };
19
+ export interface TestFramework {
20
+ init: (cid: string, config: Options.Testrunner, specs: string[], capabilities: Capabilities.RemoteCapability, reporter: BaseReporter) => TestFramework;
21
+ run(): Promise<number>;
22
+ hasTests(): boolean;
23
+ }
24
+ declare type SingleCapability = {
25
+ capabilities: Capabilities.RemoteCapability;
26
+ };
27
+ export interface SingleConfigOption extends Omit<Options.Testrunner, 'capabilities'>, SingleCapability {
28
+ }
29
+ export declare type MultiRemoteCaps = Record<string, (Capabilities.DesiredCapabilities | Capabilities.W3CCapabilities) & {
30
+ sessionId?: string;
31
+ }>;
32
+ export interface SessionStartedMessage {
33
+ origin: 'worker';
34
+ name: 'sessionStarted';
35
+ content: {
36
+ sessionId: string;
37
+ isW3C: boolean;
38
+ protocol: string;
39
+ hostname: string;
40
+ port: number;
41
+ path: string;
42
+ isMultiremote: boolean;
43
+ injectGlobals: boolean;
44
+ capabilities: Capabilities.Capabilities;
45
+ };
46
+ cid?: string;
47
+ }
48
+ export interface SessionEndedMessage {
49
+ origin: 'worker';
50
+ name: 'sessionEnded';
51
+ cid: string;
52
+ }
53
+ export {};
54
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,YAAY,MAAM,eAAe,CAAA;AAExC,oBAAY,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;AAC/E,oBAAY,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAA;AAC7E,oBAAY,iBAAiB,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,eAAe,CAAC,CAAC,CAAA;AAC7F,oBAAY,gBAAgB,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,cAAc,CAAC,CAAC,CAAA;AAE3F,UAAU,IAAK,SAAQ,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC;IAC9C,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAA;IAChC,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,oBAAY,SAAS,GAAG;IACpB,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;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,CACF,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,CAAC,UAAU,EAC1B,KAAK,EAAE,MAAM,EAAE,EACf,YAAY,EAAE,YAAY,CAAC,gBAAgB,EAC3C,QAAQ,EAAE,YAAY,KACrB,aAAa,CAAA;IAClB,GAAG,IAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IACvB,QAAQ,IAAK,OAAO,CAAA;CACvB;AAED,aAAK,gBAAgB,GAAG;IAAE,YAAY,EAAE,YAAY,CAAC,gBAAgB,CAAA;CAAE,CAAA;AACvE,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,EAAE,gBAAgB;CAAG;AACzG,oBAAY,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,YAAY,CAAC,mBAAmB,GAAG,YAAY,CAAC,eAAe,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAExI,MAAM,WAAW,qBAAqB;IAClC,MAAM,EAAE,QAAQ,CAAA;IAChB,IAAI,EAAE,gBAAgB,CAAA;IACtB,OAAO,EAAE;QACL,SAAS,EAAE,MAAM,CAAA;QACjB,KAAK,EAAE,OAAO,CAAA;QACd,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,aAAa,EAAE,OAAO,CAAA;QACtB,aAAa,EAAE,OAAO,CAAA;QACtB,YAAY,EAAE,YAAY,CAAC,YAAY,CAAA;KAC1C,CAAC;IACF,GAAG,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,mBAAmB;IAChC,MAAM,EAAE,QAAQ,CAAA;IAChB,IAAI,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAA;CACd"}
package/build/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/build/utils.d.ts CHANGED
@@ -25,12 +25,6 @@ export declare function initialiseInstance(config: ConfigWithSessionId, capabili
25
25
  * @return {string[]} logTypes
26
26
  */
27
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
28
  declare type BrowserData = {
35
29
  sessionId: string;
36
30
  isW3C: boolean;
@@ -1 +1 @@
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"}
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;AAM9D,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,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 CHANGED
@@ -1,28 +1,21 @@
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');
1
+ import merge from 'deepmerge';
2
+ import logger from '@wdio/logger';
3
+ import { remote, multiremote, attach } from 'webdriverio';
4
+ import { DEFAULTS } from 'webdriver';
5
+ import { DEFAULT_CONFIGS } from '@wdio/config';
6
+ const log = logger('@wdio/runner');
13
7
  const MERGE_OPTIONS = { clone: false };
14
- const mochaAllHooks = ['"before all" hook', '"after all" hook'];
15
8
  /**
16
9
  * sanitizes wdio config from capability properties
17
10
  * @param {Object} caps desired session capabilities
18
11
  * @return {Object} sanitized caps
19
12
  */
20
- function sanitizeCaps(caps, filterOut) {
13
+ export function sanitizeCaps(caps, filterOut) {
21
14
  const defaultConfigsKeys = [
22
15
  // WDIO config keys
23
- ...Object.keys((0, config_1.DEFAULT_CONFIGS)()),
16
+ ...Object.keys(DEFAULT_CONFIGS()),
24
17
  // WebDriver config keys
25
- ...Object.keys(webdriver_1.DEFAULTS)
18
+ ...Object.keys(DEFAULTS)
26
19
  ];
27
20
  return Object.keys(caps).filter((key) => (
28
21
  /**
@@ -33,7 +26,6 @@ function sanitizeCaps(caps, filterOut) {
33
26
  return obj;
34
27
  }, {});
35
28
  }
36
- exports.sanitizeCaps = sanitizeCaps;
37
29
  /**
38
30
  * initialise browser instance depending whether remote or multiremote is requested
39
31
  * @param {Object} config configuration of sessions
@@ -41,7 +33,7 @@ exports.sanitizeCaps = sanitizeCaps;
41
33
  * @param {boolean} isMultiremote isMultiremote
42
34
  * @return {Promise} resolves with browser object
43
35
  */
44
- async function initialiseInstance(config, capabilities, isMultiremote) {
36
+ export async function initialiseInstance(config, capabilities, isMultiremote) {
45
37
  /**
46
38
  * check if config has sessionId and attach it to a running session if so
47
39
  */
@@ -52,7 +44,7 @@ async function initialiseInstance(config, capabilities, isMultiremote) {
52
44
  * propagate connection details defined by services or user in capabilities
53
45
  */
54
46
  const { protocol, hostname, port, path } = capabilities;
55
- return (0, webdriverio_1.attach)({ ...config, ...{ protocol, hostname, port, path } });
47
+ return attach({ ...config, ...{ protocol, hostname, port, path } });
56
48
  }
57
49
  if (!isMultiremote) {
58
50
  log.debug('init remote session');
@@ -61,30 +53,29 @@ async function initialiseInstance(config, capabilities, isMultiremote) {
61
53
  ...sanitizeCaps(capabilities, true),
62
54
  capabilities: sanitizeCaps(capabilities)
63
55
  };
64
- return (0, webdriverio_1.remote)(sessionConfig);
56
+ return remote(sessionConfig);
65
57
  }
66
58
  const options = {};
67
59
  log.debug('init multiremote session');
68
60
  // @ts-expect-error ToDo(Christian): can be removed?
69
61
  delete config.capabilities;
70
62
  for (let browserName of Object.keys(capabilities)) {
71
- options[browserName] = (0, deepmerge_1.default)(config, capabilities[browserName], MERGE_OPTIONS);
63
+ options[browserName] = merge(config, capabilities[browserName], MERGE_OPTIONS);
72
64
  }
73
- const browser = await (0, webdriverio_1.multiremote)(options, config);
65
+ const browser = await multiremote(options, config);
74
66
  for (let browserName of Object.keys(capabilities)) {
75
67
  // @ts-ignore allow random global browser names
76
68
  global[browserName] = browser[browserName];
77
69
  }
78
70
  return browser;
79
71
  }
80
- exports.initialiseInstance = initialiseInstance;
81
72
  /**
82
73
  * Filter logTypes based on filter
83
74
  * @param {string[]} excludeDriverLogs logTypes filter
84
75
  * @param {string[]} driverLogTypes available driver log types
85
76
  * @return {string[]} logTypes
86
77
  */
87
- function filterLogTypes(excludeDriverLogs, driverLogTypes) {
78
+ export function filterLogTypes(excludeDriverLogs, driverLogTypes) {
88
79
  let logTypes = [...driverLogTypes];
89
80
  if (Array.isArray(excludeDriverLogs)) {
90
81
  log.debug('filtering logTypes', logTypes);
@@ -98,32 +89,13 @@ function filterLogTypes(excludeDriverLogs, driverLogTypes) {
98
89
  }
99
90
  return logTypes;
100
91
  }
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
92
  /**
121
93
  * Gets { sessionId, isW3C, protocol, hostname, port, path, queryParams } of every Multiremote instance
122
94
  * @param {object} browser browser
123
95
  * @param {boolean} isMultiremote isMultiremote
124
96
  * @return {object}
125
97
  */
126
- function getInstancesData(browser, isMultiremote) {
98
+ export function getInstancesData(browser, isMultiremote) {
127
99
  if (!isMultiremote) {
128
100
  return;
129
101
  }
@@ -136,4 +108,3 @@ function getInstancesData(browser, isMultiremote) {
136
108
  });
137
109
  return instances;
138
110
  }
139
- exports.getInstancesData = getInstancesData;
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@wdio/runner",
3
- "version": "7.20.7",
3
+ "version": "7.20.8-alpha.504+428a9d729",
4
4
  "description": "A WebdriverIO service that runs tests in arbitrary environments",
5
5
  "author": "Christian Bromann <mail@bromann.dev>",
6
6
  "homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-runner",
7
7
  "license": "MIT",
8
- "main": "./build/index",
9
8
  "engines": {
10
- "node": ">=12.0.0"
9
+ "node": "^16.13 || >=18"
11
10
  },
12
11
  "repository": {
13
12
  "type": "git",
14
- "url": "git://github.com/webdriverio/webdriverio.git"
13
+ "url": "git://github.com/webdriverio/webdriverio.git",
14
+ "directory": "packages/wdio-runner"
15
15
  },
16
16
  "keywords": [
17
17
  "webdriver",
@@ -21,18 +21,24 @@
21
21
  "bugs": {
22
22
  "url": "https://github.com/webdriverio/webdriverio/issues"
23
23
  },
24
+ "type": "module",
25
+ "exports": "./build/index.js",
26
+ "types": "./build/index.d.ts",
27
+ "typeScriptVersion": "3.8.3",
24
28
  "dependencies": {
25
- "@wdio/config": "7.20.7",
26
- "@wdio/logger": "7.19.0",
27
- "@wdio/types": "7.20.7",
28
- "@wdio/utils": "7.20.7",
29
+ "@wdio/config": "7.20.8-alpha.504+428a9d729",
30
+ "@wdio/globals": "7.20.8-alpha.504+428a9d729",
31
+ "@wdio/logger": "7.20.8-alpha.504+428a9d729",
32
+ "@wdio/types": "7.20.8-alpha.504+428a9d729",
33
+ "@wdio/utils": "7.20.8-alpha.504+428a9d729",
29
34
  "deepmerge": "^4.0.0",
35
+ "expect-webdriverio": "^4.0.0-alpha.3",
30
36
  "gaze": "^1.1.2",
31
- "webdriver": "7.20.7",
32
- "webdriverio": "7.20.7"
37
+ "webdriver": "7.20.8-alpha.504+428a9d729",
38
+ "webdriverio": "7.20.8-alpha.504+428a9d729"
33
39
  },
34
40
  "publishConfig": {
35
41
  "access": "public"
36
42
  },
37
- "gitHead": "21b8b61453f4749d87eca3e4d7d6e5e2cb60f043"
43
+ "gitHead": "428a9d729ae6231968a60908732fa3f607d195e9"
38
44
  }