@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.
- package/build/browser.d.ts +29 -0
- package/build/browser.d.ts.map +1 -0
- package/build/browser.js +104 -0
- package/build/index.d.ts +6 -33
- package/build/index.d.ts.map +1 -1
- package/build/index.js +124 -89
- package/build/reporter.d.ts +6 -2
- package/build/reporter.d.ts.map +1 -1
- package/build/reporter.js +43 -20
- package/build/types.d.ts +54 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +1 -0
- package/build/utils.d.ts +0 -6
- package/build/utils.d.ts.map +1 -1
- package/build/utils.js +16 -45
- package/package.json +17 -11
|
@@ -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"}
|
package/build/browser.js
ADDED
|
@@ -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 {
|
|
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
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
78
|
-
this._reporter = new
|
|
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 = (
|
|
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
|
|
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
|
|
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 =
|
|
139
|
+
const instances = getInstancesData(browser, isMultiremote);
|
|
142
140
|
process.send({
|
|
143
141
|
origin: 'worker',
|
|
144
142
|
name: 'sessionStarted',
|
|
145
|
-
content: {
|
|
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
|
-
|
|
194
|
-
|
|
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
|
-
|
|
223
|
-
browser
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
!
|
|
273
|
+
!this._browser?.sessionId ||
|
|
255
274
|
/**
|
|
256
275
|
* driver supports it
|
|
257
276
|
*/
|
|
258
|
-
typeof
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
323
|
-
const hasSessionId = Boolean(
|
|
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(
|
|
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
|
-
:
|
|
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 =
|
|
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
|
|
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(
|
|
388
|
+
multiremoteBrowser.instances.forEach((browserName) => {
|
|
354
389
|
// @ts-ignore sessionId is usually required
|
|
355
|
-
delete multiremoteBrowser[
|
|
390
|
+
delete multiremoteBrowser[browserName].sessionId;
|
|
356
391
|
});
|
|
357
392
|
}
|
|
358
|
-
else {
|
|
359
|
-
|
|
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
|
|
397
|
+
await executeHooksWithArgs('afterSession', this._config.afterSession, afterSessionArgs);
|
|
364
398
|
}
|
|
365
399
|
}
|
|
366
|
-
|
|
400
|
+
export { default as BaseReporter } from './reporter.js';
|
|
401
|
+
export * from './types.js';
|
package/build/reporter.d.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import type { Options, Capabilities
|
|
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
|
-
|
|
39
|
+
private _loadReporter;
|
|
36
40
|
}
|
|
37
41
|
//# sourceMappingURL=reporter.d.ts.map
|
package/build/reporter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
22
|
-
|
|
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
|
-
|
|
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
|
|
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) =>
|
|
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
|
-
|
|
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
|
-
*
|
|
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 = (
|
|
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;
|
package/build/types.d.ts
ADDED
|
@@ -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;
|
package/build/utils.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
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(
|
|
16
|
+
...Object.keys(DEFAULT_CONFIGS()),
|
|
24
17
|
// WebDriver config keys
|
|
25
|
-
...Object.keys(
|
|
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
|
|
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
|
|
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] = (
|
|
63
|
+
options[browserName] = merge(config, capabilities[browserName], MERGE_OPTIONS);
|
|
72
64
|
}
|
|
73
|
-
const browser = await
|
|
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.
|
|
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": ">=
|
|
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.
|
|
26
|
-
"@wdio/
|
|
27
|
-
"@wdio/
|
|
28
|
-
"@wdio/
|
|
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.
|
|
32
|
-
"webdriverio": "7.20.
|
|
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": "
|
|
43
|
+
"gitHead": "428a9d729ae6231968a60908732fa3f607d195e9"
|
|
38
44
|
}
|