@wdio/cli 8.8.1 → 8.8.3
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/cjs/index.d.ts +15 -0
- package/build/cjs/index.d.ts.map +1 -0
- package/build/cjs/index.js +23 -0
- package/build/cjs/package.json +3 -0
- package/build/launcher.d.ts +13 -16
- package/build/launcher.d.ts.map +1 -1
- package/build/launcher.js +22 -22
- package/package.json +14 -5
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { RunCommandArguments } from '../types.js';
|
|
2
|
+
export declare class Launcher {
|
|
3
|
+
#private;
|
|
4
|
+
private configFilePath;
|
|
5
|
+
private args;
|
|
6
|
+
private isWatchMode;
|
|
7
|
+
constructor(configFilePath: string, args?: Partial<RunCommandArguments>, isWatchMode?: boolean);
|
|
8
|
+
/**
|
|
9
|
+
* run sequence
|
|
10
|
+
* @return {Promise} that only gets resolved with either an exitCode or an error
|
|
11
|
+
*/
|
|
12
|
+
run(): Promise<undefined | number>;
|
|
13
|
+
}
|
|
14
|
+
export declare function run(): Promise<false | void>;
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cjs/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEtD,qBAAa,QAAQ;;IAKb,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,WAAW;gBAFX,cAAc,EAAE,MAAM,EACtB,IAAI,GAAE,OAAO,CAAC,mBAAmB,CAAM,EACvC,WAAW,UAAQ;IAK/B;;;OAGG;IACG,GAAG,IAAI,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC;CAG3C;AAED,wBAAsB,GAAG,IAAI,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAGjD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export class Launcher {
|
|
2
|
+
configFilePath;
|
|
3
|
+
args;
|
|
4
|
+
isWatchMode;
|
|
5
|
+
#esmLauncher;
|
|
6
|
+
constructor(configFilePath, args = {}, isWatchMode = false) {
|
|
7
|
+
this.configFilePath = configFilePath;
|
|
8
|
+
this.args = args;
|
|
9
|
+
this.isWatchMode = isWatchMode;
|
|
10
|
+
import('../launcher.js').then(launcher => this.#esmLauncher = new launcher.default(this.configFilePath, this.args, this.isWatchMode));
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* run sequence
|
|
14
|
+
* @return {Promise} that only gets resolved with either an exitCode or an error
|
|
15
|
+
*/
|
|
16
|
+
async run() {
|
|
17
|
+
return this.#esmLauncher.run();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export async function run() {
|
|
21
|
+
const { run } = await import('../index.js');
|
|
22
|
+
return run();
|
|
23
|
+
}
|
package/build/launcher.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ConfigParser } from '@wdio/config';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Services } from '@wdio/types';
|
|
3
3
|
import CLInterface from './interface.js';
|
|
4
4
|
import type { RunCommandArguments } from './types.js';
|
|
5
|
-
interface EndMessage {
|
|
5
|
+
export interface EndMessage {
|
|
6
6
|
cid: string;
|
|
7
7
|
exitCode: number;
|
|
8
8
|
specs: string[];
|
|
@@ -27,35 +27,32 @@ declare class Launcher {
|
|
|
27
27
|
constructor(_configFilePath: string, _args?: Partial<RunCommandArguments>, _isWatchMode?: boolean);
|
|
28
28
|
/**
|
|
29
29
|
* run sequence
|
|
30
|
-
* @return {Promise} that only gets
|
|
30
|
+
* @return {Promise} that only gets resolved with either an exitCode or an error
|
|
31
31
|
*/
|
|
32
|
-
run(): Promise<number>;
|
|
32
|
+
run(): Promise<undefined | number>;
|
|
33
33
|
/**
|
|
34
34
|
* run without triggering onPrepare/onComplete hooks
|
|
35
35
|
*/
|
|
36
|
-
|
|
36
|
+
private _runMode;
|
|
37
37
|
/**
|
|
38
38
|
* Format the specs into an array of objects with files and retries
|
|
39
39
|
*/
|
|
40
|
-
|
|
41
|
-
files: string[];
|
|
42
|
-
retries: number;
|
|
43
|
-
}[];
|
|
40
|
+
private _formatSpecs;
|
|
44
41
|
/**
|
|
45
42
|
* run multiple single remote tests
|
|
46
43
|
* @return {Boolean} true if all specs have been run and all instances have finished
|
|
47
44
|
*/
|
|
48
|
-
|
|
45
|
+
private _runSpecs;
|
|
49
46
|
/**
|
|
50
47
|
* gets number of all running instances
|
|
51
48
|
* @return {number} number of running instances
|
|
52
49
|
*/
|
|
53
|
-
|
|
50
|
+
private _getNumberOfRunningInstances;
|
|
54
51
|
/**
|
|
55
52
|
* get number of total specs left to complete whole suites
|
|
56
53
|
* @return {number} specs left to complete suite
|
|
57
54
|
*/
|
|
58
|
-
|
|
55
|
+
private _getNumberOfSpecsLeft;
|
|
59
56
|
/**
|
|
60
57
|
* Start instance in a child process.
|
|
61
58
|
* @param {Array} specs Specs to run
|
|
@@ -63,14 +60,14 @@ declare class Launcher {
|
|
|
63
60
|
* @param {String} rid Runner ID override
|
|
64
61
|
* @param {Number} retries Number of retries remaining
|
|
65
62
|
*/
|
|
66
|
-
|
|
63
|
+
private _startInstance;
|
|
67
64
|
private _workerHookError;
|
|
68
65
|
/**
|
|
69
66
|
* generates a runner id
|
|
70
67
|
* @param {Number} cid capability id (unique identifier for a capability)
|
|
71
68
|
* @return {String} runner id (combination of cid and test id e.g. 0a, 0b, 1a, 1b ...)
|
|
72
69
|
*/
|
|
73
|
-
|
|
70
|
+
private _getRunnerId;
|
|
74
71
|
/**
|
|
75
72
|
* Close test runner process once all child processes have exited
|
|
76
73
|
* @param {Number} cid Capabilities ID
|
|
@@ -78,14 +75,14 @@ declare class Launcher {
|
|
|
78
75
|
* @param {Array} specs Specs that were run
|
|
79
76
|
* @param {Number} retries Number or retries remaining
|
|
80
77
|
*/
|
|
81
|
-
|
|
78
|
+
private _endHandler;
|
|
82
79
|
/**
|
|
83
80
|
* We need exitHandler to catch SIGINT / SIGTERM events.
|
|
84
81
|
* Make sure all started selenium sessions get closed properly and prevent
|
|
85
82
|
* having dead driver processes. To do so let the runner end its Selenium
|
|
86
83
|
* session first before killing
|
|
87
84
|
*/
|
|
88
|
-
|
|
85
|
+
private _exitHandler;
|
|
89
86
|
/**
|
|
90
87
|
* returns true if user stopped watch mode, ex with ctrl+c
|
|
91
88
|
* @returns {boolean}
|
package/build/launcher.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE3C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE3C,OAAO,KAAK,EAAyB,QAAQ,EAAE,MAAM,aAAa,CAAA;AAElE,OAAO,WAAW,MAAM,gBAAgB,CAAA;AAGxC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAkBrD,MAAM,WAAW,UAAU;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,CAAA;CAClB;AAED,cAAM,QAAQ;IAiBN,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,YAAY;IAlBjB,YAAY,EAAE,YAAY,CAAA;IAC1B,aAAa,UAAQ;IACrB,MAAM,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAA;IAChC,SAAS,CAAC,EAAE,WAAW,CAAA;IAE9B,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,wBAAwB,CAAQ;IACxC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,aAAa,CAAI;IAEzB,OAAO,CAAC,SAAS,CAAC,CAA4B;IAC9C,OAAO,CAAC,QAAQ,CAAC,CAAU;gBAGf,eAAe,EAAE,MAAM,EACvB,KAAK,GAAE,OAAO,CAAC,mBAAmB,CAAM,EACxC,YAAY,UAAQ;IAKhC;;;OAGG;IACG,GAAG,IAAI,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC;IAiGxC;;OAEG;IACH,OAAO,CAAC,QAAQ;IAyEhB;;OAEG;IACH,OAAO,CAAC,YAAY;IAepB;;;OAGG;IACH,OAAO,CAAC,SAAS;IAmEjB;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IAIpC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAI7B;;;;;;OAMG;YACW,cAAc;IA8F5B,OAAO,CAAC,gBAAgB;IAWxB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAOpB;;;;;;OAMG;YACW,WAAW;IA0DzB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAcpB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAG7B;AAED,eAAe,QAAQ,CAAA"}
|
package/build/launcher.js
CHANGED
|
@@ -31,7 +31,7 @@ class Launcher {
|
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
33
|
* run sequence
|
|
34
|
-
* @return {Promise} that only gets
|
|
34
|
+
* @return {Promise} that only gets resolved with either an exitCode or an error
|
|
35
35
|
*/
|
|
36
36
|
async run() {
|
|
37
37
|
await this.configParser.initialize(this._args);
|
|
@@ -61,7 +61,7 @@ class Launcher {
|
|
|
61
61
|
/**
|
|
62
62
|
* catches ctrl+c event
|
|
63
63
|
*/
|
|
64
|
-
exitHook(this.
|
|
64
|
+
exitHook(this._exitHandler.bind(this));
|
|
65
65
|
let exitCode = 0;
|
|
66
66
|
let error = undefined;
|
|
67
67
|
try {
|
|
@@ -80,7 +80,7 @@ class Launcher {
|
|
|
80
80
|
log.info('Run onPrepare hook');
|
|
81
81
|
await runLauncherHook(config.onPrepare, config, caps);
|
|
82
82
|
await runServiceHook(this._launcher, 'onPrepare', config, caps);
|
|
83
|
-
exitCode = await this.
|
|
83
|
+
exitCode = await this._runMode(config, caps);
|
|
84
84
|
/**
|
|
85
85
|
* run onComplete hook
|
|
86
86
|
* Even if it fails we still want to see result and end logger stream.
|
|
@@ -117,7 +117,7 @@ class Launcher {
|
|
|
117
117
|
/**
|
|
118
118
|
* run without triggering onPrepare/onComplete hooks
|
|
119
119
|
*/
|
|
120
|
-
|
|
120
|
+
_runMode(config, caps) {
|
|
121
121
|
/**
|
|
122
122
|
* fail if no caps were found
|
|
123
123
|
*/
|
|
@@ -142,7 +142,7 @@ class Launcher {
|
|
|
142
142
|
this._schedule.push({
|
|
143
143
|
cid: cid++,
|
|
144
144
|
caps: caps,
|
|
145
|
-
specs: this.
|
|
145
|
+
specs: this._formatSpecs(caps, specFileRetries),
|
|
146
146
|
availableInstances: config.maxInstances || 1,
|
|
147
147
|
runningInstances: 0
|
|
148
148
|
});
|
|
@@ -161,7 +161,7 @@ class Launcher {
|
|
|
161
161
|
this._schedule.push({
|
|
162
162
|
cid: cid++,
|
|
163
163
|
caps: capabilities,
|
|
164
|
-
specs: this.
|
|
164
|
+
specs: this._formatSpecs(capabilities, specFileRetries),
|
|
165
165
|
availableInstances,
|
|
166
166
|
runningInstances: 0
|
|
167
167
|
});
|
|
@@ -179,7 +179,7 @@ class Launcher {
|
|
|
179
179
|
/**
|
|
180
180
|
* return immediately if no spec was run
|
|
181
181
|
*/
|
|
182
|
-
if (this.
|
|
182
|
+
if (this._runSpecs()) {
|
|
183
183
|
resolve(0);
|
|
184
184
|
}
|
|
185
185
|
});
|
|
@@ -187,7 +187,7 @@ class Launcher {
|
|
|
187
187
|
/**
|
|
188
188
|
* Format the specs into an array of objects with files and retries
|
|
189
189
|
*/
|
|
190
|
-
|
|
190
|
+
_formatSpecs(capabilities, specFileRetries) {
|
|
191
191
|
const files = this.configParser.getSpecs(capabilities.specs, capabilities.exclude);
|
|
192
192
|
return files.map(file => {
|
|
193
193
|
if (typeof file === 'string') {
|
|
@@ -205,7 +205,7 @@ class Launcher {
|
|
|
205
205
|
* run multiple single remote tests
|
|
206
206
|
* @return {Boolean} true if all specs have been run and all instances have finished
|
|
207
207
|
*/
|
|
208
|
-
|
|
208
|
+
_runSpecs() {
|
|
209
209
|
/**
|
|
210
210
|
* stop spawning new processes when CTRL+C was triggered
|
|
211
211
|
*/
|
|
@@ -213,7 +213,7 @@ class Launcher {
|
|
|
213
213
|
return true;
|
|
214
214
|
}
|
|
215
215
|
const config = this.configParser.getConfig();
|
|
216
|
-
while (this.
|
|
216
|
+
while (this._getNumberOfRunningInstances() < config.maxInstances) {
|
|
217
217
|
const schedulableCaps = this._schedule
|
|
218
218
|
/**
|
|
219
219
|
* bail if number of errors exceeds allowed
|
|
@@ -232,7 +232,7 @@ class Launcher {
|
|
|
232
232
|
/**
|
|
233
233
|
* make sure complete number of running instances is not higher than general maxInstances number
|
|
234
234
|
*/
|
|
235
|
-
.filter(() => this.
|
|
235
|
+
.filter(() => this._getNumberOfRunningInstances() < config.maxInstances)
|
|
236
236
|
/**
|
|
237
237
|
* make sure the capability has available capacities
|
|
238
238
|
*/
|
|
@@ -252,24 +252,24 @@ class Launcher {
|
|
|
252
252
|
break;
|
|
253
253
|
}
|
|
254
254
|
const specs = schedulableCaps[0].specs.shift();
|
|
255
|
-
this.
|
|
255
|
+
this._startInstance(specs.files, schedulableCaps[0].caps, schedulableCaps[0].cid, specs.rid, specs.retries);
|
|
256
256
|
schedulableCaps[0].availableInstances--;
|
|
257
257
|
schedulableCaps[0].runningInstances++;
|
|
258
258
|
}
|
|
259
|
-
return this.
|
|
259
|
+
return this._getNumberOfRunningInstances() === 0 && this._getNumberOfSpecsLeft() === 0;
|
|
260
260
|
}
|
|
261
261
|
/**
|
|
262
262
|
* gets number of all running instances
|
|
263
263
|
* @return {number} number of running instances
|
|
264
264
|
*/
|
|
265
|
-
|
|
265
|
+
_getNumberOfRunningInstances() {
|
|
266
266
|
return this._schedule.map((a) => a.runningInstances).reduce((a, b) => a + b);
|
|
267
267
|
}
|
|
268
268
|
/**
|
|
269
269
|
* get number of total specs left to complete whole suites
|
|
270
270
|
* @return {number} specs left to complete suite
|
|
271
271
|
*/
|
|
272
|
-
|
|
272
|
+
_getNumberOfSpecsLeft() {
|
|
273
273
|
return this._schedule.map((a) => a.specs.length).reduce((a, b) => a + b);
|
|
274
274
|
}
|
|
275
275
|
/**
|
|
@@ -279,7 +279,7 @@ class Launcher {
|
|
|
279
279
|
* @param {String} rid Runner ID override
|
|
280
280
|
* @param {Number} retries Number of retries remaining
|
|
281
281
|
*/
|
|
282
|
-
async
|
|
282
|
+
async _startInstance(specs, caps, cid, rid, retries) {
|
|
283
283
|
if (!this.runner || !this.interface) {
|
|
284
284
|
throw new Error('Internal Error: no runner initialised, call run() first');
|
|
285
285
|
}
|
|
@@ -290,7 +290,7 @@ class Launcher {
|
|
|
290
290
|
}
|
|
291
291
|
// Retried tests receive the cid of the failing test as rid
|
|
292
292
|
// so they can run with the same cid of the failing test.
|
|
293
|
-
const runnerId = rid || this.
|
|
293
|
+
const runnerId = rid || this._getRunnerId(cid);
|
|
294
294
|
const processNumber = this._runnerStarted + 1;
|
|
295
295
|
// process.debugPort defaults to 5858 and is set even when process
|
|
296
296
|
// is not being debugged.
|
|
@@ -352,7 +352,7 @@ class Launcher {
|
|
|
352
352
|
});
|
|
353
353
|
worker.on('message', this.interface.onMessage.bind(this.interface));
|
|
354
354
|
worker.on('error', this.interface.onMessage.bind(this.interface));
|
|
355
|
-
worker.on('exit', this.
|
|
355
|
+
worker.on('exit', this._endHandler.bind(this));
|
|
356
356
|
}
|
|
357
357
|
_workerHookError(error) {
|
|
358
358
|
if (!this.interface) {
|
|
@@ -368,7 +368,7 @@ class Launcher {
|
|
|
368
368
|
* @param {Number} cid capability id (unique identifier for a capability)
|
|
369
369
|
* @return {String} runner id (combination of cid and test id e.g. 0a, 0b, 1a, 1b ...)
|
|
370
370
|
*/
|
|
371
|
-
|
|
371
|
+
_getRunnerId(cid) {
|
|
372
372
|
if (!this._rid[cid]) {
|
|
373
373
|
this._rid[cid] = 0;
|
|
374
374
|
}
|
|
@@ -381,7 +381,7 @@ class Launcher {
|
|
|
381
381
|
* @param {Array} specs Specs that were run
|
|
382
382
|
* @param {Number} retries Number or retries remaining
|
|
383
383
|
*/
|
|
384
|
-
async
|
|
384
|
+
async _endHandler({ cid: rid, exitCode, specs, retries }) {
|
|
385
385
|
const passed = this._isWatchModeHalted() || exitCode === 0;
|
|
386
386
|
if (!passed && retries > 0) {
|
|
387
387
|
// Default is true, so test for false explicitly
|
|
@@ -416,7 +416,7 @@ class Launcher {
|
|
|
416
416
|
* - there are specs to be executed
|
|
417
417
|
* - we are running watch mode
|
|
418
418
|
*/
|
|
419
|
-
const shouldRunSpecs = this.
|
|
419
|
+
const shouldRunSpecs = this._runSpecs();
|
|
420
420
|
const inWatchMode = this._isWatchMode && !this._hasTriggeredExitRoutine;
|
|
421
421
|
if (!shouldRunSpecs || inWatchMode) {
|
|
422
422
|
/**
|
|
@@ -437,7 +437,7 @@ class Launcher {
|
|
|
437
437
|
* having dead driver processes. To do so let the runner end its Selenium
|
|
438
438
|
* session first before killing
|
|
439
439
|
*/
|
|
440
|
-
|
|
440
|
+
_exitHandler(callback) {
|
|
441
441
|
if (!callback || !this.runner || !this.interface) {
|
|
442
442
|
return;
|
|
443
443
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/cli",
|
|
3
|
-
"version": "8.8.
|
|
3
|
+
"version": "8.8.3",
|
|
4
4
|
"description": "WebdriverIO testrunner command line interface",
|
|
5
5
|
"author": "Christian Bromann <mail@bromann.dev>",
|
|
6
6
|
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-cli",
|
|
@@ -28,17 +28,26 @@
|
|
|
28
28
|
"bugs": {
|
|
29
29
|
"url": "https://github.com/webdriverio/webdriverio/issues"
|
|
30
30
|
},
|
|
31
|
+
"main": "./build/cjs/index.js",
|
|
31
32
|
"type": "module",
|
|
33
|
+
"module": "./build/index.js",
|
|
32
34
|
"types": "./build/index.d.ts",
|
|
33
35
|
"exports": {
|
|
34
|
-
".":
|
|
36
|
+
".": [
|
|
37
|
+
{
|
|
38
|
+
"types": "./build/index.d.ts",
|
|
39
|
+
"import": "./build/index.js",
|
|
40
|
+
"require": "./build/cjs/index.js"
|
|
41
|
+
},
|
|
42
|
+
"./build/cjs/index.js"
|
|
43
|
+
],
|
|
35
44
|
"./package.json": "./package.json"
|
|
36
45
|
},
|
|
37
46
|
"typeScriptVersion": "3.8.3",
|
|
38
47
|
"dependencies": {
|
|
39
48
|
"@types/node": "^18.0.0",
|
|
40
49
|
"@wdio/config": "8.8.0",
|
|
41
|
-
"@wdio/globals": "8.8.
|
|
50
|
+
"@wdio/globals": "8.8.2",
|
|
42
51
|
"@wdio/logger": "8.6.6",
|
|
43
52
|
"@wdio/protocols": "8.8.1",
|
|
44
53
|
"@wdio/types": "8.8.0",
|
|
@@ -56,7 +65,7 @@
|
|
|
56
65
|
"lodash.union": "^4.6.0",
|
|
57
66
|
"read-pkg-up": "9.1.0",
|
|
58
67
|
"recursive-readdir": "^2.2.2",
|
|
59
|
-
"webdriverio": "8.8.
|
|
68
|
+
"webdriverio": "8.8.2",
|
|
60
69
|
"yargs": "^17.5.1",
|
|
61
70
|
"yarn-install": "^1.0.0"
|
|
62
71
|
},
|
|
@@ -73,5 +82,5 @@
|
|
|
73
82
|
"publishConfig": {
|
|
74
83
|
"access": "public"
|
|
75
84
|
},
|
|
76
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "7adb7f61baef3aaf7d023165089eb8d087b81da4"
|
|
77
86
|
}
|