var KarmaEventEmitter = require('../events').EventEmitter; var EventEmitter = require('events').EventEmitter; var q = require('q'); var log = require('../logger').create('launcher'); var BEING_CAPTURED = 1; var CAPTURED = 2; var BEING_KILLED = 3; var FINISHED = 4; var RESTARTING = 5; var BEING_FORCE_KILLED = 6; /** * Base launcher that any custom launcher extends. */ var BaseLauncher = function(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); KarmaEventEmitter.call(this); this.id = id; this.state = null; this.error = null; var self = this; var killingPromise; var previousUrl; this.start = function(url) { previousUrl = url; this.error = null; this.state = BEING_CAPTURED; this.emit('start', url + '?id=' + this.id); }; this.kill = function() { // Already killed, or being killed. if (killingPromise) { return killingPromise; } killingPromise = this.emitAsync('kill').then(function() { self.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(function() { if (self.state === BEING_FORCE_KILLED) { self.state = FINISHED; } else { killingPromise = null; log.debug('Restarting %s', self.name); self.start(previousUrl); } }); self.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 || q(); 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;