How to use runServiceHook method in Webdriverio

Best JavaScript code snippet using webdriverio-monorepo

Run Webdriverio automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

utils.test.js

Source: utils.test.js Github

copy
1import logger from '@wdio/logger'
2
3import { filterPackageName, getLauncher, runServiceHook, getRunnerName } from '../src/utils'
4
5jest.mock('@wdio/config', () => {
6    class LauncherMock {
7        constructor () {
8            this.onPrepare = jest.fn()
9            this.onComplete = jest.fn()
10        }
11    }
12
13    return {
14        initialisePlugin: jest.fn()
15            .mockImplementationOnce(
16                () => LauncherMock)
17            .mockImplementationOnce(
18                () => undefined)
19            .mockImplementationOnce(
20                () => { throw new Error('Couldn\'t find plugin') })
21            .mockImplementationOnce(() => { throw new Error('buhh') })
22    }
23})
24
25test('filterPackageName', () => {
26    const reporter = [
27        ' dot - https://www.npmjs.com/package/@wdio/dot-reporter',
28        ' spec - https://www.npmjs.com/package/@wdio/spec-reporter',
29        ' junit - https://www.npmjs.com/package/@wdio/junit-reporter',
30        ' random - https://www.npmjs.com/package/wdio-random-reporter'
31    ]
32    expect(filterPackageName('reporter')(reporter)).toEqual([
33        '@wdio/dot-reporter',
34        '@wdio/spec-reporter',
35        '@wdio/junit-reporter',
36        'wdio-random-reporter'
37    ])
38})
39
40test('getLauncher', () => {
41    expect(getLauncher({})).toEqual([])
42
43    const inlineService = {
44        onPrepare: jest.fn(),
45        beforeTest: jest.fn()
46    }
47    expect(getLauncher({
48        services: [
49            inlineService,
50            'unscoped',
51            'scoped',
52            'non-existing'
53        ]
54    })).toHaveLength(2)
55})
56
57test('getLauncher not failing on syntax error', () => {
58    expect(() => getLauncher({
59        services: ['other-unscoped']
60    })).toHaveLength(0)
61    expect(logger().error).toBeCalledTimes(1)
62})
63
64test('getLauncher sets correct service scope', () => {
65    const hookSuccess = jest.fn()
66
67    const inlineService = {
68        onPrepare() {
69            this._otherMethod()
70        },
71        _otherMethod: hookSuccess
72    }
73
74    const launcher = getLauncher({
75        services: [
76            inlineService
77        ]
78    })
79
80    runServiceHook(launcher, 'onPrepare', 1, true, 'abc')
81    expect(hookSuccess).toBeCalledTimes(1)
82})
83
84test('runServiceHook', () => {
85    const hookSuccess = jest.fn()
86    const hookFailing = jest.fn().mockImplementation(() => { throw new Error('buhh') })
87    runServiceHook([
88        { onPrepare: hookSuccess },
89        { onPrepare: 'foobar' },
90        { onPrepare: hookFailing },
91        { onComplete: hookSuccess }
92    ], 'onPrepare', 1, true, 'abc')
93    expect(hookSuccess).toBeCalledTimes(1)
94    expect(hookFailing).toBeCalledTimes(1)
95})
96
97test('getRunnerName', () => {
98    expect(getRunnerName({ browserName: 'foobar' })).toBe('foobar')
99    expect(getRunnerName({ appPackage: 'foobar' })).toBe('foobar')
100    expect(getRunnerName({ appWaitActivity: 'foobar' })).toBe('foobar')
101    expect(getRunnerName({ app: 'foobar' })).toBe('foobar')
102    expect(getRunnerName({ platformName: 'foobar' })).toBe('foobar')
103    expect(getRunnerName({})).toBe('undefined')
104})
105
Full Screen

launcher.js

Source: launcher.js Github

copy
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4    value: true
5});
6
7var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
8
9var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
10
11var _regenerator = require('babel-runtime/regenerator');
12
13var _regenerator2 = _interopRequireDefault(_regenerator);
14
15var _promise = require('babel-runtime/core-js/promise');
16
17var _promise2 = _interopRequireDefault(_promise);
18
19var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
20
21var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
22
23var _assign = require('babel-runtime/core-js/object/assign');
24
25var _assign2 = _interopRequireDefault(_assign);
26
27var _keys = require('babel-runtime/core-js/object/keys');
28
29var _keys2 = _interopRequireDefault(_keys);
30
31var _getIterator2 = require('babel-runtime/core-js/get-iterator');
32
33var _getIterator3 = _interopRequireDefault(_getIterator2);
34
35var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
36
37var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
38
39var _createClass2 = require('babel-runtime/helpers/createClass');
40
41var _createClass3 = _interopRequireDefault(_createClass2);
42
43var _path = require('path');
44
45var _path2 = _interopRequireDefault(_path);
46
47var _child_process = require('child_process');
48
49var _child_process2 = _interopRequireDefault(_child_process);
50
51var _ConfigParser = require('./utils/ConfigParser');
52
53var _ConfigParser2 = _interopRequireDefault(_ConfigParser);
54
55var _BaseReporter = require('./utils/BaseReporter');
56
57var _BaseReporter2 = _interopRequireDefault(_BaseReporter);
58
59function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
60
61var Launcher = function () {
62    function Launcher(configFile, argv) {
63        (0, _classCallCheck3.default)(this, Launcher);
64
65        this.configParser = new _ConfigParser2.default();
66        this.configParser.addConfigFile(configFile);
67        this.configParser.merge(argv);
68
69        this.reporters = this.initReporters();
70
71        this.argv = argv;
72        this.configFile = configFile;
73
74        this.exitCode = 0;
75        this.hasTriggeredExitRoutine = false;
76        this.hasStartedAnyProcess = false;
77        this.processes = [];
78        this.schedule = [];
79        this.rid = [];
80        this.processesStarted = 0;
81        this.runnerFailed = 0;
82    }
83
84    /**
85     * check if multiremote or wdio test
86     */
87
88
89    (0, _createClass3.default)(Launcher, [{
90        key: 'isMultiremote',
91        value: function isMultiremote() {
92            var caps = this.configParser.getCapabilities();
93            return !Array.isArray(caps);
94        }
95
96        /**
97         * initialise reporters
98         */
99
100    }, {
101        key: 'initReporters',
102        value: function initReporters() {
103            var reporter = new _BaseReporter2.default();
104            var config = this.configParser.getConfig();
105
106            /**
107             * if no reporter is set or config property is in a wrong format
108             * just use the dot reporter
109             */
110            if (!config.reporters || !Array.isArray(config.reporters) || !config.reporters.length) {
111                config.reporters = ['dot'];
112            }
113
114            var reporters = {};
115
116            var _iteratorNormalCompletion = true;
117            var _didIteratorError = false;
118            var _iteratorError = undefined;
119
120            try {
121                for (var _iterator = (0, _getIterator3.default)(config.reporters), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
122                    var reporterName = _step.value;
123
124                    var Reporter = void 0;
125                    if (typeof reporterName === 'function') {
126                        Reporter = reporterName;
127                        if (!Reporter.reporterName) {
128                            throw new Error('Custom reporters must export a unique \'reporterName\' property');
129                        }
130                        reporters[Reporter.reporterName] = Reporter;
131                    } else if (typeof reporterName === 'string') {
132                        try {
133                            Reporter = require('wdio-' + reporterName + '-reporter');
134                        } catch (e) {
135                            throw new Error('reporter "wdio-' + reporterName + '-reporter" is not installed. Error: ' + e.stack);
136                        }
137                        reporters[reporterName] = Reporter;
138                    }
139                    if (!Reporter) {
140                        throw new Error('config.reporters must be an array of strings or functions, but got \'' + typeof reporterName + '\': ' + reporterName);
141                    }
142                }
143
144                /**
145                 * if no reporter options are set or property is in a wrong format default to
146                 * empty object
147                 */
148            } catch (err) {
149                _didIteratorError = true;
150                _iteratorError = err;
151            } finally {
152                try {
153                    if (!_iteratorNormalCompletion && _iterator.return) {
154                        _iterator.return();
155                    }
156                } finally {
157                    if (_didIteratorError) {
158                        throw _iteratorError;
159                    }
160                }
161            }
162
163            if (!config.reporterOptions || typeof config.reporterOptions !== 'object') {
164                config.reporterOptions = {};
165            }
166
167            for (var _reporterName in reporters) {
168                var Reporter = reporters[_reporterName];
169                var reporterOptions = {};
170                var _iteratorNormalCompletion2 = true;
171                var _didIteratorError2 = false;
172                var _iteratorError2 = undefined;
173
174                try {
175                    for (var _iterator2 = (0, _getIterator3.default)((0, _keys2.default)(config.reporterOptions)), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
176                        var option = _step2.value;
177
178                        if (option === _reporterName && typeof config.reporterOptions[_reporterName] === 'object') {
179                            // Copy over options specifically for this reporter type
180                            reporterOptions = (0, _assign2.default)(reporterOptions, config.reporterOptions[_reporterName]);
181                        } else if (reporters[option]) {
182                            // Don't copy options for other reporters
183                            continue;
184                        } else {
185                            // Copy over generic options
186                            reporterOptions[option] = config.reporterOptions[option];
187                        }
188                    }
189                } catch (err) {
190                    _didIteratorError2 = true;
191                    _iteratorError2 = err;
192                } finally {
193                    try {
194                        if (!_iteratorNormalCompletion2 && _iterator2.return) {
195                            _iterator2.return();
196                        }
197                    } finally {
198                        if (_didIteratorError2) {
199                            throw _iteratorError2;
200                        }
201                    }
202                }
203
204                reporter.add(new Reporter(reporter, config, reporterOptions));
205            }
206
207            return reporter;
208        }
209
210        /**
211         * run sequence
212         * @return  {Promise} that only gets resolves with either an exitCode or an error
213         */
214
215    }, {
216        key: 'run',
217        value: function () {
218            var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee() {
219                var _this = this;
220
221                var config, caps, launcher, _exitCode, cid, _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, capabilities, exitCode;
222
223                return _regenerator2.default.wrap(function _callee$(_context) {
224                    while (1) {
225                        switch (_context.prev = _context.next) {
226                            case 0:
227                                config = this.configParser.getConfig();
228                                caps = this.configParser.getCapabilities();
229                                launcher = this.getLauncher(config);
230
231
232                                this.reporters.handleEvent('start', {
233                                    isMultiremote: this.isMultiremote(),
234                                    capabilities: caps,
235                                    config: config
236                                });
237
238                                /**
239                                 * run onPrepare hook
240                                 */
241                                _context.next = 6;
242                                return config.onPrepare(config, caps);
243
244                            case 6:
245                                _context.next = 8;
246                                return this.runServiceHook(launcher, 'onPrepare', config, caps);
247
248                            case 8:
249                                if (!this.isMultiremote()) {
250                                    _context.next = 17;
251                                    break;
252                                }
253
254                                _context.next = 11;
255                                return new _promise2.default(function (resolve) {
256                                    _this.resolve = resolve;
257                                    _this.startInstance(_this.configParser.getSpecs(), caps, 0);
258                                });
259
260                            case 11:
261                                _exitCode = _context.sent;
262                                _context.next = 14;
263                                return this.runServiceHook(launcher, 'onComplete', _exitCode);
264
265                            case 14:
266                                _context.next = 16;
267                                return config.onComplete(_exitCode);
268
269                            case 16:
270                                return _context.abrupt('return', _exitCode);
271
272                            case 17:
273
274                                /**
275                                 * schedule test runs
276                                 */
277                                cid = 0;
278                                _iteratorNormalCompletion3 = true;
279                                _didIteratorError3 = false;
280                                _iteratorError3 = undefined;
281                                _context.prev = 21;
282
283                                for (_iterator3 = (0, _getIterator3.default)(caps); !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
284                                    capabilities = _step3.value;
285
286                                    this.schedule.push({
287                                        cid: cid++,
288                                        caps: capabilities,
289                                        specs: this.configParser.getSpecs(capabilities.specs, capabilities.exclude),
290                                        availableInstances: capabilities.maxInstances || config.maxInstancesPerCapability,
291                                        runningInstances: 0,
292                                        seleniumServer: { host: config.host, port: config.port, protocol: config.protocol }
293                                    });
294                                }
295
296                                /**
297                                 * catches ctrl+c event
298                                 */
299                                _context.next = 29;
300                                break;
301
302                            case 25:
303                                _context.prev = 25;
304                                _context.t0 = _context['catch'](21);
305                                _didIteratorError3 = true;
306                                _iteratorError3 = _context.t0;
307
308                            case 29:
309                                _context.prev = 29;
310                                _context.prev = 30;
311
312                                if (!_iteratorNormalCompletion3 && _iterator3.return) {
313                                    _iterator3.return();
314                                }
315
316                            case 32:
317                                _context.prev = 32;
318
319                                if (!_didIteratorError3) {
320                                    _context.next = 35;
321                                    break;
322                                }
323
324                                throw _iteratorError3;
325
326                            case 35:
327                                return _context.finish(32);
328
329                            case 36:
330                                return _context.finish(29);
331
332                            case 37:
333                                process.on('SIGINT', this.exitHandler.bind(this));
334
335                                /**
336                                 * make sure the program will not close instantly
337                                 */
338                                if (process.stdin.isPaused()) {
339                                    process.stdin.resume();
340                                }
341
342                                _context.next = 41;
343                                return new _promise2.default(function (resolve) {
344                                    _this.resolve = resolve;
345
346                                    /**
347                                     * return immediatelly if no spec was run
348                                     */
349                                    if (_this.runSpecs()) {
350                                        resolve(0);
351                                    }
352                                });
353
354                            case 41:
355                                exitCode = _context.sent;
356                                _context.next = 44;
357                                return this.runServiceHook(launcher, 'onComplete', exitCode);
358
359                            case 44:
360                                _context.next = 46;
361                                return config.onComplete(exitCode);
362
363                            case 46:
364                                return _context.abrupt('return', exitCode);
365
366                            case 47:
367                            case 'end':
368                                return _context.stop();
369                        }
370                    }
371                }, _callee, this, [[21, 25, 29, 37], [30,, 32, 36]]);
372            }));
373
374            function run() {
375                return _ref.apply(this, arguments);
376            }
377
378            return run;
379        }()
380
381        /**
382         * run service launch sequences
383         */
384
385    }, {
386        key: 'runServiceHook',
387        value: function () {
388            var _ref2 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(launcher, hookName) {
389                for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
390                    args[_key - 2] = arguments[_key];
391                }
392
393                return _regenerator2.default.wrap(function _callee2$(_context2) {
394                    while (1) {
395                        switch (_context2.prev = _context2.next) {
396                            case 0:
397                                _context2.prev = 0;
398                                _context2.next = 3;
399                                return _promise2.default.all(launcher.map(function (service) {
400                                    if (typeof service[hookName] === 'function') {
401                                        return service[hookName].apply(service, args);
402                                    }
403                                }));
404
405                            case 3:
406                                return _context2.abrupt('return', _context2.sent);
407
408                            case 6:
409                                _context2.prev = 6;
410                                _context2.t0 = _context2['catch'](0);
411
412                                console.error('A service failed in the \'' + hookName + '\' hook\n' + _context2.t0.stack + '\n\nContinue...');
413
414                            case 9:
415                            case 'end':
416                                return _context2.stop();
417                        }
418                    }
419                }, _callee2, this, [[0, 6]]);
420            }));
421
422            function runServiceHook(_x, _x2) {
423                return _ref2.apply(this, arguments);
424            }
425
426            return runServiceHook;
427        }()
428
429        /**
430         * run multiple single remote tests
431         * @return {Boolean} true if all specs have been run and all instances have finished
432         */
433
434    }, {
435        key: 'runSpecs',
436        value: function runSpecs() {
437            var _this2 = this;
438
439            var config = this.configParser.getConfig();
440
441            /**
442             * stop spawning new processes when CTRL+C was triggered
443             */
444            if (this.hasTriggeredExitRoutine) {
445                return true;
446            }
447
448            while (this.getNumberOfRunningInstances() < config.maxInstances) {
449                var schedulableCaps = this.schedule
450                /**
451                 * bail if number of errors exceeds allowed
452                 */
453                .filter(function () {
454                    var filter = typeof config.bail !== 'number' || config.bail < 1 || config.bail > _this2.runnerFailed;
455
456                    /**
457                     * clear number of specs when filter is false
458                     */
459                    if (!filter) {
460                        _this2.schedule.forEach(function (t) {
461                            t.specs = [];
462                        });
463                    }
464
465                    return filter;
466                })
467                /**
468                 * make sure complete number of running instances is not higher than general maxInstances number
469                 */
470                .filter(function (a) {
471                    return _this2.getNumberOfRunningInstances() < config.maxInstances;
472                })
473                /**
474                 * make sure the capabiltiy has available capacities
475                 */
476                .filter(function (a) {
477                    return a.availableInstances > 0;
478                })
479                /**
480                 * make sure capabiltiy has still caps to run
481                 */
482                .filter(function (a) {
483                    return a.specs.length > 0;
484                })
485                /**
486                 * make sure we are running caps with less running instances first
487                 */
488                .sort(function (a, b) {
489                    return a.runningInstances > b.runningInstances;
490                });
491
492                /**
493                 * continue if no capabiltiy were schedulable
494                 */
495                if (schedulableCaps.length === 0) {
496                    break;
497                }
498
499                this.startInstance([schedulableCaps[0].specs.pop()], schedulableCaps[0].caps, schedulableCaps[0].cid, schedulableCaps[0].seleniumServer);
500                schedulableCaps[0].availableInstances--;
501                schedulableCaps[0].runningInstances++;
502            }
503
504            return this.getNumberOfRunningInstances() === 0 && this.getNumberOfSpecsLeft() === 0;
505        }
506
507        /**
508         * gets number of all running instances
509         * @return {number} number of running instances
510         */
511
512    }, {
513        key: 'getNumberOfRunningInstances',
514        value: function getNumberOfRunningInstances() {
515            return this.schedule.map(function (a) {
516                return a.runningInstances;
517            }).reduce(function (a, b) {
518                return a + b;
519            });
520        }
521
522        /**
523         * get number of total specs left to complete whole suites
524         * @return {number} specs left to complete suite
525         */
526
527    }, {
528        key: 'getNumberOfSpecsLeft',
529        value: function getNumberOfSpecsLeft() {
530            return this.schedule.map(function (a) {
531                return a.specs.length;
532            }).reduce(function (a, b) {
533                return a + b;
534            });
535        }
536
537        /**
538         * Start instance in a child process.
539         * @param  {Array} specs  Specs to run
540         * @param  {Number} cid  Capabilities ID
541         */
542
543    }, {
544        key: 'startInstance',
545        value: function startInstance(specs, caps, cid, server) {
546            var config = this.configParser.getConfig();
547            var debug = caps.debug || config.debug;
548            cid = this.getRunnerId(cid);
549            var processNumber = this.processesStarted + 1;
550
551            // process.debugPort defaults to 5858 and is set even when process
552            // is not being debugged.
553            var debugArgs = debug ? ['--debug=' + (process.debugPort + processNumber)] : [];
554
555            // if you would like to add --debug-brk, use a different port, etc...
556            var capExecArgs = [].concat((0, _toConsumableArray3.default)(config.execArgv || []), (0, _toConsumableArray3.default)(caps.execArgv || []));
557
558            // The default value for child.fork execArgs is process.execArgs,
559            // so continue to use this unless another value is specified in config.
560            var defaultArgs = capExecArgs.length ? process.execArgv : [];
561
562            // If an arg appears multiple times the last occurence is used
563            var execArgv = [].concat((0, _toConsumableArray3.default)(defaultArgs), debugArgs, (0, _toConsumableArray3.default)(capExecArgs));
564
565            var childProcess = _child_process2.default.fork(_path2.default.join(__dirname, '/runner.js'), process.argv.slice(2), {
566                cwd: process.cwd(),
567                execArgv: execArgv
568            });
569
570            this.processes.push(childProcess);
571
572            childProcess.on('message', this.messageHandler.bind(this, cid)).on('exit', this.endHandler.bind(this, cid));
573
574            childProcess.send({
575                cid: cid,
576                command: 'run',
577                configFile: this.configFile,
578                argv: this.argv,
579                caps: caps,
580                processNumber: processNumber,
581                specs: specs,
582                server: server,
583                isMultiremote: this.isMultiremote()
584            });
585
586            this.processesStarted++;
587        }
588
589        /**
590         * generates a runner id
591         * @param  {Number} cid capability id (unique identifier for a capability)
592         * @return {String}     runner id (combination of cid and test id e.g. 0a, 0b, 1a, 1b ...)
593         */
594
595    }, {
596        key: 'getRunnerId',
597        value: function getRunnerId(cid) {
598            if (!this.rid[cid]) {
599                this.rid[cid] = 0;
600            }
601            return cid + '-' + this.rid[cid]++;
602        }
603
604        /**
605         * emit event from child process to reporter
606         * @param  {String} cid
607         * @param  {Object} m event object
608         */
609
610    }, {
611        key: 'messageHandler',
612        value: function messageHandler(cid, m) {
613            this.hasStartedAnyProcess = true;
614
615            if (!m.cid) {
616                m.cid = cid;
617            }
618
619            if (m.event === 'runner:error') {
620                this.reporters.handleEvent('error', m);
621            }
622
623            this.reporters.handleEvent(m.event, m);
624        }
625
626        /**
627         * Close test runner process once all child processes have exited
628         * @param  {Number} cid  Capabilities ID
629         * @param  {Number} childProcessExitCode  exit code of child process
630         */
631
632    }, {
633        key: 'endHandler',
634        value: function endHandler(cid, childProcessExitCode) {
635            this.exitCode = this.exitCode || childProcessExitCode;
636            this.runnerFailed += this.exitCode !== 0 ? 1 : 0;
637
638            // Update schedule now this process has ended
639            if (!this.isMultiremote()) {
640                // get cid (capability id) from rid (runner id)
641                cid = parseInt(cid, 10);
642
643                this.schedule[cid].availableInstances++;
644                this.schedule[cid].runningInstances--;
645            }
646
647            if (!this.isMultiremote() && !this.runSpecs()) {
648                return;
649            }
650
651            this.reporters.handleEvent('end', {
652                sigint: this.hasTriggeredExitRoutine,
653                exitCode: this.exitCode,
654                isMultiremote: this.isMultiremote(),
655                capabilities: this.configParser.getCapabilities(),
656                config: this.configParser.getConfig()
657            });
658
659            if (this.exitCode === 0) {
660                return this.resolve(this.exitCode);
661            }
662
663            /**
664             * finish with exit code 1
665             */
666            return this.resolve(1);
667        }
668
669        /**
670         * Make sure all started selenium sessions get closed properly and prevent
671         * having dead driver processes. To do so let the runner end its Selenium
672         * session first before killing
673         */
674
675    }, {
676        key: 'exitHandler',
677        value: function exitHandler() {
678            if (this.hasTriggeredExitRoutine || !this.hasStartedAnyProcess) {
679                console.log('\nKilling process, bye!');
680
681                // When spawned as a subprocess,
682                // SIGINT will not be forwarded to childs.
683                // Thus for the child to exit cleanly, we must force send SIGINT
684                if (!process.stdin.isTTY) {
685                    this.processes.forEach(function (p) {
686                        return p.kill('SIGINT');
687                    });
688                }
689
690                /**
691                 * finish with exit code 1
692                 */
693                return this.resolve(1);
694            }
695
696            // When spawned as a subprocess,
697            // SIGINT will not be forwarded to childs.
698            // Thus for the child to exit cleanly, we must force send SIGINT
699            if (!process.stdin.isTTY) {
700                this.processes.forEach(function (p) {
701                    return p.kill('SIGINT');
702                });
703            }
704
705            console.log('\n\nEnd selenium sessions properly ...\n(press ctrl+c again to hard kill the runner)\n');
706
707            this.hasTriggeredExitRoutine = true;
708        }
709
710        /**
711         * loads launch services
712         */
713
714    }, {
715        key: 'getLauncher',
716        value: function getLauncher(config) {
717            var launchServices = [];
718
719            if (!Array.isArray(config.services)) {
720                return launchServices;
721            }
722
723            var _iteratorNormalCompletion4 = true;
724            var _didIteratorError4 = false;
725            var _iteratorError4 = undefined;
726
727            try {
728                for (var _iterator4 = (0, _getIterator3.default)(config.services), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
729                    var serviceName = _step4.value;
730
731                    var service = void 0;
732
733                    /**
734                     * allow custom services
735                     */
736                    if (typeof serviceName === 'object') {
737                        launchServices.push(serviceName);
738                        continue;
739                    }
740
741                    try {
742                        service = require('wdio-' + serviceName + '-service/launcher');
743                    } catch (e) {
744                        if (!e.message.match('Cannot find module \'wdio-' + serviceName + '-service/launcher\'')) {
745                            throw new Error('Couldn\'t initialise launcher from service "' + serviceName + '".\n' + e.stack);
746                        }
747                    }
748
749                    if (service && typeof service.onPrepare === 'function') {
750                        launchServices.push(service);
751                    }
752                }
753            } catch (err) {
754                _didIteratorError4 = true;
755                _iteratorError4 = err;
756            } finally {
757                try {
758                    if (!_iteratorNormalCompletion4 && _iterator4.return) {
759                        _iterator4.return();
760                    }
761                } finally {
762                    if (_didIteratorError4) {
763                        throw _iteratorError4;
764                    }
765                }
766            }
767
768            return launchServices;
769        }
770    }]);
771    return Launcher;
772}();
773
774exports.default = Launcher;
775module.exports = exports['default'];
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Webdriverio on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)