141 lines
3.2 KiB
JavaScript
141 lines
3.2 KiB
JavaScript
const KarmaEventEmitter = require('../events').EventEmitter
|
|
const EventEmitter = require('events').EventEmitter
|
|
|
|
const log = require('../logger').create('launcher')
|
|
const helper = require('../helper')
|
|
|
|
const BEING_CAPTURED = 'BEING_CAPTURED'
|
|
const CAPTURED = 'CAPTURED'
|
|
const BEING_KILLED = 'BEING_KILLED'
|
|
const FINISHED = 'FINISHED'
|
|
const RESTARTING = 'RESTARTING'
|
|
const BEING_FORCE_KILLED = 'BEING_FORCE_KILLED'
|
|
|
|
/**
|
|
* Base launcher that any custom launcher extends.
|
|
*/
|
|
function BaseLauncher (id, emitter) {
|
|
if (this.start) {
|
|
return
|
|
}
|
|
|
|
// TODO(vojta): figure out how to do inheritance with DI
|
|
Object.keys(EventEmitter.prototype).forEach(function (method) {
|
|
this[method] = EventEmitter.prototype[method]
|
|
}, this)
|
|
|
|
this.bind = KarmaEventEmitter.prototype.bind.bind(this)
|
|
this.emitAsync = KarmaEventEmitter.prototype.emitAsync.bind(this)
|
|
|
|
this.id = id
|
|
this._state = null
|
|
Object.defineProperty(this, 'state', {
|
|
get: () => {
|
|
return this._state
|
|
},
|
|
set: (toState) => {
|
|
log.debug(`${this._state} -> ${toState}`)
|
|
this._state = toState
|
|
}
|
|
})
|
|
|
|
this.error = null
|
|
|
|
let killingPromise
|
|
let previousUrl
|
|
|
|
this.start = function (url) {
|
|
previousUrl = url
|
|
|
|
this.error = null
|
|
this.state = BEING_CAPTURED
|
|
this.emit('start', url + '?id=' + this.id + (helper.isDefined(this.displayName) ? '&displayName=' + encodeURIComponent(this.displayName) : ''))
|
|
}
|
|
|
|
this.kill = function () {
|
|
// Already killed, or being killed.
|
|
if (killingPromise) {
|
|
return killingPromise
|
|
}
|
|
|
|
killingPromise = this.emitAsync('kill').then(() => {
|
|
this.state = FINISHED
|
|
})
|
|
|
|
this.state = BEING_KILLED
|
|
|
|
return killingPromise
|
|
}
|
|
|
|
this.forceKill = function () {
|
|
this.kill()
|
|
this.state = BEING_FORCE_KILLED
|
|
|
|
return killingPromise
|
|
}
|
|
|
|
this.restart = function () {
|
|
if (this.state === BEING_FORCE_KILLED) {
|
|
return
|
|
}
|
|
|
|
if (!killingPromise) {
|
|
killingPromise = this.emitAsync('kill')
|
|
}
|
|
|
|
killingPromise.then(() => {
|
|
if (this.state === BEING_FORCE_KILLED) {
|
|
this.state = FINISHED
|
|
} else {
|
|
killingPromise = null
|
|
log.debug(`Restarting ${this.name}`)
|
|
this.start(previousUrl)
|
|
}
|
|
})
|
|
|
|
this.state = RESTARTING
|
|
}
|
|
|
|
this.markCaptured = function () {
|
|
if (this.state === BEING_CAPTURED) {
|
|
this.state = CAPTURED
|
|
}
|
|
}
|
|
|
|
this.isCaptured = function () {
|
|
return this.state === CAPTURED
|
|
}
|
|
|
|
this.toString = function () {
|
|
return this.name
|
|
}
|
|
|
|
this._done = function (error) {
|
|
killingPromise = killingPromise || Promise.resolve()
|
|
|
|
this.error = this.error || error
|
|
this.emit('done')
|
|
|
|
if (this.error && this.state !== BEING_FORCE_KILLED && this.state !== RESTARTING) {
|
|
emitter.emit('browser_process_failure', this)
|
|
}
|
|
|
|
this.state = FINISHED
|
|
}
|
|
|
|
this.STATE_BEING_CAPTURED = BEING_CAPTURED
|
|
this.STATE_CAPTURED = CAPTURED
|
|
this.STATE_BEING_KILLED = BEING_KILLED
|
|
this.STATE_FINISHED = FINISHED
|
|
this.STATE_RESTARTING = RESTARTING
|
|
this.STATE_BEING_FORCE_KILLED = BEING_FORCE_KILLED
|
|
}
|
|
|
|
BaseLauncher.decoratorFactory = function (id, emitter) {
|
|
return function (launcher) {
|
|
BaseLauncher.call(launcher, id, emitter)
|
|
}
|
|
}
|
|
|
|
module.exports = BaseLauncher
|