mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-09-28 21:24:26 +08:00
No changes in the changelog (https://github.com/karma-runner/karma/blob/master/CHANGELOG.md) to concern ourselves about, but one useful change is they upgraded the log4js dependency which was spitting out console messages on each test run. This is fixed with this version of Karma. Bug: none Change-Id: Ic49618cbda7a079cacb9813f5129692a83508a92 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3745621 Commit-Queue: Jack Franklin <jacktfranklin@chromium.org> Auto-Submit: Jack Franklin <jacktfranklin@chromium.org> Reviewed-by: Philip Pfaffe <pfaffe@chromium.org> Commit-Queue: Philip Pfaffe <pfaffe@chromium.org>
200 lines
5.3 KiB
JavaScript
200 lines
5.3 KiB
JavaScript
'use strict'
|
|
|
|
const Jobs = require('qjobs')
|
|
|
|
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
|
|
const baseBrowserDecoratorFactory = function (
|
|
baseLauncherDecorator,
|
|
captureTimeoutLauncherDecorator,
|
|
retryLauncherDecorator,
|
|
processLauncherDecorator,
|
|
processKillTimeout
|
|
) {
|
|
return function (launcher) {
|
|
baseLauncherDecorator(launcher)
|
|
captureTimeoutLauncherDecorator(launcher)
|
|
retryLauncherDecorator(launcher)
|
|
processLauncherDecorator(launcher, processKillTimeout)
|
|
}
|
|
}
|
|
|
|
class Launcher {
|
|
constructor (server, emitter, injector) {
|
|
this._server = server
|
|
this._emitter = emitter
|
|
this._injector = injector
|
|
this._browsers = []
|
|
this._lastStartTime = null
|
|
|
|
// Attach list of dependency injection parameters to methods.
|
|
this.launch.$inject = [
|
|
'config.browsers',
|
|
'config.concurrency'
|
|
]
|
|
|
|
this.launchSingle.$inject = [
|
|
'config.protocol',
|
|
'config.hostname',
|
|
'config.port',
|
|
'config.urlRoot',
|
|
'config.upstreamProxy',
|
|
'config.processKillTimeout'
|
|
]
|
|
|
|
this._emitter.on('exit', (callback) => this.killAll(callback))
|
|
}
|
|
|
|
getBrowserById (id) {
|
|
return this._browsers.find((browser) => browser.id === id)
|
|
}
|
|
|
|
launchSingle (protocol, hostname, port, urlRoot, upstreamProxy, processKillTimeout) {
|
|
if (upstreamProxy) {
|
|
protocol = upstreamProxy.protocol
|
|
hostname = upstreamProxy.hostname
|
|
port = upstreamProxy.port
|
|
urlRoot = upstreamProxy.path + urlRoot.slice(1)
|
|
}
|
|
|
|
return (name) => {
|
|
let browser
|
|
const locals = {
|
|
id: ['value', Launcher.generateId()],
|
|
name: ['value', name],
|
|
processKillTimeout: ['value', processKillTimeout],
|
|
baseLauncherDecorator: ['factory', baseDecorator],
|
|
captureTimeoutLauncherDecorator: ['factory', captureTimeoutDecorator],
|
|
retryLauncherDecorator: ['factory', retryDecorator],
|
|
processLauncherDecorator: ['factory', processDecorator],
|
|
baseBrowserDecorator: ['factory', baseBrowserDecoratorFactory]
|
|
}
|
|
|
|
// TODO(vojta): determine script from name
|
|
if (name.includes('/')) {
|
|
name = 'Script'
|
|
}
|
|
|
|
try {
|
|
browser = this._injector.createChild([locals], ['launcher:' + name]).get('launcher:' + name)
|
|
} catch (e) {
|
|
if (e.message.includes(`No provider for "launcher:${name}"`)) {
|
|
log.error(`Cannot load browser "${name}": it is not registered! Perhaps you are missing some plugin?`)
|
|
} else {
|
|
log.error(`Cannot load browser "${name}"!\n ` + e.stack)
|
|
}
|
|
|
|
this._emitter.emit('load_error', 'launcher', name)
|
|
return
|
|
}
|
|
|
|
this.jobs.add((args, done) => {
|
|
log.info(`Starting browser ${browser.displayName || browser.name}`)
|
|
|
|
browser.on('browser_process_failure', () => done(browser.error))
|
|
|
|
browser.on('done', () => {
|
|
if (!browser.error && browser.state !== browser.STATE_RESTARTING) {
|
|
done(null, browser)
|
|
}
|
|
})
|
|
|
|
browser.start(`${protocol}//${hostname}:${port}${urlRoot}`)
|
|
}, [])
|
|
|
|
this.jobs.run()
|
|
this._browsers.push(browser)
|
|
}
|
|
}
|
|
|
|
launch (names, concurrency) {
|
|
log.info(`Launching browsers ${names.join(', ')} with concurrency ${concurrency === Infinity ? 'unlimited' : concurrency}`)
|
|
this.jobs = new Jobs({ maxConcurrency: concurrency })
|
|
|
|
this._lastStartTime = Date.now()
|
|
|
|
if (this._server.loadErrors.length) {
|
|
this.jobs.add((args, done) => done(), [])
|
|
} else {
|
|
names.forEach((name) => this._injector.invoke(this.launchSingle, this)(name))
|
|
}
|
|
|
|
this.jobs.on('end', (err) => {
|
|
log.debug('Finished all browsers')
|
|
|
|
if (err) {
|
|
log.error(err)
|
|
}
|
|
})
|
|
|
|
this.jobs.run()
|
|
|
|
return this._browsers
|
|
}
|
|
|
|
kill (id, callback) {
|
|
callback = callback || function () {}
|
|
const browser = this.getBrowserById(id)
|
|
|
|
if (browser) {
|
|
browser.forceKill().then(callback)
|
|
return true
|
|
}
|
|
process.nextTick(callback)
|
|
return false
|
|
}
|
|
|
|
restart (id) {
|
|
const browser = this.getBrowserById(id)
|
|
if (browser) {
|
|
browser.restart()
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
killAll (callback) {
|
|
callback = callback || function () {}
|
|
log.debug('Disconnecting all browsers')
|
|
|
|
if (!this._browsers.length) {
|
|
return process.nextTick(callback)
|
|
}
|
|
|
|
Promise.all(
|
|
this._browsers
|
|
.map((browser) => browser.forceKill())
|
|
).then(callback)
|
|
}
|
|
|
|
areAllCaptured () {
|
|
return this._browsers.every((browser) => browser.isCaptured())
|
|
}
|
|
|
|
markCaptured (id) {
|
|
const browser = this.getBrowserById(id)
|
|
if (browser) {
|
|
browser.markCaptured()
|
|
log.debug(`${browser.name} (id ${browser.id}) captured in ${(Date.now() - this._lastStartTime) / 1000} secs`)
|
|
}
|
|
}
|
|
|
|
static generateId () {
|
|
return Math.floor(Math.random() * 100000000).toString()
|
|
}
|
|
}
|
|
|
|
Launcher.factory = function (server, emitter, injector) {
|
|
return new Launcher(server, emitter, injector)
|
|
}
|
|
|
|
Launcher.factory.$inject = ['server', 'emitter', 'injector']
|
|
|
|
exports.Launcher = Launcher
|