UNPKG

@browserstack/testcafe

Version:

Automated browser testing for the modern web development stack.

145 lines 19.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const child_process_1 = require("child_process"); const debug_1 = __importDefault(require("debug")); const promisify_event_1 = __importDefault(require("promisify-event")); const promisified_functions_1 = require("../../promisified-functions"); const commands_1 = __importDefault(require("./commands")); const WORKER_PATH = require.resolve('./worker'); const WORKER_STDIO_CONFIG = ['ignore', 'pipe', 'pipe', 'ipc']; const DEBUG_LOGGER = debug_1.default('testcafe:utils:temp-directory:cleanup-process'); class CleanupProcess { constructor() { this.worker = null; this.initialized = false; this.initPromise = Promise.resolve(void 0); this.errorPromise = null; this.messageCounter = 0; this.pendingResponses = {}; } _sendMessage(id, msg) { return Promise.race([ promisified_functions_1.sendMessageToChildProcess(this.worker, Object.assign({ id }, msg)), this._waitProcessError() ]); } _onResponse(response) { const pendingResponse = this.pendingResponses[response.id]; if (response.error) { if (pendingResponse) pendingResponse.control.reject(response.error); else this.pendingResponses[response.id] = Promise.reject(response.error); } else if (pendingResponse) pendingResponse.control.resolve(); else this.pendingResponses[response.id] = Promise.resolve(); } async _waitResponse(id) { if (!this.pendingResponses[id]) { const promiseControl = {}; this.pendingResponses[id] = new Promise((resolve, reject) => { Object.assign(promiseControl, { resolve, reject }); }); this.pendingResponses[id].control = promiseControl; } try { await this.pendingResponses[id]; } finally { delete this.pendingResponses[id]; } } async _waitResponseForMessage(msg) { const currentId = this.messageCounter; this.messageCounter++; await this._sendMessage(currentId, msg); await this._waitResponse(currentId); } _waitProcessExit() { return promisify_event_1.default(this.worker, 'exit') .then(exitCode => Promise.reject(new Error(`Worker process terminated with code ${exitCode}`))); } _waitProcessError() { if (this.errorPromise) return this.errorPromise; this.errorPromise = promisify_event_1.default(this.worker, 'error'); this.errorPromise.then(() => { this.errorPromise = null; }); return this.errorPromise; } _setupWorkerEventHandlers() { this.worker.on('message', message => this._onResponse(message)); this.worker.stdout.on('data', data => DEBUG_LOGGER('Worker process stdout:\n', String(data))); this.worker.stderr.on('data', data => DEBUG_LOGGER('Worker process stderr:\n', String(data))); } _unrefWorkerProcess() { this.worker.unref(); this.worker.stdout.unref(); this.worker.stderr.unref(); const channel = this.worker.channel || this.worker._channel; channel.unref(); } _handleProcessError(error) { this.initialized = false; DEBUG_LOGGER(error); } init() { this.initPromise = this.initPromise .then(async (initialized) => { if (initialized !== void 0) return initialized; this.worker = child_process_1.spawn(process.argv0, [WORKER_PATH], { detached: true, stdio: WORKER_STDIO_CONFIG }); this._setupWorkerEventHandlers(); this._unrefWorkerProcess(); const exitPromise = this._waitProcessExit(); try { await Promise.race([ this._waitResponseForMessage({ command: commands_1.default.init }), this._waitProcessError(), exitPromise ]); this.initialized = true; exitPromise.catch(error => this._handleProcessError(error)); this.worker.on('error', error => this._handleProcessError(error)); } catch (e) { DEBUG_LOGGER('Failed to start cleanup process'); DEBUG_LOGGER(e); this.initialized = false; } return this.initialized; }); return this.initPromise; } async addDirectory(path) { if (!this.initialized) return; try { await this._waitResponseForMessage({ command: commands_1.default.add, path }); } catch (e) { DEBUG_LOGGER(`Failed to add the ${path} directory to cleanup process`); DEBUG_LOGGER(e); } } async removeDirectory(path) { if (!this.initialized) return; try { await this._waitResponseForMessage({ command: commands_1.default.remove, path }); } catch (e) { DEBUG_LOGGER(`Failed to remove the ${path} directory in cleanup process`); DEBUG_LOGGER(e); } } } exports.default = new CleanupProcess(); module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdXRpbHMvdGVtcC1kaXJlY3RvcnkvY2xlYW51cC1wcm9jZXNzL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsaURBQXNDO0FBQ3RDLGtEQUEwQjtBQUMxQixzRUFBNkM7QUFDN0MsdUVBQXdFO0FBQ3hFLDBEQUFrQztBQUdsQyxNQUFNLFdBQVcsR0FBVyxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3hELE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztBQUU5RCxNQUFNLFlBQVksR0FBRyxlQUFLLENBQUMsK0NBQStDLENBQUMsQ0FBQztBQUU1RSxNQUFNLGNBQWM7SUFDaEI7UUFDSSxJQUFJLENBQUMsTUFBTSxHQUFTLElBQUksQ0FBQztRQUN6QixJQUFJLENBQUMsV0FBVyxHQUFJLEtBQUssQ0FBQztRQUMxQixJQUFJLENBQUMsV0FBVyxHQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUV6QixJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQztRQUV4QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFRCxZQUFZLENBQUUsRUFBRSxFQUFFLEdBQUc7UUFDakIsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQ2hCLGlEQUF5QixDQUFDLElBQUksQ0FBQyxNQUFNLGtCQUFJLEVBQUUsSUFBSyxHQUFHLEVBQUc7WUFDdEQsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1NBQzNCLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxXQUFXLENBQUUsUUFBUTtRQUNqQixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsZ0JB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QUFDO1lBQ3ZFLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNuQjtJQUNMLENBQUM7SUFFRCxLQUFLLENBQUMsZUFBZSxDQUFFLElBQUk7UUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXO1lBQ2pCLE9BQU87UUFFWCxJQUFJO1lBQ0EsTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQUMsRUFBRSxPQUFPLEVBQUUsa0JBQVEsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztTQUMxRTtRQUNELE9BQU8sQ0FBQyxFQUFFO1lBQ04sWUFBWSxDQUFDLHdCQUF3QixJQUFJLCtCQUErQixDQUFDLENBQUM7WUFDMUUsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ25CO0lBQ0wsQ0FBQztDQUNKO0FBRUQsa0JBQWUsSUFBSSxjQUFjLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHNwYXduIH0gZnJvbSAnY2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgZGVidWcgZnJvbSAnZGVidWcnO1xuaW1wb3J0IHByb21pc2lmeUV2ZW50IGZyb20gJ3Byb21pc2lmeS1ldmVudCc7XG5pbXBvcnQgeyBzZW5kTWVzc2FnZVRvQ2hpbGRQcm9jZXNzIH0gZnJvbSAnLi4vLi4vcHJvbWlzaWZpZWQtZnVuY3Rpb25zJztcbmltcG9ydCBDT01NQU5EUyBmcm9tICcuL2NvbW1hbmRzJztcblxuXG5jb25zdCBXT1JLRVJfUEFUSCAgICAgICAgID0gcmVxdWlyZS5yZXNvbHZlKCcuL3dvcmtlcicpO1xuY29uc3QgV09SS0VSX1NURElPX0NPTkZJRyA9IFsnaWdub3JlJywgJ3BpcGUnLCAncGlwZScsICdpcGMnXTtcblxuY29uc3QgREVCVUdfTE9HR0VSID0gZGVidWcoJ3Rlc3RjYWZlOnV0aWxzOnRlbXAtZGlyZWN0b3J5OmNsZWFudXAtcHJvY2VzcycpO1xuXG5jbGFzcyBDbGVhbnVwUHJvY2VzcyB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICB0aGlzLndvcmtlciAgICAgICA9IG51bGw7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZWQgID0gZmFsc2U7XG4gICAgICAgIHRoaXMuaW5pdFByb21pc2UgID0gUHJvbWlzZS5yZXNvbHZlKHZvaWQgMCk7XG4gICAgICAgIHRoaXMuZXJyb3JQcm9taXNlID0gbnVsbDtcblxuICAgICAgICB0aGlzLm1lc3NhZ2VDb3VudGVyID0gMDtcblxuICAgICAgICB0aGlzLnBlbmRpbmdSZXNwb25zZXMgPSB7fTtcbiAgICB9XG5cbiAgICBfc2VuZE1lc3NhZ2UgKGlkLCBtc2cpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmFjZShbXG4gICAgICAgICAgICBzZW5kTWVzc2FnZVRvQ2hpbGRQcm9jZXNzKHRoaXMud29ya2VyLCB7IGlkLCAuLi5tc2cgfSksXG4gICAgICAgICAgICB0aGlzLl93YWl0UHJvY2Vzc0Vycm9yKClcbiAgICAgICAgXSk7XG4gICAgfVxuXG4gICAgX29uUmVzcG9uc2UgKHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnN0IHBlbmRpbmdSZXNwb25zZSA9IHRoaXMucGVuZGluZ1Jlc3BvbnNlc1tyZXNwb25zZS5pZF07XG5cbiAgICAgICAgaWYgKHJlc3BvbnNlLmVycm9yKSB7XG4gICAgICAgICAgICBpZiAocGVuZGluZ1Jlc3BvbnNlKVxuICAgICAgICAgICAgICAgIHBlbmRpbmdSZXNwb25zZS5jb250cm9sLnJlamVjdChyZXNwb25zZS5lcnJvcik7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdGhpcy5wZW5kaW5nUmVzcG9uc2VzW3Jlc3BvbnNlLmlkXSA9IFByb21pc2UucmVqZWN0KHJlc3BvbnNlLmVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChwZW5kaW5nUmVzcG9uc2UpXG4gICAgICAgICAgICBwZW5kaW5nUmVzcG9uc2UuY29udHJvbC5yZXNvbHZlKCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRoaXMucGVuZGluZ1Jlc3BvbnNlc1tyZXNwb25zZS5pZF0gPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICBhc3luYyBfd2FpdFJlc3BvbnNlIChpZCkge1xuICAgICAgICBpZiAoIXRoaXMucGVuZGluZ1Jlc3BvbnNlc1tpZF0pIHtcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VDb250cm9sID0ge307XG5cbiAgICAgICAgICAgIHRoaXMucGVuZGluZ1Jlc3BvbnNlc1tpZF0gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihwcm9taXNlQ29udHJvbCwgeyByZXNvbHZlLCByZWplY3QgfSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGhpcy5wZW5kaW5nUmVzcG9uc2VzW2lkXS5jb250cm9sID0gcHJvbWlzZUNvbnRyb2w7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5wZW5kaW5nUmVzcG9uc2VzW2lkXTtcbiAgICAgICAgfVxuICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnBlbmRpbmdSZXNwb25zZXNbaWRdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgX3dhaXRSZXNwb25zZUZvck1lc3NhZ2UgKG1zZykge1xuICAgICAgICBjb25zdCBjdXJyZW50SWQgPSB0aGlzLm1lc3NhZ2VDb3VudGVyO1xuXG4gICAgICAgIHRoaXMubWVzc2FnZUNvdW50ZXIrKztcblxuICAgICAgICBhd2FpdCB0aGlzLl9zZW5kTWVzc2FnZShjdXJyZW50SWQsIG1zZyk7XG4gICAgICAgIGF3YWl0IHRoaXMuX3dhaXRSZXNwb25zZShjdXJyZW50SWQpO1xuICAgIH1cblxuICAgIF93YWl0UHJvY2Vzc0V4aXQgKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzaWZ5RXZlbnQodGhpcy53b3JrZXIsICdleGl0JylcbiAgICAgICAgICAgIC50aGVuKGV4aXRDb2RlID0+IFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihgV29ya2VyIHByb2Nlc3MgdGVybWluYXRlZCB3aXRoIGNvZGUgJHtleGl0Q29kZX1gKSkpO1xuICAgIH1cblxuICAgIF93YWl0UHJvY2Vzc0Vycm9yICgpIHtcbiAgICAgICAgaWYgKHRoaXMuZXJyb3JQcm9taXNlKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXJyb3JQcm9taXNlO1xuXG4gICAgICAgIHRoaXMuZXJyb3JQcm9taXNlID0gcHJvbWlzaWZ5RXZlbnQodGhpcy53b3JrZXIsICdlcnJvcicpO1xuXG4gICAgICAgIHRoaXMuZXJyb3JQcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lcnJvclByb21pc2UgPSBudWxsO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdGhpcy5lcnJvclByb21pc2U7XG4gICAgfVxuXG4gICAgX3NldHVwV29ya2VyRXZlbnRIYW5kbGVycyAoKSB7XG4gICAgICAgIHRoaXMud29ya2VyLm9uKCdtZXNzYWdlJywgbWVzc2FnZSA9PiB0aGlzLl9vblJlc3BvbnNlKG1lc3NhZ2UpKTtcblxuICAgICAgICB0aGlzLndvcmtlci5zdGRvdXQub24oJ2RhdGEnLCBkYXRhID0+IERFQlVHX0xPR0dFUignV29ya2VyIHByb2Nlc3Mgc3Rkb3V0OlxcbicsIFN0cmluZyhkYXRhKSkpO1xuICAgICAgICB0aGlzLndvcmtlci5zdGRlcnIub24oJ2RhdGEnLCBkYXRhID0+IERFQlVHX0xPR0dFUignV29ya2VyIHByb2Nlc3Mgc3RkZXJyOlxcbicsIFN0cmluZyhkYXRhKSkpO1xuICAgIH1cblxuICAgIF91bnJlZldvcmtlclByb2Nlc3MgKCkge1xuICAgICAgICB0aGlzLndvcmtlci51bnJlZigpO1xuICAgICAgICB0aGlzLndvcmtlci5zdGRvdXQudW5yZWYoKTtcbiAgICAgICAgdGhpcy53b3JrZXIuc3RkZXJyLnVucmVmKCk7XG5cbiAgICAgICAgY29uc3QgY2hhbm5lbCA9IHRoaXMud29ya2VyLmNoYW5uZWwgfHwgdGhpcy53b3JrZXIuX2NoYW5uZWw7XG5cbiAgICAgICAgY2hhbm5lbC51bnJlZigpO1xuICAgIH1cblxuICAgIF9oYW5kbGVQcm9jZXNzRXJyb3IgKGVycm9yKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSBmYWxzZTtcblxuICAgICAgICBERUJVR19MT0dHRVIoZXJyb3IpO1xuICAgIH1cblxuICAgIGluaXQgKCkge1xuICAgICAgICB0aGlzLmluaXRQcm9taXNlID0gdGhpcy5pbml0UHJvbWlzZVxuICAgICAgICAgICAgLnRoZW4oYXN5bmMgaW5pdGlhbGl6ZWQgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpbml0aWFsaXplZCAhPT0gdm9pZCAwKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5pdGlhbGl6ZWQ7XG5cbiAgICAgICAgICAgICAgICB0aGlzLndvcmtlciA9IHNwYXduKHByb2Nlc3MuYXJndjAsIFtXT1JLRVJfUEFUSF0sIHsgZGV0YWNoZWQ6IHRydWUsIHN0ZGlvOiBXT1JLRVJfU1RESU9fQ09ORklHIH0pO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0dXBXb3JrZXJFdmVudEhhbmRsZXJzKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fdW5yZWZXb3JrZXJQcm9jZXNzKCk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBleGl0UHJvbWlzZSA9IHRoaXMuX3dhaXRQcm9jZXNzRXhpdCgpO1xuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5yYWNlKFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3dhaXRSZXNwb25zZUZvck1lc3NhZ2UoeyBjb21tYW5kOiBDT01NQU5EUy5pbml0IH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fd2FpdFByb2Nlc3NFcnJvcigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhpdFByb21pc2VcbiAgICAgICAgICAgICAgICAgICAgXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplZCA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICAgICAgZXhpdFByb21pc2UuY2F0Y2goZXJyb3IgPT4gdGhpcy5faGFuZGxlUHJvY2Vzc0Vycm9yKGVycm9yKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy53b3JrZXIub24oJ2Vycm9yJywgZXJyb3IgPT4gdGhpcy5faGFuZGxlUHJvY2Vzc0Vycm9yKGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIERFQlVHX0xPR0dFUignRmFpbGVkIHRvIHN0YXJ0IGNsZWFudXAgcHJvY2VzcycpO1xuICAgICAgICAgICAgICAgICAgICBERUJVR19MT0dHRVIoZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmluaXRpYWxpemVkO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaW5pdFByb21pc2U7XG4gICAgfVxuXG4gICAgYXN5bmMgYWRkRGlyZWN0b3J5IChwYXRoKSB7XG4gICAgICAgIGlmICghdGhpcy5pbml0aWFsaXplZClcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5fd2FpdFJlc3BvbnNlRm9yTWVzc2FnZSh7IGNvbW1hbmQ6IENPTU1BTkRTLmFkZCwgcGF0aCB9KTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgREVCVUdfTE9HR0VSKGBGYWlsZWQgdG8gYWRkIHRoZSAke3BhdGh9IGRpcmVjdG9yeSB0byBjbGVhbnVwIHByb2Nlc3NgKTtcbiAgICAgICAgICAgIERFQlVHX0xPR0dFUihlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIHJlbW92ZURpcmVjdG9yeSAocGF0aCkge1xuICAgICAgICBpZiAoIXRoaXMuaW5pdGlhbGl6ZWQpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX3dhaXRSZXNwb25zZUZvck1lc3NhZ2UoeyBjb21tYW5kOiBDT01NQU5EUy5yZW1vdmUsIHBhdGggfSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIERFQlVHX0xPR0dFUihgRmFpbGVkIHRvIHJlbW92ZSB0aGUgJHtwYXRofSBkaXJlY3RvcnkgaW4gY2xlYW51cCBwcm9jZXNzYCk7XG4gICAgICAgICAgICBERUJVR19MT0dHRVIoZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG5ldyBDbGVhbnVwUHJvY2VzcygpO1xuIl19