171 lines
29 KiB
JavaScript
171 lines
29 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 async_event_emitter_1 = __importDefault(require("../utils/async-event-emitter"));
|
||
|
//@ts-ignore
|
||
|
const testcafe_legacy_api_1 = require("testcafe-legacy-api");
|
||
|
const test_run_1 = __importDefault(require("../test-run"));
|
||
|
const session_controller_1 = __importDefault(require("../test-run/session-controller"));
|
||
|
const quarantine_1 = require("../utils/get-options/quarantine");
|
||
|
const DISCONNECT_THRESHOLD = 3;
|
||
|
class TestRunController extends async_event_emitter_1.default {
|
||
|
constructor({ test, index, proxy, screenshots, warningLog, fixtureHookController, opts, testRunHook, compilerService, messageBus, }) {
|
||
|
super();
|
||
|
this.test = test;
|
||
|
this.index = index;
|
||
|
this._opts = opts;
|
||
|
this._proxy = proxy;
|
||
|
this._screenshots = screenshots;
|
||
|
this._warningLog = warningLog;
|
||
|
this._fixtureHookController = fixtureHookController;
|
||
|
this._testRunHook = testRunHook;
|
||
|
this._testRunCtor = TestRunController._getTestRunCtor(test, opts);
|
||
|
this.testRun = null;
|
||
|
this.done = false;
|
||
|
this._quarantine = this._opts.quarantineMode ? new quarantine_1.Quarantine() : null;
|
||
|
this._disconnectionCount = 0;
|
||
|
this.compilerService = compilerService;
|
||
|
this._messageBus = messageBus;
|
||
|
}
|
||
|
static _getTestRunCtor(test, opts) {
|
||
|
if (opts.TestRunCtor)
|
||
|
return opts.TestRunCtor;
|
||
|
return test.isLegacy ? testcafe_legacy_api_1.TestRun : test_run_1.default;
|
||
|
}
|
||
|
async _createTestRun(connection, startRunExecutionTime) {
|
||
|
const screenshotCapturer = this._screenshots.createCapturerFor(this.test, this.index, this._quarantine, connection, this._warningLog);
|
||
|
const TestRunCtor = this._testRunCtor;
|
||
|
this.testRun = new TestRunCtor({
|
||
|
test: this.test,
|
||
|
browserConnection: connection,
|
||
|
globalWarningLog: this._warningLog,
|
||
|
opts: this._opts,
|
||
|
compilerService: this.compilerService,
|
||
|
messageBus: this._messageBus,
|
||
|
screenshotCapturer,
|
||
|
startRunExecutionTime,
|
||
|
});
|
||
|
await this.testRun.initialize();
|
||
|
this._screenshots.addTestRun(this.test, this.testRun);
|
||
|
if (this.testRun.addQuarantineInfo)
|
||
|
this.testRun.addQuarantineInfo(this._quarantine);
|
||
|
if (this._quarantine) {
|
||
|
const { successThreshold, attemptLimit } = this._opts.quarantineMode;
|
||
|
this._quarantine.setCustomParameters(attemptLimit, successThreshold);
|
||
|
}
|
||
|
if (!this._quarantine || this._isFirstQuarantineAttempt()) {
|
||
|
await this.emit('test-run-create', {
|
||
|
testRun: this.testRun,
|
||
|
legacy: TestRunCtor === testcafe_legacy_api_1.TestRun,
|
||
|
test: this.test,
|
||
|
index: this.index,
|
||
|
quarantine: this._quarantine,
|
||
|
});
|
||
|
}
|
||
|
return this.testRun;
|
||
|
}
|
||
|
async _endQuarantine() {
|
||
|
if (this._quarantine.attempts.length > 1)
|
||
|
this.testRun.unstable = this._quarantine.getPassedAttempts().length > 0;
|
||
|
await this._emitTestRunDone();
|
||
|
}
|
||
|
_shouldKeepInQuarantine() {
|
||
|
const errors = this.testRun.errs;
|
||
|
const hasErrors = !!errors.length;
|
||
|
const attempts = this._quarantine.attempts;
|
||
|
const isFirstAttempt = this._isFirstQuarantineAttempt();
|
||
|
attempts.push({ testRunId: this.testRun.id, errors });
|
||
|
return isFirstAttempt ? hasErrors : !this._quarantine.isThresholdReached();
|
||
|
}
|
||
|
_isFirstQuarantineAttempt() {
|
||
|
return !!this._quarantine && !this._quarantine.attempts.length;
|
||
|
}
|
||
|
async _keepInQuarantine() {
|
||
|
await this._restartTest();
|
||
|
}
|
||
|
async _restartTest() {
|
||
|
await this.emit('test-run-restart');
|
||
|
}
|
||
|
async _testRunDoneInQuarantineMode() {
|
||
|
if (this._shouldKeepInQuarantine())
|
||
|
await this._keepInQuarantine();
|
||
|
else
|
||
|
await this._endQuarantine();
|
||
|
}
|
||
|
async _testRunDone() {
|
||
|
if (this._quarantine)
|
||
|
await this._testRunDoneInQuarantineMode();
|
||
|
else
|
||
|
await this._emitTestRunDone();
|
||
|
}
|
||
|
async _emitActionStart(args) {
|
||
|
await this._messageBus.emit('test-action-start', args);
|
||
|
}
|
||
|
async _emitActionDone(args) {
|
||
|
await this.emit('test-action-done', args);
|
||
|
}
|
||
|
async _emitTestRunDone() {
|
||
|
// NOTE: we should report test run completion in order they were completed in browser.
|
||
|
// To keep a sequence after fixture hook execution we use completion queue.
|
||
|
await this._fixtureHookController.runFixtureAfterHookIfNecessary(this.testRun);
|
||
|
await this._testRunHook.runTestRunAfterHookIfNecessary(this.testRun);
|
||
|
this.done = true;
|
||
|
await this.emit('test-run-done');
|
||
|
}
|
||
|
async _emitTestRunStart() {
|
||
|
await this._messageBus.emit('test-run-start', this.testRun);
|
||
|
}
|
||
|
async _testRunBeforeDone() {
|
||
|
let raiseEvent = !this._quarantine;
|
||
|
if (!raiseEvent) {
|
||
|
const isSuccessfulQuarantineFirstAttempt = this._isFirstQuarantineAttempt() && !this.testRun.errs.length;
|
||
|
const isAttemptsThresholdReached = this._quarantine.isThresholdReached(this.testRun.errs);
|
||
|
raiseEvent = isSuccessfulQuarantineFirstAttempt || isAttemptsThresholdReached;
|
||
|
}
|
||
|
if (raiseEvent)
|
||
|
await this.emit('test-run-before-done');
|
||
|
}
|
||
|
_testRunDisconnected(connection) {
|
||
|
this._disconnectionCount++;
|
||
|
const disconnectionThresholdExceedeed = this._disconnectionCount >= DISCONNECT_THRESHOLD;
|
||
|
return connection
|
||
|
.processDisconnection(disconnectionThresholdExceedeed)
|
||
|
.then(() => {
|
||
|
return this._restartTest();
|
||
|
});
|
||
|
}
|
||
|
_assignTestRunEvents(testRun, connection) {
|
||
|
testRun.on('action-start', async (args) => this._emitActionStart(Object.assign(args, { testRun })));
|
||
|
testRun.on('action-done', async (args) => this._emitActionDone(Object.assign(args, { testRun })));
|
||
|
testRun.once('start', async () => this._emitTestRunStart());
|
||
|
testRun.once('ready', async () => {
|
||
|
if (!this._quarantine || this._isFirstQuarantineAttempt())
|
||
|
await this.emit('test-run-ready');
|
||
|
});
|
||
|
testRun.once('before-done', () => this._testRunBeforeDone());
|
||
|
testRun.once('done', () => this._testRunDone());
|
||
|
testRun.once('disconnected', () => this._testRunDisconnected(connection));
|
||
|
}
|
||
|
get blocked() {
|
||
|
return this._fixtureHookController.isTestBlocked(this.test);
|
||
|
}
|
||
|
async start(connection, startRunExecutionTime) {
|
||
|
const testRun = await this._createTestRun(connection, startRunExecutionTime);
|
||
|
const hookOk = await this._testRunHook.runTestRunBeforeHookIfNecessary(testRun)
|
||
|
&& await this._fixtureHookController.runFixtureBeforeHookIfNecessary(testRun);
|
||
|
if (this.test.skip || !hookOk) {
|
||
|
await this._emitTestRunStart();
|
||
|
await this.emit('test-run-before-done');
|
||
|
await this._emitTestRunDone();
|
||
|
return null;
|
||
|
}
|
||
|
this._assignTestRunEvents(testRun, connection);
|
||
|
testRun.start();
|
||
|
return session_controller_1.default.getSessionUrl(testRun, this._proxy);
|
||
|
}
|
||
|
}
|
||
|
exports.default = TestRunController;
|
||
|
module.exports = exports.default;
|
||
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1ydW4tY29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW5uZXIvdGVzdC1ydW4tY29udHJvbGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHVGQUE2RDtBQUM3RCxZQUFZO0FBQ1osNkRBQStEO0FBQy9ELDJEQUFrQztBQUNsQyx3RkFBK0Q7QUFVL0QsZ0VBQTZEO0FBSTdELE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0FBRy9CLE1BQXFCLGlCQUFrQixTQUFRLDZCQUFpQjtJQWlCNUQsWUFBb0IsRUFDaEIsSUFBSSxFQUNKLEtBQUssRUFDTCxLQUFLLEVBQ0wsV0FBVyxFQUNYLFVBQVUsRUFDVixxQkFBcUIsRUFDckIsSUFBSSxFQUNKLFdBQVcsRUFDWCxlQUFlLEVBQ2YsVUFBVSxHQUNVO1FBQ3BCLEtBQUssRUFBRSxDQUFDO1FBRVIsSUFBSSxDQUFDLElBQUksR0FBSSxJQUFJLENBQUM7UUFDbEIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7UUFFbEIsSUFBSSxDQUFDLE1BQU0sR0FBbUIsS0FBSyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxZQUFZLEdBQWEsV0FBVyxDQUFDO1FBQzFDLElBQUksQ0FBQyxXQUFXLEdBQWMsVUFBVSxDQUFDO1FBQ3pDLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxxQkFBcUIsQ0FBQztRQUNwRCxJQUFJLENBQUMsWUFBWSxHQUFhLFdBQVcsQ0FBQztRQUUxQyxJQUFJLENBQUMsWUFBWSxHQUFHLGlCQUFpQixDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFbEUsSUFBSSxDQUFDLE9BQU8sR0FBZSxJQUFJLENBQUM7UUFDaEMsSUFBSSxDQUFDLElBQUksR0FBa0IsS0FBSyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxXQUFXLEdBQVcsSUFBSSxDQUFDLEtB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
|