qunit-harness
Version:
A library for running qunit tests on a local machine and in the SauceLabs environment.
278 lines (205 loc) • 10.5 kB
JavaScript
;
var _inherits = require('babel-runtime/helpers/inherits').default;
var _classCallCheck = require('babel-runtime/helpers/class-call-check').default;
var _regeneratorRuntime = require('babel-runtime/regenerator').default;
var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default').default;
exports.__esModule = true;
var _pinkie = require('pinkie');
var _pinkie2 = _interopRequireDefault(_pinkie);
var _promisifyEvent = require('promisify-event');
var _promisifyEvent2 = _interopRequireDefault(_promisifyEvent);
var _events = require('events');
var _job = require('./job');
var _job2 = _interopRequireDefault(_job);
var _utilsWait = require('../utils/wait');
var _utilsWait2 = _interopRequireDefault(_utilsWait);
var _request = require('./request');
var _request2 = _interopRequireDefault(_request);
var REPORTING_TIMEOUT = 1000 * 30;
var WAITING_FOR_FREE_MACHINE_TIMEOUT = 1000 * 60;
var SauceLabsRunner = (function (_EventEmitter) {
_inherits(SauceLabsRunner, _EventEmitter);
function SauceLabsRunner(options) {
_classCallCheck(this, SauceLabsRunner);
_EventEmitter.call(this);
var browsers = options.browsers || [];
this.options = {
username: options.username || '',
accessKey: options.accessKey || '',
build: options.build || Date.now(),
browsers: browsers,
testName: options.name || 'QUnit tests',
tags: options.tags || ['master'],
urls: options.urls || [],
timeout: options.timeout || '',
tunnelIdentifier: options.tunnelIdentifier || Math.floor(new Date().getTime() / 1000 - 1230768000).toString()
};
this.requestAdapter = new _request2.default(this.options.username, this.options.accessKey);
this.jobs = [];
this.jobResults = [];
this.reportingInterval = null;
this.freeMachineCheckInterval = null;
}
SauceLabsRunner.prototype._getQueuedJobs = function _getQueuedJobs(count) {
return this.jobs.filter(function (job) {
return job.getStatus() === _job2.default.STATUSES.INITIALIZED;
}).splice(0, count);
};
SauceLabsRunner.prototype._getInProgressJobsCount = function _getInProgressJobsCount() {
return this.jobs.filter(function (job) {
return job.getStatus() === _job2.default.STATUSES.IN_PROGRESS;
}).length;
};
SauceLabsRunner.prototype._getCompletedJobsCount = function _getCompletedJobsCount() {
return this.jobs.filter(function (job) {
return job.getStatus() === _job2.default.STATUSES.COMPLETED;
}).length;
};
SauceLabsRunner.prototype._getFailedJobsCount = function _getFailedJobsCount() {
return this.jobs.filter(function (job) {
return job.getStatus() === _job2.default.STATUSES.FAILED;
}).length;
};
SauceLabsRunner.prototype._outputCurrentTaskStatus = function _outputCurrentTaskStatus() {
var total = this.jobs.length;
var inProgress = this._getInProgressJobsCount();
var completed = this._getCompletedJobsCount();
var failed = this._getFailedJobsCount();
var queued = total - inProgress - completed - failed;
var message = 'Tasks total: ' + total + ', queued: ' + queued + ', in progress: ' + inProgress + ', completed: ' + completed;
if (failed) message += ', failed: ' + failed;
console.log(message);
};
SauceLabsRunner.prototype._runCurrentTaskStatusReporting = function _runCurrentTaskStatusReporting() {
var _this = this;
var accountUrl = 'https://saucelabs.com/u/' + this.options.username;
console.log('See the progress: ' + accountUrl + ' (session: "' + this.options.testName + '", build: "' + this.options.build + '")');
this.reportingInterval = setInterval(function () {
return _this._outputCurrentTaskStatus();
}, REPORTING_TIMEOUT);
};
SauceLabsRunner.prototype._getFreeMachineCount = function _getFreeMachineCount() {
var _ref, concurrency, orgFreeWindowsMachineCount, orgFreeMacMachineCount, orgFreeMachineCount, teamFreeWindowsMachineCount, teamFreeMacMachineCount, teamFreeMachineCount;
return _regeneratorRuntime.async(function _getFreeMachineCount$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
context$2$0.next = 2;
return _regeneratorRuntime.awrap(this.requestAdapter.get(_request2.default.URLS.CONCURRENCY));
case 2:
_ref = context$2$0.sent;
concurrency = _ref.concurrency;
orgFreeWindowsMachineCount = concurrency.organization.allowed.vms - concurrency.organization.current.vms;
orgFreeMacMachineCount = concurrency.organization.allowed.mac_vms - concurrency.organization.current.mac_vms;
orgFreeMachineCount = Math.min(orgFreeWindowsMachineCount, orgFreeMacMachineCount);
teamFreeWindowsMachineCount = concurrency.team.allowed.vms - concurrency.team.current.vms;
teamFreeMacMachineCount = concurrency.team.allowed.mac_vms - concurrency.team.current.mac_vms;
teamFreeMachineCount = Math.min(teamFreeWindowsMachineCount, teamFreeMacMachineCount);
return context$2$0.abrupt('return', Math.min(orgFreeMachineCount, teamFreeMachineCount));
case 11:
case 'end':
return context$2$0.stop();
}
}, null, this);
};
SauceLabsRunner.prototype._checkForFreeMachines = function _checkForFreeMachines() {
var freeMachinesCount;
return _regeneratorRuntime.async(function _checkForFreeMachines$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
context$2$0.next = 2;
return _regeneratorRuntime.awrap(this._getFreeMachineCount());
case 2:
freeMachinesCount = context$2$0.sent;
if (freeMachinesCount) this.emit('free-machines-found', { count: freeMachinesCount });
case 4:
case 'end':
return context$2$0.stop();
}
}, null, this);
};
SauceLabsRunner.prototype._startNextJobs = function _startNextJobs(count) {
var jobs, jobsComplete;
return _regeneratorRuntime.async(function _startNextJobs$(context$2$0) {
var _this2 = this;
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
jobs = this._getQueuedJobs(count);
if (jobs.length) {
jobs.forEach(function (job) {
job.run().then(function (result) {
_this2.jobResults = _this2.jobResults.concat(result);
_this2.emit('job-done');
});
});
} else {
if (this.freeMachineCheckInterval) {
clearInterval(this.freeMachineCheckInterval);
this.freeMachineCheckInterval = null;
}
jobsComplete = this._getCompletedJobsCount() + this._getFailedJobsCount() === this.jobs.length;
if (jobsComplete) this.emit('done');
}
case 2:
case 'end':
return context$2$0.stop();
}
}, null, this);
};
SauceLabsRunner.prototype._startFreeMachineChecker = function _startFreeMachineChecker() {
return _regeneratorRuntime.async(function _startFreeMachineChecker$(context$2$0) {
var _this3 = this;
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
this._checkForFreeMachines();
this.freeMachineCheckInterval = setInterval(function () {
return _this3._checkForFreeMachines();
}, WAITING_FOR_FREE_MACHINE_TIMEOUT);
case 2:
case 'end':
return context$2$0.stop();
}
}, null, this);
};
SauceLabsRunner.prototype.runTests = function runTests() {
var jobsDonePromise;
return _regeneratorRuntime.async(function runTests$(context$2$0) {
var _this4 = this;
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
this.jobs = this.options.browsers.map(function (browser) {
return new _job2.default(_this4.options, browser);
});
this._runCurrentTaskStatusReporting();
context$2$0.prev = 2;
jobsDonePromise = _promisifyEvent2.default(this, 'done');
this._startFreeMachineChecker();
this.on('free-machines-found', function (e) {
return _this4._startNextJobs(e.count);
});
this.on('job-done', function () {
return _this4._startNextJobs(1);
});
context$2$0.next = 9;
return _regeneratorRuntime.awrap(jobsDonePromise);
case 9:
clearInterval(this.reportingInterval);
context$2$0.next = 17;
break;
case 12:
context$2$0.prev = 12;
context$2$0.t0 = context$2$0['catch'](2);
clearInterval(this.freeMachineCheckInterval);
clearInterval(this.reportingInterval);
throw 'RUN TESTS ERROR: ' + context$2$0.t0;
case 17:
return context$2$0.abrupt('return', this.jobResults);
case 18:
case 'end':
return context$2$0.stop();
}
}, null, this, [[2, 12]]);
};
return SauceLabsRunner;
})(_events.EventEmitter);
exports.default = SauceLabsRunner;
module.exports = exports.default;