Telegram Web, preconfigured for usage in I2P.
http://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
299 lines
7.2 KiB
299 lines
7.2 KiB
var helper = require('./helper'); |
|
var events = require('./events'); |
|
var logger = require('./logger'); |
|
|
|
|
|
var Result = function() { |
|
var startTime = Date.now(); |
|
|
|
this.total = this.skipped = this.failed = this.success = 0; |
|
this.netTime = this.totalTime = 0; |
|
this.disconnected = this.error = false; |
|
|
|
this.totalTimeEnd = function() { |
|
this.totalTime = Date.now() - startTime; |
|
}; |
|
}; |
|
|
|
|
|
// The browser is ready to execute tests. |
|
var READY = 1; |
|
|
|
// The browser is executing the tests/ |
|
var EXECUTING = 2; |
|
|
|
// The browser is not executing, but temporarily disconnected (waiting for reconnecting). |
|
var READY_DISCONNECTED = 3; |
|
|
|
// The browser is executing the tests, but temporarily disconnect (waiting for reconnecting). |
|
var EXECUTING_DISCONNECTED = 4; |
|
|
|
// The browser got permanently disconnected (being removed from the collection and destroyed). |
|
var DISCONNECTED = 5; |
|
|
|
|
|
var Browser = function(id, fullName, /* capturedBrowsers */ collection, emitter, socket, timer, |
|
/* config.browserDisconnectTimeout */ disconnectDelay) { |
|
|
|
var name = helper.browserFullNameToShort(fullName); |
|
var log = logger.create(name); |
|
|
|
this.id = id; |
|
this.fullName = fullName; |
|
this.name = name; |
|
this.state = READY; |
|
this.lastResult = new Result(); |
|
|
|
this.init = function() { |
|
collection.add(this); |
|
|
|
events.bindAll(this, socket); |
|
|
|
log.info('Connected on socket %s', socket.id); |
|
|
|
// TODO(vojta): remove launchId, |
|
// it's here just for WebStorm B-C. |
|
this.launchId = this.id; |
|
this.id = socket.id; |
|
|
|
// TODO(vojta): move to collection |
|
emitter.emit('browsers_change', collection); |
|
|
|
emitter.emit('browser_register', this); |
|
}; |
|
|
|
this.isReady = function() { |
|
return this.state === READY; |
|
}; |
|
|
|
this.toString = function() { |
|
return this.name; |
|
}; |
|
|
|
this.onError = function(error) { |
|
if (this.isReady()) { |
|
return; |
|
} |
|
|
|
this.lastResult.error = true; |
|
emitter.emit('browser_error', this, error); |
|
}; |
|
|
|
this.onInfo = function(info) { |
|
if (this.isReady()) { |
|
return; |
|
} |
|
|
|
// TODO(vojta): remove |
|
if (helper.isDefined(info.dump)) { |
|
emitter.emit('browser_log', this, info.dump, 'dump'); |
|
} |
|
|
|
if (helper.isDefined(info.log)) { |
|
emitter.emit('browser_log', this, info.log, info.type); |
|
} |
|
|
|
if (helper.isDefined(info.total)) { |
|
this.lastResult.total = info.total; |
|
} |
|
}; |
|
|
|
this.onComplete = function(result) { |
|
if (this.isReady()) { |
|
return; |
|
} |
|
|
|
this.state = READY; |
|
this.lastResult.totalTimeEnd(); |
|
|
|
if (!this.lastResult.success) { |
|
this.lastResult.error = true; |
|
} |
|
|
|
emitter.emit('browsers_change', collection); |
|
emitter.emit('browser_complete', this, result); |
|
}; |
|
|
|
var self = this; |
|
var disconnect = function() { |
|
self.state = DISCONNECTED; |
|
log.warn('Disconnected'); |
|
collection.remove(self); |
|
}; |
|
|
|
var pendingDisconnect; |
|
this.onDisconnect = function() { |
|
if (this.state === READY) { |
|
disconnect(); |
|
} else if (this.state === EXECUTING) { |
|
log.debug('Disconnected during run, waiting for reconnecting.'); |
|
this.state = EXECUTING_DISCONNECTED; |
|
|
|
pendingDisconnect = timer.setTimeout(function() { |
|
self.lastResult.totalTimeEnd(); |
|
self.lastResult.disconnected = true; |
|
disconnect(); |
|
emitter.emit('browser_complete', self); |
|
}, disconnectDelay); |
|
} |
|
}; |
|
|
|
this.onReconnect = function(newSocket) { |
|
if (this.state === EXECUTING_DISCONNECTED) { |
|
this.state = EXECUTING; |
|
log.debug('Reconnected.'); |
|
} else if (this.state === EXECUTING || this.state === READY) { |
|
log.debug('New connection, forgetting the old one.'); |
|
// TODO(vojta): this should only remove this browser.onDisconnect listener |
|
socket.removeAllListeners('disconnect'); |
|
} |
|
|
|
socket = newSocket; |
|
events.bindAll(this, newSocket); |
|
if (pendingDisconnect) { |
|
timer.clearTimeout(pendingDisconnect); |
|
} |
|
}; |
|
|
|
this.onResult = function(result) { |
|
if (result.length) { |
|
return result.forEach(this.onResult, this); |
|
} |
|
|
|
// ignore - probably results from last run (after server disconnecting) |
|
if (this.isReady()) { |
|
return; |
|
} |
|
|
|
if (result.skipped) { |
|
this.lastResult.skipped++; |
|
} else if (result.success) { |
|
this.lastResult.success++; |
|
} else { |
|
this.lastResult.failed++; |
|
} |
|
|
|
this.lastResult.netTime += result.time; |
|
emitter.emit('spec_complete', this, result); |
|
}; |
|
|
|
this.serialize = function() { |
|
return { |
|
id: this.id, |
|
name: this.name, |
|
isReady: this.state === READY |
|
}; |
|
}; |
|
}; |
|
|
|
Browser.STATE_READY = READY; |
|
Browser.STATE_EXECUTING = EXECUTING; |
|
Browser.STATE_READY_DISCONNECTED = READY_DISCONNECTED; |
|
Browser.STATE_EXECUTING_DISCONNECTED = EXECUTING_DISCONNECTED; |
|
Browser.STATE_DISCONNECTED = DISCONNECTED; |
|
|
|
|
|
var Collection = function(emitter, browsers) { |
|
browsers = browsers || []; |
|
|
|
this.add = function(browser) { |
|
browsers.push(browser); |
|
emitter.emit('browsers_change', this); |
|
}; |
|
|
|
this.remove = function(browser) { |
|
var index = browsers.indexOf(browser); |
|
|
|
if (index === -1) { |
|
return false; |
|
} |
|
|
|
browsers.splice(index, 1); |
|
emitter.emit('browsers_change', this); |
|
|
|
return true; |
|
}; |
|
|
|
this.getById = function(browserId) { |
|
for (var i = 0; i < browsers.length; i++) { |
|
// TODO(vojta): use id, once we fix WebStorm plugin |
|
if (browsers[i].launchId === browserId) { |
|
return browsers[i]; |
|
} |
|
} |
|
|
|
return null; |
|
}; |
|
|
|
this.setAllToExecuting = function() { |
|
browsers.forEach(function(browser) { |
|
browser.state = EXECUTING; |
|
}); |
|
|
|
emitter.emit('browsers_change', this); |
|
}; |
|
|
|
this.areAllReady = function(nonReadyList) { |
|
nonReadyList = nonReadyList || []; |
|
|
|
browsers.forEach(function(browser) { |
|
if (!browser.isReady()) { |
|
nonReadyList.push(browser); |
|
} |
|
}); |
|
|
|
return nonReadyList.length === 0; |
|
}; |
|
|
|
this.serialize = function() { |
|
return browsers.map(function(browser) { |
|
return browser.serialize(); |
|
}); |
|
}; |
|
|
|
this.getResults = function() { |
|
var results = browsers.reduce(function(previous, current) { |
|
previous.success += current.lastResult.success; |
|
previous.failed += current.lastResult.failed; |
|
previous.error = previous.error || current.lastResult.error; |
|
previous.disconnected = previous.disconnected || current.lastResult.disconnected; |
|
return previous; |
|
}, {success: 0, failed: 0, error: false, disconnected: false, exitCode: 0}); |
|
|
|
// compute exit status code |
|
results.exitCode = results.failed || results.error || results.disconnected ? 1 : 0; |
|
|
|
return results; |
|
}; |
|
|
|
this.clearResults = function() { |
|
browsers.forEach(function(browser) { |
|
browser.lastResult = new Result(); |
|
}); |
|
}; |
|
|
|
this.clone = function() { |
|
return new Collection(emitter, browsers.slice()); |
|
}; |
|
|
|
// Array APIs |
|
this.map = function(callback, context) { |
|
return browsers.map(callback, context); |
|
}; |
|
|
|
this.forEach = function(callback, context) { |
|
return browsers.forEach(callback, context); |
|
}; |
|
|
|
// this.length |
|
Object.defineProperty(this, 'length', { |
|
get: function() { |
|
return browsers.length; |
|
} |
|
}); |
|
}; |
|
Collection.$inject = ['emitter']; |
|
|
|
exports.Result = Result; |
|
exports.Browser = Browser; |
|
exports.Collection = Collection;
|
|
|