diff --git a/lib/launcher.js b/lib/launcher.js index 84b5cce16..f0fde7054 100644 --- a/lib/launcher.js +++ b/lib/launcher.js @@ -1,16 +1,17 @@ -var Promise = require('bluebird') -var Jobs = require('qjobs') +'use strict' -var helper = require('./helper') -var log = require('./logger').create('launcher') +const Promise = require('bluebird') +const Jobs = require('qjobs') -var baseDecorator = require('./launchers/base').decoratorFactory -var captureTimeoutDecorator = require('./launchers/capture_timeout').decoratorFactory -var retryDecorator = require('./launchers/retry').decoratorFactory -var processDecorator = require('./launchers/process').decoratorFactory +const log = require('./logger').create('launcher') + +const baseDecorator = require('./launchers/base').decoratorFactory +const captureTimeoutDecorator = require('./launchers/capture_timeout').decoratorFactory +const retryDecorator = require('./launchers/retry').decoratorFactory +const processDecorator = require('./launchers/process').decoratorFactory // TODO(vojta): remove once nobody uses it -var baseBrowserDecoratorFactory = function ( +const baseBrowserDecoratorFactory = function ( baseLauncherDecorator, captureTimeoutLauncherDecorator, retryLauncherDecorator, @@ -25,34 +26,22 @@ var baseBrowserDecoratorFactory = function ( } } -var Launcher = function (server, emitter, injector) { +function Launcher (server, emitter, injector) { this._browsers = [] - var lastStartTime - var self = this - - var getBrowserById = function (id) { - for (var i = 0; i < self._browsers.length; i++) { - if (self._browsers[i].id === id) { - return self._browsers[i] - } - } + let lastStartTime - return null - } + const getBrowserById = (id) => this._browsers.find((browser) => browser.id === id) - this.launchSingle = function (protocol, hostname, port, urlRoot, upstreamProxy, processKillTimeout) { - var self = this - return function (name) { - name = (name + '').trim() - if (upstreamProxy) { - protocol = upstreamProxy.protocol - hostname = upstreamProxy.hostname - port = upstreamProxy.port - urlRoot = upstreamProxy.path + urlRoot.substr(1) - } - var url = protocol + '//' + hostname + ':' + port + urlRoot + this.launchSingle = (protocol, hostname, port, urlRoot, upstreamProxy, processKillTimeout) => { + if (upstreamProxy) { + protocol = upstreamProxy.protocol + hostname = upstreamProxy.hostname + port = upstreamProxy.port + urlRoot = upstreamProxy.path + urlRoot.substr(1) + } - var locals = { + return (name) => { + const locals = { id: ['value', Launcher.generateId()], name: ['value', name], processKillTimeout: ['value', processKillTimeout], @@ -71,81 +60,53 @@ var Launcher = function (server, emitter, injector) { try { var browser = injector.createChild([locals], ['launcher:' + name]).get('launcher:' + name) } catch (e) { - if (e.message.indexOf('No provider for "launcher:' + name + '"') !== -1) { - log.error('Cannot load browser "%s": it is not registered! ' + - 'Perhaps you are missing some plugin?', name) + if (e.message.indexOf(`No provider for "launcher:${name}"`) !== -1) { + log.error(`Cannot load browser "${name}": it is not registered! Perhaps you are missing some plugin?`) } else { - log.error('Cannot load browser "%s"!\n ' + e.stack, name) + log.error(`Cannot load browser "${name}"!\n ` + e.stack) } emitter.emit('load_error', 'launcher', name) return } - // TODO(vojta): remove in v1.0 (BC for old launchers) - if (!browser.forceKill) { - browser.forceKill = function () { - var me = this - return new Promise(function (resolve) { - me.kill(resolve) - }) - } + this.jobs.add((args, done) => { + log.info(`Starting browser ${browser.displayName || browser.name}`) - browser.restart = function () { - var me = this - this.kill(function () { - me.start(url) - }) - } - } + browser.on('browser_process_failure', () => done(browser.error)) - self.jobs.add(function (args, done) { - log.info('Starting browser %s', helper.isDefined(browser.displayName) ? browser.displayName : browser.name) - - browser.on('browser_process_failure', function () { - done(browser.error) + browser.on('done', () => { + if (!browser.error && browser.state !== browser.STATE_RESTARTING) { + done(null, browser) + } }) - browser.on('done', function () { - // We are not done if there was an error as first the retry takes - // place which we catch with `browser_process_failure` if it fails - if (browser.error || browser.state === browser.STATE_RESTARTING) return - - done(null, browser) - }) - - browser.start(url) + browser.start(`${protocol}//${hostname}:${port}${urlRoot}`) }, []) - self.jobs.run() - self._browsers.push(browser) + this.jobs.run() + this._browsers.push(browser) } } - this.launch = function (names, concurrency) { + this.launch = (names, concurrency) => { log.info( 'Launching browser%s %s with %s', names.length > 1 ? 's' : '', names.join(', '), - concurrency === Infinity ? 'unlimited concurrency' : 'concurrency ' + concurrency + concurrency === Infinity ? 'unlimited concurrency' : `concurrency ${concurrency}` ) - this.jobs = new Jobs({maxConcurrency: concurrency}) + this.jobs = new Jobs({ maxConcurrency: concurrency }) - var self = this lastStartTime = Date.now() - if (server.loadErrors.length === 0) { - names.forEach(function (name) { - injector.invoke(self.launchSingle, self)(name) - }) + if (server.loadErrors.length) { + this.jobs.add((args, done) => done(), []) } else { - // Empty task to ensure `end` is emitted - this.jobs.add(function (args, done) { - done() - }, []) + names.forEach((name) => injector.invoke(this.launchSingle, this)(name)) } - this.jobs.on('end', function (err) { + this.jobs.on('end', (err) => { log.debug('Finished all browsers') if (err) { @@ -155,7 +116,7 @@ var Launcher = function (server, emitter, injector) { this.jobs.run() - return self._browsers + return this._browsers } this.launch.$inject = [ @@ -173,76 +134,53 @@ var Launcher = function (server, emitter, injector) { 'config.processKillTimeout' ] - this.kill = function (id, callback) { - var browser = getBrowserById(id) + this.kill = (id, callback) => { callback = callback || function () {} + const browser = getBrowserById(id) - if (!browser) { - process.nextTick(callback) - return false + if (browser) { + browser.forceKill().then(callback) + return true } - - browser.forceKill().then(callback) - return true + process.nextTick(callback) + return false } - this.restart = function (id) { - var browser = getBrowserById(id) - - if (!browser) { - return false + this.restart = (id) => { + const browser = getBrowserById(id) + if (browser) { + browser.restart() + return true } - - browser.restart() - return true + return false } - this.killAll = function (callback) { + this.killAll = (callback) => { + callback = callback || function () {} log.debug('Disconnecting all browsers') - var remaining = 0 - var finish = function () { - remaining-- - if (!remaining && callback) { - callback() - } - } - - if (!self._browsers.length) { + if (!this._browsers.length) { return process.nextTick(callback) } - self._browsers.forEach(function (browser) { - remaining++ - browser.forceKill().then(finish) - }) + Promise.all( + this._browsers + .map((browser) => browser.forceKill()) + ).then(callback) } - this.areAllCaptured = function () { - return !self._browsers.some(function (browser) { - return !browser.isCaptured() - }) - } + this.areAllCaptured = () => this._browsers.every((browser) => browser.isCaptured()) - this.markCaptured = function (id) { - self._browsers.forEach(function (browser) { - if (browser.id === id) { - browser.markCaptured() - log.debug('%s (id %s) captured in %d secs', browser.name, browser.id, - (Date.now() - lastStartTime) / 1000) - } - }) + this.markCaptured = (id) => { + const browser = getBrowserById(id) + browser.markCaptured() + log.debug(`${browser.name} (id ${browser.id}) captured in ${(Date.now() - lastStartTime) / 1000} secs`) } - // register events emitter.on('exit', this.killAll) } Launcher.$inject = ['server', 'emitter', 'injector'] +Launcher.generateId = () => Math.floor(Math.random() * 100000000).toString() -Launcher.generateId = function () { - return '' + Math.floor(Math.random() * 100000000) -} - -// PUBLISH exports.Launcher = Launcher diff --git a/test/unit/launcher.spec.js b/test/unit/launcher.spec.js index 8b69955d5..d00ffa684 100644 --- a/test/unit/launcher.spec.js +++ b/test/unit/launcher.spec.js @@ -1,3 +1,5 @@ +'use strict' + var Promise = require('bluebird') var di = require('di') @@ -61,9 +63,7 @@ function ScriptBrowser (id, name, baseBrowserDecorator) { describe('launcher', () => { // mock out id generator var lastGeneratedId = null - launcher.Launcher.generateId = () => { - return ++lastGeneratedId - } + launcher.Launcher.generateId = () => ++lastGeneratedId before(() => { Promise.setScheduler((fn) => fn())