testplane
Version:
Tests framework based on mocha and wdio
170 lines • 7.57 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MainRunner = void 0;
const lodash_1 = __importDefault(require("lodash"));
const eventsUtils = __importStar(require("../events/utils"));
const temp = __importStar(require("../temp"));
const pool = __importStar(require("../browser-pool"));
const browser_runner_1 = require("./browser-runner");
const events_1 = require("../events");
const types_1 = require("./types");
const runtime_config_1 = __importDefault(require("../config/runtime-config"));
const workers_registry_1 = __importDefault(require("../utils/workers-registry"));
const promise_group_1 = __importDefault(require("./promise-group"));
const logger = __importStar(require("../utils/logger"));
const runner_1 = require("../browser/cdp/selectivity/runner");
/**
* Part of Public API:
* @link https://testplane.io/docs/v8/reference/testplane-events/#runner_start
*/
class MainRunner extends types_1.RunnableEmitter {
constructor(config, interceptors) {
super();
this.config = config;
this.interceptors = interceptors;
this.browserPool = null;
this.activeBrowserRunners = new Map();
this.running = new promise_group_1.default();
this.runned = false;
this.cancelled = false;
this.workersRegistry = workers_registry_1.default.create(this.config);
this.workers = null;
eventsUtils.passthroughEvent(this.workersRegistry, this, [
events_1.MasterEvents.NEW_WORKER_PROCESS,
events_1.MasterEvents.ERROR,
events_1.MasterEvents.DOM_SNAPSHOTS,
events_1.MasterEvents.ADD_FILE_TO_REMOVE,
events_1.MasterEvents.TEST_DEPENDENCIES,
events_1.MasterEvents.TEST_ASSIGNED_TO_WORKER,
]);
temp.init(this.config.system.tempDir);
runtime_config_1.default.getInstance().extend({ tempOpts: temp.serialize() });
}
init() {
if (this.workers) {
return;
}
this.workersRegistry.init();
this.workers = this.registerWorkers(require.resolve("../worker"), ["runTest", "cancel"]);
this.browserPool = pool.create(this.config, this);
}
_isRunning() {
return this.runned && !this.workersRegistry.isEnded() && !this.cancelled;
}
async run(testCollection, stats, opts) {
this.runned = true;
try {
await this.emitAndWait(events_1.MasterEvents.RUNNER_START, this);
this.emit(events_1.MasterEvents.BEGIN);
!this.cancelled && (await this._runTests(testCollection, opts));
}
finally {
this.emit(events_1.MasterEvents.END);
await this.emitAndWait(events_1.MasterEvents.RUNNER_END, stats.getResult()).catch(logger.warn);
await this.workersRegistry.end();
}
}
addTestToRun(test, browserId) {
if (!this._isRunning() || this.running.isFulfilled()) {
return false;
}
const runner = this.activeBrowserRunners.get(browserId);
if (runner && runner.addTestToRun(test)) {
return true;
}
const browserRunner = this._addTestToBrowserRunner(test, browserId);
this.running.add(this._waitBrowserRunnerTestsCompletion(browserRunner));
return true;
}
async _runTests(testCollection, opts) {
const runTestFn = this._addTestToBrowserRunner.bind(this);
const selectivityRunner = runner_1.SelectivityRunner.create(this, this.config, runTestFn, {
shouldDisableSelectivity: opts?.shouldDisableSelectivity,
});
testCollection.eachTestAcrossBrowsers((test, browserId) => selectivityRunner.startTestCheckToRun(test, browserId));
await selectivityRunner.runNecessaryTests();
this.activeBrowserRunners.forEach(runner => this.running.add(this._waitBrowserRunnerTestsCompletion(runner)));
return this.running.done();
}
_addTestToBrowserRunner(test, browserId) {
const browserRunner = this.activeBrowserRunners.get(browserId) || this._createBrowserRunner(browserId);
browserRunner.addTestToRun(test);
return browserRunner;
}
_createBrowserRunner(browserId) {
const runner = browser_runner_1.BrowserRunner.create(browserId, this.config, this.browserPool, this.workers);
eventsUtils.passthroughEvent(runner, this, this.getEventsToPassthrough());
this.interceptEvents(runner, this.getEventsToIntercept());
this.activeBrowserRunners.set(browserId, runner);
return runner;
}
async _waitBrowserRunnerTestsCompletion(runner) {
await runner.waitTestsCompletion();
this.activeBrowserRunners.delete(runner.browserId);
}
getEventsToPassthrough() {
return (0, lodash_1.default)(events_1.RunnerSyncEvents).values().difference(this.getEventsToIntercept()).value();
}
getEventsToIntercept() {
return (0, lodash_1.default)(this.interceptors).map("event").uniq().value();
}
interceptEvents(runner, events) {
events.forEach((event) => {
runner.on(event, data => {
try {
const toEmit = this.applyInterceptors({ event, data }, this.interceptors);
toEmit && toEmit.event && this.emit(toEmit.event, toEmit.data);
}
catch (e) {
this.emit(events_1.MasterEvents.ERROR, e);
}
});
});
}
applyInterceptors({ event, data } = {}, interceptors) {
const interceptor = lodash_1.default.find(interceptors, { event });
if (!interceptor) {
return { event, data };
}
return this.applyInterceptors(interceptor.handler({ event, data }) || { event, data }, lodash_1.default.without(interceptors, interceptor));
}
cancel(error) {
this.cancelled = true;
this.browserPool?.cancel(error);
this.activeBrowserRunners.forEach(runner => runner.cancel(error));
this.workers?.cancel().catch(() => {
/* we can just ignore the error thrown, because we don't care about cleanup at this point */
});
}
registerWorkers(workerFilepath, exportedMethods) {
return this.workersRegistry.register(workerFilepath, exportedMethods);
}
}
exports.MainRunner = MainRunner;
//# sourceMappingURL=index.js.map