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