@wdio/cli 7.17.0 → 7.18.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.
Files changed (47) hide show
  1. package/build/@types/yarn-install.d.ts +16 -0
  2. package/build/@types/yarn-install.d.ts.map +1 -0
  3. package/build/@types/yarn-install.js +1 -0
  4. package/build/commands/config.d.ts +64 -0
  5. package/build/commands/config.d.ts.map +1 -0
  6. package/build/commands/config.js +236 -0
  7. package/build/commands/install.d.ts +18 -0
  8. package/build/commands/install.d.ts.map +1 -0
  9. package/build/commands/install.js +112 -0
  10. package/build/commands/repl.d.ts +36 -0
  11. package/build/commands/repl.d.ts.map +1 -0
  12. package/build/commands/repl.js +62 -0
  13. package/build/commands/run.d.ts +172 -0
  14. package/build/commands/run.d.ts.map +1 -0
  15. package/build/commands/run.js +172 -0
  16. package/build/constants.d.ts +485 -0
  17. package/build/constants.d.ts.map +1 -0
  18. package/build/constants.js +370 -0
  19. package/build/index.d.ts +5 -0
  20. package/build/index.d.ts.map +1 -0
  21. package/build/index.js +88 -0
  22. package/build/interface.d.ts +77 -0
  23. package/build/interface.d.ts.map +1 -0
  24. package/build/interface.js +248 -0
  25. package/build/launcher.d.ts +96 -0
  26. package/build/launcher.d.ts.map +1 -0
  27. package/build/launcher.js +436 -0
  28. package/build/templates/afterTest.ejs +20 -0
  29. package/build/templates/exampleFiles/cucumber/features/login.feature +12 -0
  30. package/build/templates/exampleFiles/cucumber/step_definitions/steps.js.ejs +52 -0
  31. package/build/templates/exampleFiles/jasmine/example.e2e.js.ejs +42 -0
  32. package/build/templates/exampleFiles/mocha/example.e2e.js.ejs +42 -0
  33. package/build/templates/exampleFiles/pageobjects/login.page.js.ejs +44 -0
  34. package/build/templates/exampleFiles/pageobjects/page.js.ejs +13 -0
  35. package/build/templates/exampleFiles/pageobjects/secure.page.js.ejs +19 -0
  36. package/build/templates/reporters.ejs +14 -0
  37. package/build/templates/wdio.conf.tpl.ejs +457 -0
  38. package/build/types.d.ts +110 -0
  39. package/build/types.d.ts.map +1 -0
  40. package/build/types.js +2 -0
  41. package/build/utils.d.ts +87 -0
  42. package/build/utils.d.ts.map +1 -0
  43. package/build/utils.js +360 -0
  44. package/build/watcher.d.ts +34 -0
  45. package/build/watcher.d.ts.map +1 -0
  46. package/build/watcher.js +150 -0
  47. package/package.json +7 -7
@@ -0,0 +1,248 @@
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 chalk_1 = __importDefault(require("chalk"));
7
+ const events_1 = require("events");
8
+ const logger_1 = __importDefault(require("@wdio/logger"));
9
+ const utils_1 = require("./utils");
10
+ const log = (0, logger_1.default)('@wdio/cli');
11
+ class WDIOCLInterface extends events_1.EventEmitter {
12
+ constructor(_config, totalWorkerCnt, _isWatchMode = false) {
13
+ super();
14
+ this._config = _config;
15
+ this.totalWorkerCnt = totalWorkerCnt;
16
+ this._isWatchMode = _isWatchMode;
17
+ this.result = {
18
+ finished: 0,
19
+ passed: 0,
20
+ retries: 0,
21
+ failed: 0
22
+ };
23
+ this._jobs = new Map();
24
+ this._skippedSpecs = 0;
25
+ this._inDebugMode = false;
26
+ this._start = new Date();
27
+ this._messages = {
28
+ reporter: {},
29
+ debugger: {}
30
+ };
31
+ /**
32
+ * Colors can be forcibly enabled/disabled with env variable `FORCE_COLOR`
33
+ * `FORCE_COLOR=1` - forcibly enable colors
34
+ * `FORCE_COLOR=0` - forcibly disable colors
35
+ */
36
+ this.hasAnsiSupport = chalk_1.default.supportsColor.hasBasic;
37
+ this.totalWorkerCnt = totalWorkerCnt;
38
+ this._isWatchMode = _isWatchMode;
39
+ this._specFileRetries = _config.specFileRetries || 0;
40
+ this._specFileRetriesDelay = _config.specFileRetriesDelay || 0;
41
+ this.on('job:start', this.addJob.bind(this));
42
+ this.on('job:end', this.clearJob.bind(this));
43
+ this.setup();
44
+ this.onStart();
45
+ }
46
+ setup() {
47
+ this._jobs = new Map();
48
+ this._start = new Date();
49
+ /**
50
+ * The relationship between totalWorkerCnt and these counters are as follows:
51
+ * totalWorkerCnt - retries = finished = passed + failed
52
+ */
53
+ this.result = {
54
+ finished: 0,
55
+ passed: 0,
56
+ retries: 0,
57
+ failed: 0
58
+ };
59
+ this._messages = {
60
+ reporter: {},
61
+ debugger: {}
62
+ };
63
+ }
64
+ onStart() {
65
+ this.log(chalk_1.default.bold(`\nExecution of ${chalk_1.default.blue(this.totalWorkerCnt)} workers started at`), this._start.toISOString());
66
+ if (this._inDebugMode) {
67
+ this.log(chalk_1.default.bgYellow.black('DEBUG mode enabled!'));
68
+ }
69
+ if (this._isWatchMode) {
70
+ this.log(chalk_1.default.bgYellow.black('WATCH mode enabled!'));
71
+ }
72
+ this.log('');
73
+ }
74
+ onSpecRunning(rid) {
75
+ this.onJobComplete(rid, this._jobs.get(rid), 0, chalk_1.default.bold.cyan('RUNNING'));
76
+ }
77
+ onSpecRetry(rid, job, retries = 0) {
78
+ const delayMsg = this._specFileRetriesDelay > 0 ? ` after ${this._specFileRetriesDelay}s` : '';
79
+ this.onJobComplete(rid, job, retries, chalk_1.default.bold(chalk_1.default.yellow('RETRYING') + delayMsg));
80
+ }
81
+ onSpecPass(rid, job, retries = 0) {
82
+ this.onJobComplete(rid, job, retries, chalk_1.default.bold.green('PASSED'));
83
+ }
84
+ onSpecFailure(rid, job, retries = 0) {
85
+ this.onJobComplete(rid, job, retries, chalk_1.default.bold.red('FAILED'));
86
+ }
87
+ onSpecSkip(rid, job) {
88
+ this.onJobComplete(rid, job, 0, 'SKIPPED', log.info);
89
+ }
90
+ onJobComplete(cid, job, retries = 0, message = '', _logger = this.log) {
91
+ const details = [`[${cid}]`, message];
92
+ if (job) {
93
+ details.push('in', (0, utils_1.getRunnerName)(job.caps), this.getFilenames(job.specs));
94
+ }
95
+ if (retries > 0) {
96
+ details.push(`(${retries} retries)`);
97
+ }
98
+ return _logger(...details);
99
+ }
100
+ onTestError(payload) {
101
+ var _a, _b, _c;
102
+ const error = {
103
+ type: ((_a = payload.error) === null || _a === void 0 ? void 0 : _a.type) || 'Error',
104
+ message: ((_b = payload.error) === null || _b === void 0 ? void 0 : _b.message) || (typeof payload.error === 'string' ? payload.error : 'Unknown error.'),
105
+ stack: (_c = payload.error) === null || _c === void 0 ? void 0 : _c.stack
106
+ };
107
+ return this.log(`[${payload.cid}]`, `${chalk_1.default.red(error.type)} in "${payload.fullTitle}"\n${chalk_1.default.red(error.stack || error.message)}`);
108
+ }
109
+ getFilenames(specs = []) {
110
+ if (specs.length > 0) {
111
+ return '- ' + specs.join(', ').replace(new RegExp(`${process.cwd()}`, 'g'), '');
112
+ }
113
+ return '';
114
+ }
115
+ /**
116
+ * add job to interface
117
+ */
118
+ addJob({ cid, caps, specs, hasTests }) {
119
+ this._jobs.set(cid, { caps, specs, hasTests });
120
+ if (hasTests) {
121
+ this.onSpecRunning(cid);
122
+ }
123
+ else {
124
+ this._skippedSpecs++;
125
+ }
126
+ }
127
+ /**
128
+ * clear job from interface
129
+ */
130
+ clearJob({ cid, passed, retries }) {
131
+ const job = this._jobs.get(cid);
132
+ this._jobs.delete(cid);
133
+ const retryAttempts = this._specFileRetries - retries;
134
+ const retry = !passed && retries > 0;
135
+ if (!retry) {
136
+ this.result.finished++;
137
+ }
138
+ if (job && job.hasTests === false) {
139
+ return this.onSpecSkip(cid, job);
140
+ }
141
+ if (passed) {
142
+ this.result.passed++;
143
+ this.onSpecPass(cid, job, retryAttempts);
144
+ }
145
+ else if (retry) {
146
+ this.totalWorkerCnt++;
147
+ this.result.retries++;
148
+ this.onSpecRetry(cid, job, retryAttempts);
149
+ }
150
+ else {
151
+ this.result.failed++;
152
+ this.onSpecFailure(cid, job, retryAttempts);
153
+ }
154
+ }
155
+ /**
156
+ * for testing purposes call console log in a static method
157
+ */
158
+ log(...args) {
159
+ // eslint-disable-next-line no-console
160
+ console.log(...args);
161
+ return args;
162
+ }
163
+ logHookError(error) {
164
+ return this.log(`${chalk_1.default.red(error.name)} in "${error.origin}"\n${chalk_1.default.red(error.stack || error.message)}`);
165
+ }
166
+ /**
167
+ * event handler that is triggered when runner sends up events
168
+ */
169
+ onMessage(event) {
170
+ if (event.name === 'reporterRealTime') {
171
+ this.log(event.content);
172
+ return;
173
+ }
174
+ if (event.origin === 'debugger' && event.name === 'start') {
175
+ this.log(chalk_1.default.yellow(event.params.introMessage));
176
+ this._inDebugMode = true;
177
+ return this._inDebugMode;
178
+ }
179
+ if (event.origin === 'debugger' && event.name === 'stop') {
180
+ this._inDebugMode = false;
181
+ return this._inDebugMode;
182
+ }
183
+ if (event.name === 'testFrameworkInit') {
184
+ return this.emit('job:start', event.content);
185
+ }
186
+ if (!event.origin) {
187
+ return log.warn(`Can't identify message from worker: ${JSON.stringify(event)}, ignoring!`);
188
+ }
189
+ if (event.origin === 'worker' && event.name === 'error') {
190
+ return this.log(`[${event.cid}]`, chalk_1.default.white.bgRed.bold(' Error: '), event.content.message || event.content.stack || event.content);
191
+ }
192
+ if (event.origin !== 'reporter' && event.origin !== 'debugger') {
193
+ return this.log(event.cid, event.origin, event.name, event.content);
194
+ }
195
+ if (event.name === 'printFailureMessage') {
196
+ return this.onTestError(event.content);
197
+ }
198
+ if (!this._messages[event.origin][event.name]) {
199
+ this._messages[event.origin][event.name] = [];
200
+ }
201
+ this._messages[event.origin][event.name].push(event.content);
202
+ if (this._isWatchMode) {
203
+ this.printReporters();
204
+ }
205
+ }
206
+ sigintTrigger() {
207
+ /**
208
+ * allow to exit repl mode via Ctrl+C
209
+ */
210
+ if (this._inDebugMode) {
211
+ return false;
212
+ }
213
+ const isRunning = this._jobs.size !== 0;
214
+ const shutdownMessage = isRunning
215
+ ? 'Ending WebDriver sessions gracefully ...\n' +
216
+ '(press ctrl+c again to hard kill the runner)'
217
+ : 'Ended WebDriver sessions gracefully after a SIGINT signal was received!';
218
+ return this.log('\n\n' + shutdownMessage);
219
+ }
220
+ printReporters() {
221
+ /**
222
+ * print reporter output
223
+ */
224
+ const reporter = this._messages.reporter;
225
+ this._messages.reporter = {};
226
+ for (const [reporterName, messages] of Object.entries(reporter)) {
227
+ this.log('\n', chalk_1.default.bold.magenta(`"${reporterName}" Reporter:`));
228
+ this.log(messages.join(''));
229
+ }
230
+ }
231
+ printSummary() {
232
+ const totalJobs = this.totalWorkerCnt - this.result.retries;
233
+ const elapsed = (new Date(Date.now() - this._start.getTime())).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];
234
+ const retries = this.result.retries ? chalk_1.default.yellow(this.result.retries, 'retries') + ', ' : '';
235
+ const failed = this.result.failed ? chalk_1.default.red(this.result.failed, 'failed') + ', ' : '';
236
+ const skipped = this._skippedSpecs > 0 ? chalk_1.default.gray(this._skippedSpecs, 'skipped') + ', ' : '';
237
+ const percentCompleted = totalJobs ? Math.round(this.result.finished / totalJobs * 100) : 0;
238
+ return this.log('\nSpec Files:\t', chalk_1.default.green(this.result.passed, 'passed') + ', ' + retries + failed + skipped + totalJobs, 'total', `(${percentCompleted}% completed)`, 'in', elapsed, '\n');
239
+ }
240
+ finalise() {
241
+ if (this._isWatchMode) {
242
+ return;
243
+ }
244
+ this.printReporters();
245
+ this.printSummary();
246
+ }
247
+ }
248
+ exports.default = WDIOCLInterface;
@@ -0,0 +1,96 @@
1
+ import { ConfigParser } from '@wdio/config';
2
+ import type { Options, Capabilities, Services } from '@wdio/types';
3
+ import CLInterface from './interface';
4
+ import { RunCommandArguments } from './types';
5
+ interface EndMessage {
6
+ cid: string;
7
+ exitCode: number;
8
+ specs: string[];
9
+ retries: number;
10
+ }
11
+ declare class Launcher {
12
+ private _configFilePath;
13
+ private _args;
14
+ private _isWatchMode;
15
+ configParser: ConfigParser;
16
+ isMultiremote: boolean;
17
+ runner: Services.RunnerInstance;
18
+ interface: CLInterface;
19
+ private _exitCode;
20
+ private _hasTriggeredExitRoutine;
21
+ private _schedule;
22
+ private _rid;
23
+ private _runnerStarted;
24
+ private _runnerFailed;
25
+ private _launcher?;
26
+ private _resolve?;
27
+ constructor(_configFilePath: string, _args?: Partial<RunCommandArguments>, _isWatchMode?: boolean);
28
+ /**
29
+ * run sequence
30
+ * @return {Promise} that only gets resolves with either an exitCode or an error
31
+ */
32
+ run(): Promise<number>;
33
+ /**
34
+ * run without triggering onPrepare/onComplete hooks
35
+ */
36
+ runMode(config: Required<Options.Testrunner>, caps: Capabilities.RemoteCapabilities): Promise<number>;
37
+ /**
38
+ * Format the specs into an array of objects with files and retries
39
+ */
40
+ formatSpecs(capabilities: (Capabilities.DesiredCapabilities | Capabilities.W3CCapabilities | Capabilities.RemoteCapabilities), specFileRetries: number): {
41
+ files: string[];
42
+ retries: number;
43
+ }[];
44
+ /**
45
+ * run multiple single remote tests
46
+ * @return {Boolean} true if all specs have been run and all instances have finished
47
+ */
48
+ runSpecs(): boolean;
49
+ /**
50
+ * gets number of all running instances
51
+ * @return {number} number of running instances
52
+ */
53
+ getNumberOfRunningInstances(): number;
54
+ /**
55
+ * get number of total specs left to complete whole suites
56
+ * @return {number} specs left to complete suite
57
+ */
58
+ getNumberOfSpecsLeft(): number;
59
+ /**
60
+ * Start instance in a child process.
61
+ * @param {Array} specs Specs to run
62
+ * @param {Number} cid Capabilities ID
63
+ * @param {String} rid Runner ID override
64
+ * @param {Number} retries Number of retries remaining
65
+ */
66
+ startInstance(specs: string[], caps: Capabilities.DesiredCapabilities | Capabilities.W3CCapabilities | Capabilities.MultiRemoteCapabilities, cid: number, rid: string | undefined, retries: number): Promise<void>;
67
+ private _workerHookError;
68
+ /**
69
+ * generates a runner id
70
+ * @param {Number} cid capability id (unique identifier for a capability)
71
+ * @return {String} runner id (combination of cid and test id e.g. 0a, 0b, 1a, 1b ...)
72
+ */
73
+ getRunnerId(cid: number): string;
74
+ /**
75
+ * Close test runner process once all child processes have exited
76
+ * @param {Number} cid Capabilities ID
77
+ * @param {Number} exitCode exit code of child process
78
+ * @param {Array} specs Specs that were run
79
+ * @param {Number} retries Number or retries remaining
80
+ */
81
+ endHandler({ cid: rid, exitCode, specs, retries }: EndMessage): Promise<void>;
82
+ /**
83
+ * We need exitHandler to catch SIGINT / SIGTERM events.
84
+ * Make sure all started selenium sessions get closed properly and prevent
85
+ * having dead driver processes. To do so let the runner end its Selenium
86
+ * session first before killing
87
+ */
88
+ exitHandler(callback?: (value: void) => void): void | Promise<void>;
89
+ /**
90
+ * returns true if user stopped watch mode, ex with ctrl+c
91
+ * @returns {boolean}
92
+ */
93
+ private _isWatchModeHalted;
94
+ }
95
+ export default Launcher;
96
+ //# sourceMappingURL=launcher.d.ts.map
@@ -0,0 +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,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAElE,OAAO,WAAW,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAmB7C,UAAU,UAAU;IAChB,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;IAlBxB,YAAY,EAAE,YAAY,CAAA;IAC1B,aAAa,EAAE,OAAO,CAAA;IACtB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAA;IAC/B,SAAS,EAAE,WAAW,CAAA;IAEtB,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;IA8ChC;;;OAGG;IACG,GAAG;IA+DT;;OAEG;IACH,OAAO,CAAE,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAkEtG;;OAEG;IACH,WAAW,CAAC,YAAY,EAAE,CAAC,YAAY,CAAC,mBAAmB,GAAG,YAAY,CAAC,eAAe,GAAG,YAAY,CAAC,kBAAkB,CAAC,EAAE,eAAe,EAAE,MAAM;;;;IAgBtJ;;;OAGG;IACH,QAAQ;IAmER;;;OAGG;IACH,2BAA2B;IAI3B;;;OAGG;IACH,oBAAoB;IAIpB;;;;;;OAMG;IACG,aAAa,CACf,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,YAAY,CAAC,mBAAmB,GAAG,YAAY,CAAC,eAAe,GAAG,YAAY,CAAC,uBAAuB,EAC5G,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,OAAO,EAAE,MAAM;IA+EnB,OAAO,CAAC,gBAAgB;IAOxB;;;;OAIG;IACH,WAAW,CAAE,GAAG,EAAE,MAAM;IAOxB;;;;;;OAMG;IACG,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,UAAU;IAkDnE;;;;;OAKG;IACH,WAAW,CAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI;IAc7C;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAG7B;AAED,eAAe,QAAQ,CAAA"}