UNPKG

creevey

Version:

creevey is a tool for automated visual testing, that tightly integrated with storybook

171 lines (135 loc) 15.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _cluster = _interopRequireDefault(require("cluster")); var _events = require("events"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } class Pool extends _events.EventEmitter { get isRunning() { return this.workers.length !== this.freeWorkers.length; } constructor(config, browser) { super(); _defineProperty(this, "maxRetries", void 0); _defineProperty(this, "browser", void 0); _defineProperty(this, "config", void 0); _defineProperty(this, "workers", []); _defineProperty(this, "queue", []); _defineProperty(this, "forcedStop", false); this.maxRetries = config.maxRetries; this.browser = browser; this.config = config.browsers[browser]; } async init() { this.workers = Array.from({ length: this.config.limit || 1 }).map(() => { _cluster.default.setupMaster({ args: ['--browser', this.browser, ...process.argv.slice(2)] }); const worker = _cluster.default.fork(); this.exitHandler(worker); return worker; }); // TODO handle errors const [data] = await Promise.all(this.workers.map(worker => new Promise(resolve => worker.once('message', resolve)))); const message = JSON.parse(data); if (message.type == 'ready') return; if (message.type == 'error') throw message.payload.error; } start(tests) { if (this.isRunning) return false; this.queue = tests.map(({ id, path }) => ({ id, path, retries: 0 })); this.process(); return true; } stop() { // TODO Timeout if (!this.isRunning) { // TODO this.emit("stop"); return; } this.forcedStop = true; this.queue = []; } process() { const worker = this.getFreeWorker(); const [test] = this.queue; if (this.queue.length == 0 && this.workers.length === this.freeWorkers.length) { this.forcedStop = false; this.emit('stop'); return; } if (!worker || !test) return; const { id } = test; this.queue.shift(); this.sendStatus({ id, status: 'running' }); worker.isRunning = true; worker.once('message', data => { const message = JSON.parse(data); if (message.type == 'ready') return; if (message.type == 'error') worker.disconnect(); const { payload: result } = message; const { status } = result; const shouldRetry = status == 'failed' && test.retries < this.maxRetries && !this.forcedStop; if (shouldRetry) { test.retries += 1; this.queue.push(test); } worker.isRunning = false; this.sendStatus({ id, status, result }); this.process(); }); worker.send(JSON.stringify(test)); this.process(); } sendStatus(message) { this.emit('test', message); } getFreeWorker() { return this.freeWorkers[Math.floor(Math.random() * this.freeWorkers.length)]; } get aliveWorkers() { return this.workers.filter(worker => !worker.exitedAfterDisconnect); } get freeWorkers() { return this.aliveWorkers.filter(worker => !worker.isRunning); } exitHandler(worker) { worker.once('exit', () => { _cluster.default.setupMaster({ args: ['--browser', this.browser, ...process.argv.slice(2)] }); const newWorker = _cluster.default.fork(); this.exitHandler(newWorker); // TODO handle errors newWorker.once('message', () => { this.workers[this.workers.indexOf(worker)] = newWorker; this.process(); }); }); } } exports.default = Pool; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2ZXIvbWFzdGVyL3Bvb2wudHMiXSwibmFtZXMiOlsiUG9vbCIsIkV2ZW50RW1pdHRlciIsImlzUnVubmluZyIsIndvcmtlcnMiLCJsZW5ndGgiLCJmcmVlV29ya2VycyIsImNvbnN0cnVjdG9yIiwiY29uZmlnIiwiYnJvd3NlciIsIm1heFJldHJpZXMiLCJicm93c2VycyIsImluaXQiLCJBcnJheSIsImZyb20iLCJsaW1pdCIsIm1hcCIsImNsdXN0ZXIiLCJzZXR1cE1hc3RlciIsImFyZ3MiLCJwcm9jZXNzIiwiYXJndiIsInNsaWNlIiwid29ya2VyIiwiZm9yayIsImV4aXRIYW5kbGVyIiwiZGF0YSIsIlByb21pc2UiLCJhbGwiLCJyZXNvbHZlIiwib25jZSIsIm1lc3NhZ2UiLCJKU09OIiwicGFyc2UiLCJ0eXBlIiwicGF5bG9hZCIsImVycm9yIiwic3RhcnQiLCJ0ZXN0cyIsInF1ZXVlIiwiaWQiLCJwYXRoIiwicmV0cmllcyIsInN0b3AiLCJmb3JjZWRTdG9wIiwiZ2V0RnJlZVdvcmtlciIsInRlc3QiLCJlbWl0Iiwic2hpZnQiLCJzZW5kU3RhdHVzIiwic3RhdHVzIiwiZGlzY29ubmVjdCIsInJlc3VsdCIsInNob3VsZFJldHJ5IiwicHVzaCIsInNlbmQiLCJzdHJpbmdpZnkiLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJhbGl2ZVdvcmtlcnMiLCJmaWx0ZXIiLCJleGl0ZWRBZnRlckRpc2Nvbm5lY3QiLCJuZXdXb3JrZXIiLCJpbmRleE9mIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7Ozs7OztBQUdlLE1BQU1BLElBQU4sU0FBbUJDLG9CQUFuQixDQUFnQztBQU83QyxNQUFXQyxTQUFYLEdBQWdDO0FBQzlCLFdBQU8sS0FBS0MsT0FBTCxDQUFhQyxNQUFiLEtBQXdCLEtBQUtDLFdBQUwsQ0FBaUJELE1BQWhEO0FBQ0Q7O0FBQ0RFLEVBQUFBLFdBQVcsQ0FBQ0MsTUFBRCxFQUFpQkMsT0FBakIsRUFBa0M7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T0FBTDtBQUNELE9BSEQ7QUFJRCxLQVREO0FBVUQ7O0FBM0g0QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjbHVzdGVyIGZyb20gJ2NsdXN0ZXInO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnZXZlbnRzJztcbmltcG9ydCB7IFdvcmtlciwgQ29uZmlnLCBUZXN0UmVzdWx0LCBCcm93c2VyQ29uZmlnLCBXb3JrZXJNZXNzYWdlLCBUZXN0U3RhdHVzIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQb29sIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcbiAgcHJpdmF0ZSBtYXhSZXRyaWVzOiBudW1iZXI7XG4gIHByaXZhdGUgYnJvd3Nlcjogc3RyaW5nO1xuICBwcml2YXRlIGNvbmZpZzogQnJvd3NlckNvbmZpZztcbiAgcHJpdmF0ZSB3b3JrZXJzOiBXb3JrZXJbXSA9IFtdO1xuICBwcml2YXRlIHF1ZXVlOiB7IGlkOiBzdHJpbmc7IHBhdGg6IHN0cmluZ1tdOyByZXRyaWVzOiBudW1iZXIgfVtdID0gW107XG4gIHByaXZhdGUgZm9yY2VkU3RvcCA9IGZhbHNlO1xuICBwdWJsaWMgZ2V0IGlzUnVubmluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy53b3JrZXJzLmxlbmd0aCAhPT0gdGhpcy5mcmVlV29ya2Vycy5sZW5ndGg7XG4gIH1cbiAgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcsIGJyb3dzZXI6IHN0cmluZykge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLm1heFJldHJpZXMgPSBjb25maWcubWF4UmV0cmllcztcbiAgICB0aGlzLmJyb3dzZXIgPSBicm93c2VyO1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnLmJyb3dzZXJzW2Jyb3dzZXJdIGFzIEJyb3dzZXJDb25maWc7XG4gIH1cblxuICBhc3luYyBpbml0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMud29ya2VycyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IHRoaXMuY29uZmlnLmxpbWl0IHx8IDEgfSkubWFwKCgpID0+IHtcbiAgICAgIGNsdXN0ZXIuc2V0dXBNYXN0ZXIoeyBhcmdzOiBbJy0tYnJvd3NlcicsIHRoaXMuYnJvd3NlciwgLi4ucHJvY2Vzcy5hcmd2LnNsaWNlKDIpXSB9KTtcbiAgICAgIGNvbnN0IHdvcmtlciA9IGNsdXN0ZXIuZm9yaygpO1xuICAgICAgdGhpcy5leGl0SGFuZGxlcih3b3JrZXIpO1xuICAgICAgcmV0dXJuIHdvcmtlcjtcbiAgICB9KTtcbiAgICAvLyBUT0RPIGhhbmRsZSBlcnJvcnNcbiAgICBjb25zdCBbZGF0YV0gPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHRoaXMud29ya2Vycy5tYXAoKHdvcmtlcikgPT4gbmV3IFByb21pc2UoKHJlc29sdmU6ICh2YWx1ZTogc3RyaW5nKSA9PiB2b2lkKSA9PiB3b3JrZXIub25jZSgnbWVzc2FnZScsIHJlc29sdmUpKSksXG4gICAgKTtcbiAgICBjb25zdCBtZXNzYWdlOiBXb3JrZXJNZXNzYWdlID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICBpZiAobWVzc2FnZS50eXBlID09ICdyZWFkeScpIHJldHVybjtcbiAgICBpZiAobWVzc2FnZS50eXBlID09ICdlcnJvcicpIHRocm93IG1lc3NhZ2UucGF5bG9hZC5lcnJvcjtcbiAgfVxuXG4gIHN0YXJ0KHRlc3RzOiB7IGlkOiBzdHJpbmc7IHBhdGg6IHN0cmluZ1tdIH1bXSk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmlzUnVubmluZykgcmV0dXJuIGZhbHNlO1xuXG4gICAgdGhpcy5xdWV1ZSA9IHRlc3RzLm1hcCgoeyBpZCwgcGF0aCB9KSA9PiAoeyBpZCwgcGF0aCwgcmV0cmllczogMCB9KSk7XG4gICAgdGhpcy5wcm9jZXNzKCk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHN0b3AoKTogdm9pZCB7XG4gICAgLy8gVE9ETyBUaW1lb3V0XG4gICAgaWYgKCF0aGlzLmlzUnVubmluZykge1xuICAgICAgLy8gVE9ETyB0aGlzLmVtaXQoXCJzdG9wXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuZm9yY2VkU3RvcCA9IHRydWU7XG4gICAgdGhpcy5xdWV1ZSA9IFtdO1xuICB9XG5cbiAgcHJvY2VzcygpOiB2b2lkIHtcbiAgICBjb25zdCB3b3JrZXIgPSB0aGlzLmdldEZyZWVXb3JrZXIoKTtcbiAgICBjb25zdCBbdGVzdF0gPSB0aGlzLnF1ZXVlO1xuXG4gICAgaWYgKHRoaXMucXVldWUubGVuZ3RoID09IDAgJiYgdGhpcy53b3JrZXJzLmxlbmd0aCA9PT0gdGhpcy5mcmVlV29ya2Vycy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuZm9yY2VkU3RvcCA9IGZhbHNlO1xuICAgICAgdGhpcy5lbWl0KCdzdG9wJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCF3b3JrZXIgfHwgIXRlc3QpIHJldHVybjtcblxuICAgIGNvbnN0IHsgaWQgfSA9IHRlc3Q7XG5cbiAgICB0aGlzLnF1ZXVlLnNoaWZ0KCk7XG5cbiAgICB0aGlzLnNlbmRTdGF0dXMoeyBpZCwgc3RhdHVzOiAncnVubmluZycgfSk7XG5cbiAgICB3b3JrZXIuaXNSdW5uaW5nID0gdHJ1ZTtcbiAgICB3b3JrZXIub25jZSgnbWVzc2FnZScsIChkYXRhKSA9PiB7XG4gICAgICBjb25zdCBtZXNzYWdlOiBXb3JrZXJNZXNzYWdlID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgIGlmIChtZXNzYWdlLnR5cGUgPT0gJ3JlYWR5JykgcmV0dXJuO1xuICAgICAgaWYgKG1lc3NhZ2UudHlwZSA9PSAnZXJyb3InKSB3b3JrZXIuZGlzY29ubmVjdCgpO1xuXG4gICAgICBjb25zdCB7IHBheWxvYWQ6IHJlc3VsdCB9ID0gbWVzc2FnZTtcbiAgICAgIGNvbnN0IHsgc3RhdHVzIH0gPSByZXN1bHQ7XG4gICAgICBjb25zdCBzaG91bGRSZXRyeSA9IHN0YXR1cyA9PSAnZmFpbGVkJyAmJiB0ZXN0LnJldHJpZXMgPCB0aGlzLm1heFJldHJpZXMgJiYgIXRoaXMuZm9yY2VkU3RvcDtcblxuICAgICAgaWYgKHNob3VsZFJldHJ5KSB7XG4gICAgICAgIHRlc3QucmV0cmllcyArPSAxO1xuICAgICAgICB0aGlzLnF1ZXVlLnB1c2godGVzdCk7XG4gICAgICB9XG5cbiAgICAgIHdvcmtlci5pc1J1bm5pbmcgPSBmYWxzZTtcblxuICAgICAgdGhpcy5zZW5kU3RhdHVzKHsgaWQsIHN0YXR1cywgcmVzdWx0IH0pO1xuICAgICAgdGhpcy5wcm9jZXNzKCk7XG4gICAgfSk7XG4gICAgd29ya2VyLnNlbmQoSlNPTi5zdHJpbmdpZnkodGVzdCkpO1xuICAgIHRoaXMucHJvY2VzcygpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZW5kU3RhdHVzKG1lc3NhZ2U6IHsgaWQ6IHN0cmluZzsgc3RhdHVzOiBUZXN0U3RhdHVzOyByZXN1bHQ/OiBUZXN0UmVzdWx0IH0pOiB2b2lkIHtcbiAgICB0aGlzLmVtaXQoJ3Rlc3QnLCBtZXNzYWdlKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RnJlZVdvcmtlcigpOiBXb3JrZXIgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmZyZWVXb3JrZXJzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHRoaXMuZnJlZVdvcmtlcnMubGVuZ3RoKV07XG4gIH1cblxuICBwcml2YXRlIGdldCBhbGl2ZVdvcmtlcnMoKTogV29ya2VyW10ge1xuICAgIHJldHVybiB0aGlzLndvcmtlcnMuZmlsdGVyKCh3b3JrZXIpID0+ICF3b3JrZXIuZXhpdGVkQWZ0ZXJEaXNjb25uZWN0KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IGZyZWVXb3JrZXJzKCk6IFdvcmtlcltdIHtcbiAgICByZXR1cm4gdGhpcy5hbGl2ZVdvcmtlcnMuZmlsdGVyKCh3b3JrZXIpID0+ICF3b3JrZXIuaXNSdW5uaW5nKTtcbiAgfVxuXG4gIHByaXZhdGUgZXhpdEhhbmRsZXIod29ya2VyOiBXb3JrZXIpOiB2b2lkIHtcbiAgICB3b3JrZXIub25jZSgnZXhpdCcsICgpID0+IHtcbiAgICAgIGNsdXN0ZXIuc2V0dXBNYXN0ZXIoeyBhcmdzOiBbJy0tYnJvd3NlcicsIHRoaXMuYnJvd3NlciwgLi4ucHJvY2Vzcy5hcmd2LnNsaWNlKDIpXSB9KTtcbiAgICAgIGNvbnN0IG5ld1dvcmtlciA9IGNsdXN0ZXIuZm9yaygpO1xuICAgICAgdGhpcy5leGl0SGFuZGxlcihuZXdXb3JrZXIpO1xuICAgICAgLy8gVE9ETyBoYW5kbGUgZXJyb3JzXG4gICAgICBuZXdXb3JrZXIub25jZSgnbWVzc2FnZScsICgpID0+IHtcbiAgICAgICAgdGhpcy53b3JrZXJzW3RoaXMud29ya2Vycy5pbmRleE9mKHdvcmtlcildID0gbmV3V29ya2VyO1xuICAgICAgICB0aGlzLnByb2Nlc3MoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59XG4iXX0=