175 lines
31 KiB
JavaScript
175 lines
31 KiB
JavaScript
|
"use strict";
|
||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
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"));
|
||
|
const test_run_hook_controller_1 = __importDefault(require("./test-run-hook-controller"));
|
||
|
var BrowserJobStatus;
|
||
|
(function (BrowserJobStatus) {
|
||
|
BrowserJobStatus[BrowserJobStatus["initialized"] = 0] = "initialized";
|
||
|
BrowserJobStatus[BrowserJobStatus["starting"] = 1] = "starting";
|
||
|
BrowserJobStatus[BrowserJobStatus["started"] = 2] = "started";
|
||
|
})(BrowserJobStatus || (BrowserJobStatus = {}));
|
||
|
class BrowserJob extends async_event_emitter_1.default {
|
||
|
constructor({ tests, browserConnections, proxy, screenshots, warningLog, fixtureHookController, opts, compilerService, messageBus, }) {
|
||
|
var _a;
|
||
|
super();
|
||
|
this._status = BrowserJobStatus.initialized;
|
||
|
this._startTime = new Date();
|
||
|
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._messageBus = messageBus;
|
||
|
this._testRunHook = new test_run_hook_controller_1.default(tests, (_a = opts.hooks) === null || _a === void 0 ? void 0 : _a.testRun);
|
||
|
this._testRunControllerQueue = tests.map((test, index) => this._createTestRunController(test, index, compilerService));
|
||
|
this._completionQueue = [];
|
||
|
this._reportsPending = [];
|
||
|
this._connectionErrorListener = (error) => this._setResult(browser_job_result_1.default.errored, error);
|
||
|
this._resolveWaitingLastTestInFixture = null;
|
||
|
this.browserConnections.map(bc => bc.once('error', this._connectionErrorListener));
|
||
|
}
|
||
|
_createTestRunController(test, index, compilerService) {
|
||
|
const testRunController = new test_run_controller_1.default({
|
||
|
test,
|
||
|
index: index + 1,
|
||
|
proxy: this._proxy,
|
||
|
screenshots: this._screenshots,
|
||
|
warningLog: this.warningLog,
|
||
|
fixtureHookController: this.fixtureHookController,
|
||
|
opts: this._opts,
|
||
|
messageBus: this._messageBus,
|
||
|
compilerService,
|
||
|
testRunHook: this._testRunHook,
|
||
|
});
|
||
|
testRunController.on('test-run-create', async (testRunInfo) => {
|
||
|
await this.emit('test-run-create', testRunInfo);
|
||
|
});
|
||
|
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));
|
||
|
testRunController.on('test-action-done', async (args) => {
|
||
|
await this.emit('test-action-done', args);
|
||
|
});
|
||
|
return testRunController;
|
||
|
}
|
||
|
async _setResult(status, data) {
|
||
|
if (this._result)
|
||
|
return;
|
||
|
this._result = { status, data };
|
||
|
this.browserConnections.forEach(bc => bc.removeListener('error', this._connectionErrorListener));
|
||
|
await Promise.all(this.browserConnections.map(bc => bc.reportJobResult(this._result.status, this._result.data)));
|
||
|
}
|
||
|
_addToCompletionQueue(testRunInfo) {
|
||
|
this._completionQueue.push(testRunInfo);
|
||
|
}
|
||
|
_removeFromCompletionQueue(testRunInfo) {
|
||
|
(0, lodash_1.pull)(this._completionQueue, testRunInfo);
|
||
|
}
|
||
|
async _onTestRunRestart(testRunController) {
|
||
|
this._removeFromCompletionQueue(testRunController);
|
||
|
this._testRunControllerQueue.unshift(testRunController);
|
||
|
await this.emit('test-run-restart', 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);
|
||
|
(0, lodash_1.pull)(this._reportsPending, testRunController);
|
||
|
if (!this._reportsPending.length && this._resolveWaitingLastTestInFixture) {
|
||
|
this._resolveWaitingLastTestInFixture();
|
||
|
this._resolveWaitingLastTestInFixture = null;
|
||
|
}
|
||
|
}
|
||
|
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'));
|
||
|
}
|
||
|
}
|
||
|
async _isNextTestRunAvailable(testRunController) {
|
||
|
// NOTE: event task start is currently executing,
|
||
|
// so test run is temporary blocked
|
||
|
if (this._status === BrowserJobStatus.starting)
|
||
|
return false;
|
||
|
// NOTE: before hook for test run fixture is currently
|
||
|
// executing, so test run is temporary blocked
|
||
|
const isBlocked = testRunController.blocked;
|
||
|
const isConcurrency = this._opts.concurrency > 1;
|
||
|
const hasIncompleteTestRuns = this._completionQueue.some(controller => !controller.done);
|
||
|
const needWaitLastTestInFixture = this._reportsPending.some(controller => controller.test.fixture !== testRunController.test.fixture);
|
||
|
if (isBlocked || (hasIncompleteTestRuns || needWaitLastTestInFixture) && !isConcurrency) {
|
||
|
const disablePageReloads = testRunController.test.disablePageReloads ||
|
||
|
this._opts.disablePageReloads && testRunController.test.disablePageReloads !== false;
|
||
|
if (!needWaitLastTestInFixture || !disablePageReloads)
|
||
|
return false;
|
||
|
// NOTE: if we have `disablePageReloads` enabled and the next test is from next
|
||
|
// fixture, then we need to wait until all reporters finished to prevent
|
||
|
// redirecting to the `idle` page
|
||
|
await new Promise(resolve => {
|
||
|
this._resolveWaitingLastTestInFixture = resolve;
|
||
|
});
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
// API
|
||
|
get hasQueuedTestRuns() {
|
||
|
return !!this._testRunControllerQueue.length;
|
||
|
}
|
||
|
get currentTestRun() {
|
||
|
return this._completionQueue.length ? this._completionQueue[0].testRun : null;
|
||
|
}
|
||
|
async popNextTestRunInfo(connection) {
|
||
|
while (this._testRunControllerQueue.length) {
|
||
|
const testRunController = this._testRunControllerQueue[0];
|
||
|
const isNextTestRunAvailable = await this._isNextTestRunAvailable(testRunController);
|
||
|
if (!isNextTestRunAvailable)
|
||
|
break;
|
||
|
this._reportsPending.push(testRunController);
|
||
|
this._testRunControllerQueue.shift();
|
||
|
this._addToCompletionQueue(testRunController);
|
||
|
if (this._status === BrowserJobStatus.initialized) {
|
||
|
this._status = BrowserJobStatus.starting;
|
||
|
this._startTime = new Date();
|
||
|
await this.emit('start', this._startTime);
|
||
|
this._status = BrowserJobStatus.started;
|
||
|
}
|
||
|
const testRunUrl = await testRunController.start(connection, this._startTime);
|
||
|
if (testRunUrl) {
|
||
|
return {
|
||
|
testRunId: testRunController.testRun.id,
|
||
|
url: 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJvd3Nlci1qb2IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVubmVyL2Jyb3dzZXItam9iLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsbUNBQXdDO0FBQ3hDLHVGQUE2RDtBQUM3RCxnRkFBc0Q7QUFDdEQsd0ZBQStEO0FBUS9ELDhFQUFvRDtBQUlwRCwwRkFBK0Q7QUFXL0QsSUFBSyxnQkFBbUQ7QUFBeEQsV0FBSyxnQkFBZ0I7SUFBRyxxRUFBVyxDQUFBO0lBQUUsK0RBQVEsQ0FBQTtJQUFFLDZEQUFPLENBQUE7QUFBQyxDQUFDLEVBQW5ELGdCQUFnQixLQUFoQixnQkFBZ0IsUUFBbUM7QUFFeEQsTUFBcUIsVUFBVyxTQUFRLDZCQUFpQjtJQW9CckQsWUFBb0IsRUFDaEIsS0FBSyxFQUNMLGtCQUFrQixFQUNsQixLQUFLLEVBQ0wsV0FBVyxFQUNYLFVBQVUsRUFDVixxQkFBcUIsRUFDckIsSUFBSSxFQUNKLGVBQWUsRUFDZixVQUFVLEdBQ0c7O1FBQ2IsS0FBSyxFQUFFLENBQUM7UUFFUixJQUFJLENBQUMsT0FBTyxHQUFHLGdCQUFnQixDQUFDLFdBQVcsQ0FBQztRQUM1QyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFFN0IsSUFBSSxDQUFDLE1BQU0sR0FBa0IsQ0FBQyxDQUFDO1FBQy9CLElBQUksQ0FBQyxPQUFPLEdBQWlCLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsS0FBSyxHQUFtQixJQUFJLENBQUM7UUFDbEMsSUFBSSxDQUFDLE1BQU0sR0FBa0IsS0FBSyxDQUFDO1FBQ25DLElBQUksQ0FBQyxrQkFBa0IsR0FBTSxrQkFBa0IsQ0FBQztRQUNoRCxJQUFJLENBQUMsWUFBWSxHQUFZLFdBQVcsQ0FBQztRQUN6QyxJQUFJLENBQUMsVUFBVSxHQUFjLFVBQVUsQ0FBQztRQUN4QyxJQUFJLENBQUMscUJBQXFCLEdBQUcscUJBQXFCLENBQUM7UUFDbkQsSUFBSSxD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
|