UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

115 lines 18.7 kB
"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