testcafe
Version:
Automated browser testing for the modern web development stack.
115 lines • 18.7 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const pinkie_1 = __importDefault(require("pinkie"));
const lodash_1 = require("lodash");
const async_event_emitter_1 = __importDefault(require("../utils/async-event-emitter"));
const test_run_controller_1 = __importDefault(require("./test-run-controller"));
const session_controller_1 = __importDefault(require("../test-run/session-controller"));
const browser_job_result_1 = __importDefault(require("./browser-job-result"));
// Browser job
class BrowserJob extends async_event_emitter_1.default {
constructor(tests, browserConnections, proxy, screenshots, warningLog, fixtureHookController, opts) {
super();
this.started = false;
this.total = 0;
this.passed = 0;
this.opts = opts;
this.proxy = proxy;
this.browserConnections = browserConnections;
this.screenshots = screenshots;
this.warningLog = warningLog;
this.fixtureHookController = fixtureHookController;
this.result = null;
this.testRunControllerQueue = tests.map((test, index) => this._createTestRunController(test, index));
this.completionQueue = [];
this.connectionErrorListener = error => this._setResult(browser_job_result_1.default.errored, error);
this.browserConnections.map(bc => bc.once('error', this.connectionErrorListener));
}
_createTestRunController(test, index) {
const testRunController = new test_run_controller_1.default(test, index + 1, this.proxy, this.screenshots, this.warningLog, this.fixtureHookController, this.opts);
testRunController.on('test-run-create', async (testRunInfo) => {
await this.emit('test-run-create', testRunInfo);
});
testRunController.on('test-run-start', async () => {
await this.emit('test-run-start', testRunController.testRun);
});
testRunController.on('test-run-ready', async () => {
await this.emit('test-run-ready', testRunController);
});
testRunController.on('test-run-restart', async () => this._onTestRunRestart(testRunController));
testRunController.on('test-run-before-done', async () => {
await this.emit('test-run-before-done', testRunController);
});
testRunController.on('test-run-done', async () => this._onTestRunDone(testRunController));
return testRunController;
}
async _setResult(status, data) {
if (this.result)
return;
this.result = { status, data };
this.browserConnections.forEach(bc => bc.removeListener('error', this.connectionErrorListener));
await pinkie_1.default.all(this.browserConnections.map(bc => bc.reportJobResult(this.result.status, this.result.data)));
}
_addToCompletionQueue(testRunInfo) {
this.completionQueue.push(testRunInfo);
}
_removeFromCompletionQueue(testRunInfo) {
lodash_1.remove(this.completionQueue, testRunInfo);
}
_onTestRunRestart(testRunController) {
this._removeFromCompletionQueue(testRunController);
this.testRunControllerQueue.unshift(testRunController);
}
async _onTestRunDone(testRunController) {
this.total++;
if (!testRunController.testRun.errs.length)
this.passed++;
while (this.completionQueue.length && this.completionQueue[0].done) {
testRunController = this.completionQueue.shift();
await this.emit('test-run-done', testRunController.testRun);
}
if (!this.completionQueue.length && !this.hasQueuedTestRuns) {
if (!this.opts.live)
session_controller_1.default.closeSession(testRunController.testRun);
this
._setResult(browser_job_result_1.default.done, { total: this.total, passed: this.passed })
.then(() => this.emit('done'));
}
}
// API
get hasQueuedTestRuns() {
return !!this.testRunControllerQueue.length;
}
async popNextTestRunUrl(connection) {
while (this.testRunControllerQueue.length) {
// NOTE: before hook for test run fixture is currently
// executing, so test run is temporary blocked
const isBlocked = this.testRunControllerQueue[0].blocked;
const isConcurrency = this.opts.concurrency > 1;
const hasIncompleteTestRuns = this.completionQueue.some(controller => !controller.done);
if (isBlocked || hasIncompleteTestRuns && !isConcurrency)
break;
const testRunController = this.testRunControllerQueue.shift();
this._addToCompletionQueue(testRunController);
if (!this.started) {
this.started = true;
await this.emit('start');
}
const testRunUrl = await testRunController.start(connection);
if (testRunUrl)
return testRunUrl;
}
return null;
}
abort() {
this.clearListeners();
this._setResult(browser_job_result_1.default.aborted);
this.browserConnections.map(bc => bc.removeJob(this));
}
}
exports.default = BrowserJob;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJvd3Nlci1qb2IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVubmVyL2Jyb3dzZXItam9iLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsb0RBQTZCO0FBQzdCLG1DQUFnQztBQUNoQyx1RkFBNkQ7QUFDN0QsZ0ZBQXNEO0FBQ3RELHdGQUErRDtBQUMvRCw4RUFBMEM7QUFHMUMsY0FBYztBQUNkLE1BQXFCLFVBQVcsU0FBUSw2QkFBaUI7SUFDckQsWUFBYSxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUscUJBQXFCLEVBQUUsSUFBSTtRQUMvRixLQUFLLEVBQUUsQ0FBQztRQUVSLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBRXJCLElBQUksQ0FBQyxLQUFLLEdBQW1CLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsTUFBTSxHQUFrQixDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLElBQUksR0FBb0IsSUFBSSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxLQUFLLEdBQW1CLEtBQUssQ0FBQztRQUNuQyxJQUFJLENBQUMsa0JBQWtCLEdBQU0sa0JBQWtCLENBQUM7UUFDaEQsSUFBSSxDQUFDLFdBQVcsR0FBYSxXQUFXLENBQUM7UUFDekMsSUFBSSxDQUFDLFVBQVUsR0FBYyxVQUFVLENBQUM7UUFDeEMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLHFCQUFxQixDQUFDO1FBQ25ELElBQUksQ0FBQyxNQUFNLEdBQWtCLElBQUksQ0FBQztRQUVsQyxJQUFJLENBQUMsc0JBQXNCLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUVyRyxJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztRQUUxQixJQUFJLENB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Q0FBQyxVQUFVLENBQUMsNEJBQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzFELENBQUM7Q0FDSjtBQXBJRCw2QkFvSUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUHJvbWlzZSBmcm9tICdwaW5raWUnO1xuaW1wb3J0IHsgcmVtb3ZlIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBBc3luY0V2ZW50RW1pdHRlciBmcm9tICcuLi91dGlscy9hc3luYy1ldmVudC1lbWl0dGVyJztcbmltcG9ydCBUZXN0UnVuQ29udHJvbGxlciBmcm9tICcuL3Rlc3QtcnVuLWNvbnRyb2xsZXInO1xuaW1wb3J0IFNlc3Npb25Db250cm9sbGVyIGZyb20gJy4uL3Rlc3QtcnVuL3Nlc3Npb24tY29udHJvbGxlcic7XG5pbXBvcnQgUkVTVUxUIGZyb20gJy4vYnJvd3Nlci1qb2ItcmVzdWx0JztcblxuXG4vLyBCcm93c2VyIGpvYlxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnJvd3NlckpvYiBleHRlbmRzIEFzeW5jRXZlbnRFbWl0dGVyIHtcbiAgICBjb25zdHJ1Y3RvciAodGVzdHMsIGJyb3dzZXJDb25uZWN0aW9ucywgcHJveHksIHNjcmVlbnNob3RzLCB3YXJuaW5nTG9nLCBmaXh0dXJlSG9va0NvbnRyb2xsZXIsIG9wdHMpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzLnN0YXJ0ZWQgPSBmYWxzZTtcblxuICAgICAgICB0aGlzLnRvdGFsICAgICAgICAgICAgICAgICA9IDA7XG4gICAgICAgIHRoaXMucGFzc2VkICAgICAgICAgICAgICAgID0gMDtcbiAgICAgICAgdGhpcy5vcHRzICAgICAgICAgICAgICAgICAgPSBvcHRzO1xuICAgICAgICB0aGlzLnByb3h5ICAgICAgICAgICAgICAgICA9IHByb3h5O1xuICAgICAgICB0aGlzLmJyb3dzZXJDb25uZWN0aW9ucyAgICA9IGJyb3dzZXJDb25uZWN0aW9ucztcbiAgICAgICAgdGhpcy5zY3JlZW5zaG90cyAgICAgICAgICAgPSBzY3JlZW5zaG90cztcbiAgICAgICAgdGhpcy53YXJuaW5nTG9nICAgICAgICAgICAgPSB3YXJuaW5nTG9nO1xuICAgICAgICB0aGlzLmZpeHR1cmVIb29rQ29udHJvbGxlciA9IGZpeHR1cmVIb29rQ29udHJvbGxlcjtcbiAgICAgICAgdGhpcy5yZXN1bHQgICAgICAgICAgICAgICAgPSBudWxsO1xuXG4gICAgICAgIHRoaXMudGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZSA9IHRlc3RzLm1hcCgodGVzdCwgaW5kZXgpID0+IHRoaXMuX2NyZWF0ZVRlc3RSdW5Db250cm9sbGVyKHRlc3QsIGluZGV4KSk7XG5cbiAgICAgICAgdGhpcy5jb21wbGV0aW9uUXVldWUgPSBbXTtcblxuICAgICAgICB0aGlzLmNvbm5lY3Rpb25FcnJvckxpc3RlbmVyID0gZXJyb3IgPT4gdGhpcy5fc2V0UmVzdWx0KFJFU1VMVC5lcnJvcmVkLCBlcnJvcik7XG5cbiAgICAgICAgdGhpcy5icm93c2VyQ29ubmVjdGlvbnMubWFwKGJjID0+IGJjLm9uY2UoJ2Vycm9yJywgdGhpcy5jb25uZWN0aW9uRXJyb3JMaXN0ZW5lcikpO1xuICAgIH1cblxuICAgIF9jcmVhdGVUZXN0UnVuQ29udHJvbGxlciAodGVzdCwgaW5kZXgpIHtcbiAgICAgICAgY29uc3QgdGVzdFJ1bkNvbnRyb2xsZXIgPSBuZXcgVGVzdFJ1bkNvbnRyb2xsZXIodGVzdCwgaW5kZXggKyAxLCB0aGlzLnByb3h5LCB0aGlzLnNjcmVlbnNob3RzLCB0aGlzLndhcm5pbmdMb2csXG4gICAgICAgICAgICB0aGlzLmZpeHR1cmVIb29rQ29udHJvbGxlciwgdGhpcy5vcHRzKTtcblxuICAgICAgICB0ZXN0UnVuQ29udHJvbGxlci5vbigndGVzdC1ydW4tY3JlYXRlJywgYXN5bmMgdGVzdFJ1bkluZm8gPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCd0ZXN0LXJ1bi1jcmVhdGUnLCB0ZXN0UnVuSW5mbyk7XG4gICAgICAgIH0pO1xuICAgICAgICB0ZXN0UnVuQ29udHJvbGxlci5vbigndGVzdC1ydW4tc3RhcnQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ3Rlc3QtcnVuLXN0YXJ0JywgdGVzdFJ1bkNvbnRyb2xsZXIudGVzdFJ1bik7XG4gICAgICAgIH0pO1xuICAgICAgICB0ZXN0UnVuQ29udHJvbGxlci5vbigndGVzdC1ydW4tcmVhZHknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ3Rlc3QtcnVuLXJlYWR5JywgdGVzdFJ1bkNvbnRyb2xsZXIpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGVzdFJ1bkNvbnRyb2xsZXIub24oJ3Rlc3QtcnVuLXJlc3RhcnQnLCBhc3luYyAoKSA9PiB0aGlzLl9vblRlc3RSdW5SZXN0YXJ0KHRlc3RSdW5Db250cm9sbGVyKSk7XG4gICAgICAgIHRlc3RSdW5Db250cm9sbGVyLm9uKCd0ZXN0LXJ1bi1iZWZvcmUtZG9uZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdCgndGVzdC1ydW4tYmVmb3JlLWRvbmUnLCB0ZXN0UnVuQ29udHJvbGxlcik7XG4gICAgICAgIH0pO1xuICAgICAgICB0ZXN0UnVuQ29udHJvbGxlci5vbigndGVzdC1ydW4tZG9uZScsIGFzeW5jICgpID0+IHRoaXMuX29uVGVzdFJ1bkRvbmUodGVzdFJ1bkNvbnRyb2xsZXIpKTtcblxuICAgICAgICByZXR1cm4gdGVzdFJ1bkNvbnRyb2xsZXI7XG4gICAgfVxuXG4gICAgYXN5bmMgX3NldFJlc3VsdCAoc3RhdHVzLCBkYXRhKSB7XG4gICAgICAgIGlmICh0aGlzLnJlc3VsdClcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICB0aGlzLnJlc3VsdCA9IHsgc3RhdHVzLCBkYXRhIH07XG5cbiAgICAgICAgdGhpcy5icm93c2VyQ29ubmVjdGlvbnMuZm9yRWFjaChiYyA9PiBiYy5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCB0aGlzLmNvbm5lY3Rpb25FcnJvckxpc3RlbmVyKSk7XG5cbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwodGhpcy5icm93c2VyQ29ubmVjdGlvbnMubWFwKGJjID0+IGJjLnJlcG9ydEpvYlJlc3VsdCh0aGlzLnJlc3VsdC5zdGF0dXMsIHRoaXMucmVzdWx0LmRhdGEpKSk7XG4gICAgfVxuXG4gICAgX2FkZFRvQ29tcGxldGlvblF1ZXVlICh0ZXN0UnVuSW5mbykge1xuICAgICAgICB0aGlzLmNvbXBsZXRpb25RdWV1ZS5wdXNoKHRlc3RSdW5JbmZvKTtcbiAgICB9XG5cbiAgICBfcmVtb3ZlRnJvbUNvbXBsZXRpb25RdWV1ZSAodGVzdFJ1bkluZm8pIHtcbiAgICAgICAgcmVtb3ZlKHRoaXMuY29tcGxldGlvblF1ZXVlLCB0ZXN0UnVuSW5mbyk7XG4gICAgfVxuXG4gICAgX29uVGVzdFJ1blJlc3RhcnQgKHRlc3RSdW5Db250cm9sbGVyKSB7XG4gICAgICAgIHRoaXMuX3JlbW92ZUZyb21Db21wbGV0aW9uUXVldWUodGVzdFJ1bkNvbnRyb2xsZXIpO1xuICAgICAgICB0aGlzLnRlc3RSdW5Db250cm9sbGVyUXVldWUudW5zaGlmdCh0ZXN0UnVuQ29udHJvbGxlcik7XG4gICAgfVxuXG4gICAgYXN5bmMgX29uVGVzdFJ1bkRvbmUgKHRlc3RSdW5Db250cm9sbGVyKSB7XG4gICAgICAgIHRoaXMudG90YWwrKztcblxuICAgICAgICBpZiAoIXRlc3RSdW5Db250cm9sbGVyLnRlc3RSdW4uZXJycy5sZW5ndGgpXG4gICAgICAgICAgICB0aGlzLnBhc3NlZCsrO1xuXG4gICAgICAgIHdoaWxlICh0aGlzLmNvbXBsZXRpb25RdWV1ZS5sZW5ndGggJiYgdGhpcy5jb21wbGV0aW9uUXVldWVbMF0uZG9uZSkge1xuICAgICAgICAgICAgdGVzdFJ1bkNvbnRyb2xsZXIgPSB0aGlzLmNvbXBsZXRpb25RdWV1ZS5zaGlmdCgpO1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ3Rlc3QtcnVuLWRvbmUnLCB0ZXN0UnVuQ29udHJvbGxlci50ZXN0UnVuKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5jb21wbGV0aW9uUXVldWUubGVuZ3RoICYmICF0aGlzLmhhc1F1ZXVlZFRlc3RSdW5zKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMub3B0cy5saXZlKVxuICAgICAgICAgICAgICAgIFNlc3Npb25Db250cm9sbGVyLmNsb3NlU2Vzc2lvbih0ZXN0UnVuQ29udHJvbGxlci50ZXN0UnVuKTtcblxuICAgICAgICAgICAgdGhpc1xuICAgICAgICAgICAgICAgIC5fc2V0UmVzdWx0KFJFU1VMVC5kb25lLCB7IHRvdGFsOiB0aGlzLnRvdGFsLCBwYXNzZWQ6IHRoaXMucGFzc2VkIH0pXG4gICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5lbWl0KCdkb25lJykpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gQVBJXG4gICAgZ2V0IGhhc1F1ZXVlZFRlc3RSdW5zICgpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy50ZXN0UnVuQ29udHJvbGxlclF1ZXVlLmxlbmd0aDtcbiAgICB9XG5cbiAgICBhc3luYyBwb3BOZXh0VGVzdFJ1blVybCAoY29ubmVjdGlvbikge1xuICAgICAgICB3aGlsZSAodGhpcy50ZXN0UnVuQ29udHJvbGxlclF1ZXVlLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8gTk9URTogYmVmb3JlIGhvb2sgZm9yIHRlc3QgcnVuIGZpeHR1cmUgaXMgY3VycmVudGx5XG4gICAgICAgICAgICAvLyBleGVjdXRpbmcsIHNvIHRlc3QgcnVuIGlzIHRlbXBvcmFyeSBibG9ja2VkXG4gICAgICAgICAgICBjb25zdCBpc0Jsb2NrZWQgICAgICAgICAgICAgPSB0aGlzLnRlc3RSdW5Db250cm9sbGVyUXVldWVbMF0uYmxvY2tlZDtcbiAgICAgICAgICAgIGNvbnN0IGlzQ29uY3VycmVuY3kgICAgICAgICA9IHRoaXMub3B0cy5jb25jdXJyZW5jeSA+IDE7XG4gICAgICAgICAgICBjb25zdCBoYXNJbmNvbXBsZXRlVGVzdFJ1bnMgPSB0aGlzLmNvbXBsZXRpb25RdWV1ZS5zb21lKGNvbnRyb2xsZXIgPT4gIWNvbnRyb2xsZXIuZG9uZSk7XG5cbiAgICAgICAgICAgIGlmIChpc0Jsb2NrZWQgfHwgaGFzSW5jb21wbGV0ZVRlc3RSdW5zICYmICFpc0NvbmN1cnJlbmN5KVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjb25zdCB0ZXN0UnVuQ29udHJvbGxlciA9IHRoaXMudGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZS5zaGlmdCgpO1xuXG4gICAgICAgICAgICB0aGlzLl9hZGRUb0NvbXBsZXRpb25RdWV1ZSh0ZXN0UnVuQ29udHJvbGxlcik7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5zdGFydGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGFydGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ3N0YXJ0Jyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHRlc3RSdW5VcmwgPSBhd2FpdCB0ZXN0UnVuQ29udHJvbGxlci5zdGFydChjb25uZWN0aW9uKTtcblxuICAgICAgICAgICAgaWYgKHRlc3RSdW5VcmwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRlc3RSdW5Vcmw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBhYm9ydCAoKSB7XG4gICAgICAgIHRoaXMuY2xlYXJMaXN0ZW5lcnMoKTtcbiAgICAgICAgdGhpcy5fc2V0UmVzdWx0KFJFU1VMVC5hYm9ydGVkKTtcbiAgICAgICAgdGhpcy5icm93c2VyQ29ubmVjdGlvbnMubWFwKGJjID0+IGJjLnJlbW92ZUpvYih0aGlzKSk7XG4gICAgfVxufVxuIl19