Skip to content

Commit

Permalink
Merge pull request #1928 from karma-runner/better-launcher
Browse files Browse the repository at this point in the history
fix(launcher): Allow dynamic browser launches
  • Loading branch information
dignifiedquire committed Mar 7, 2016
2 parents 8ef475f + b35a53c commit 95c4754
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 93 deletions.
3 changes: 2 additions & 1 deletion gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ module.exports = function (grunt) {
cucumberjs: {
options: {
steps: 'test/e2e/steps',
format: 'progress'
format: 'progress',
require: 'test/e2e/support/env.js'
},
all: 'test/e2e/*.feature',
current: {
Expand Down
84 changes: 53 additions & 31 deletions lib/launcher.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var Promise = require('bluebird')
var Batch = require('batch')
var Jobs = require('qjobs')

var helper = require('./helper')
var log = require('./logger').create('launcher')
Expand All @@ -25,27 +25,25 @@ var baseBrowserDecoratorFactory = function (
}

var Launcher = function (server, emitter, injector) {
var browsers = []
this._browsers = []
var lastStartTime
var self = this

var getBrowserById = function (id) {
for (var i = 0; i < browsers.length; i++) {
if (browsers[i].id === id) {
return browsers[i]
for (var i = 0; i < self._browsers.length; i++) {
if (self._browsers[i].id === id) {
return self._browsers[i]
}
}

return null
}

this.launch = function (names, protocol, hostname, port, urlRoot, concurrency) {
var url = protocol + '//' + hostname + ':' + port + urlRoot
var batch = new Batch()
batch.concurrency(concurrency)
this.launchSingle = function (protocol, hostname, port, urlRoot) {
var self = this
return function (name) {
var url = protocol + '//' + hostname + ':' + port + urlRoot

lastStartTime = Date.now()

names.forEach(function (name) {
var locals = {
id: ['value', Launcher.generateId()],
name: ['value', name],
Expand Down Expand Up @@ -75,29 +73,26 @@ var Launcher = function (server, emitter, injector) {
return
}

if (server.loadErrors.length > 0) return []
// TODO(vojta): remove in v1.0 (BC for old launchers)
if (!browser.forceKill) {
browser.forceKill = function () {
var self = this

var me = this
return new Promise(function (resolve) {
self.kill(resolve)
me.kill(resolve)
})
}

browser.restart = function () {
var self = this
var me = this
this.kill(function () {
self.start(url)
me.start(url)
})
}
}

batch.push(function (done) {
self.jobs.add(function (args, done) {
log.info('Starting browser %s', helper.isDefined(browser.displayName) ? browser.displayName : browser.name)

browser.start(url)
browser.on('browser_process_failure', function () {
done(browser.error)
})
Expand All @@ -109,29 +104,56 @@ var Launcher = function (server, emitter, injector) {

done(null, browser)
})
})

browsers.push(browser)
})
browser.start(url)
}, [])

self.jobs.run()
self._browsers.push(browser)
}
}

this.launch = function (names, concurrency) {
log.info('Launching', names, concurrency)
this.jobs = new Jobs({maxConcurrency: concurrency})

batch.end(function (err) {
var self = this
lastStartTime = Date.now()

if (server.loadErrors.length === 0) {
names.forEach(function (name) {
injector.invoke(self.launchSingle, self)(name)
})
} else {
// Empty task to ensure `end` is emitted
this.jobs.add(function (args, done) {
done()
}, [])
}

this.jobs.on('end', function (err) {
log.debug('Finished all browsers')

if (err) {
log.error(err)
}
})

return browsers
this.jobs.run()

return self._browsers
}

this.launch.$inject = [
'config.browsers',
'config.concurrency'
]

this.launchSingle.$inject = [
'config.protocol',
'config.hostname',
'config.port',
'config.urlRoot',
'config.concurrency'
'config.urlRoot'
]

this.kill = function (id, callback) {
Expand Down Expand Up @@ -169,24 +191,24 @@ var Launcher = function (server, emitter, injector) {
}
}

if (!browsers.length) {
if (!self._browsers.length) {
return process.nextTick(callback)
}

browsers.forEach(function (browser) {
self._browsers.forEach(function (browser) {
remaining++
browser.forceKill().then(finish)
})
}

this.areAllCaptured = function () {
return !browsers.some(function (browser) {
return !self._browsers.some(function (browser) {
return !browser.isCaptured()
})
}

this.markCaptured = function (id) {
browsers.forEach(function (browser) {
self._browsers.forEach(function (browser) {
if (browser.id === id) {
browser.markCaptured()
log.debug('%s (id %s) captured in %d secs', browser.name, browser.id,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@
"Karolis Narkevicius <karolis.n@gmail.com>"
],
"dependencies": {
"batch": "^0.5.3",
"bluebird": "^3.3.0",
"body-parser": "^1.12.4",
"chokidar": "^1.4.1",
Expand All @@ -281,6 +280,7 @@
"mime": "^1.3.4",
"minimatch": "^3.0.0",
"optimist": "^0.6.1",
"qjobs": "^1.1.4",
"rimraf": "^2.3.3",
"socket.io": "^1.4.5",
"source-map": "^0.5.3",
Expand Down
6 changes: 1 addition & 5 deletions test/e2e/load.feature
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,5 @@ Feature: Basic Testrunner
"""
And it fails with like:
"""
Cannot load browser "NonExistingBrowser": it is not registered! Perhaps you are missing some plugin\?
"""
And it fails with like:
"""
Found 3 load errors
Found 2 load errors
"""
5 changes: 5 additions & 0 deletions test/e2e/support/env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var configure = function () {
this.setDefaultTimeout(60 * 1000)
}

module.exports = configure
Loading

0 comments on commit 95c4754

Please sign in to comment.