"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const callsite_1 = __importDefault(require("callsite")); const events_1 = require("events"); const TRACKING_MARK_RE = /^\$\$testcafe_test_run\$\$(\S+)\$\$$/; const STACK_CAPACITY = 5000; class TestRunTracker extends events_1.EventEmitter { constructor() { super(); this.enabled = false; this.activeTestRuns = {}; } _createContextSwitchingFunctionHook(ctxSwitchingFn, patchedArgsCount) { const tracker = this; return function () { const testRunId = tracker.getContextTestRunId(); if (testRunId) { for (let i = 0; i < patchedArgsCount; i++) { if (typeof arguments[i] === 'function') arguments[i] = tracker.addTrackingMarkerToFunction(testRunId, arguments[i]); } } // @ts-ignore return ctxSwitchingFn.apply(this, arguments); }; } _getStackFrames() { // NOTE: increase stack capacity to seek deep stack entries const savedLimit = Error.stackTraceLimit; Error.stackTraceLimit = STACK_CAPACITY; const frames = (0, callsite_1.default)(); Error.stackTraceLimit = savedLimit; return frames; } getMarkedFnName(testRunId) { return `$$testcafe_test_run$$${testRunId}$$`; } ensureEnabled() { if (!this.enabled) { global.setTimeout = this._createContextSwitchingFunctionHook(global.setTimeout, 1); global.setInterval = this._createContextSwitchingFunctionHook(global.setInterval, 1); global.setImmediate = this._createContextSwitchingFunctionHook(global.setImmediate, 1); process.nextTick = this._createContextSwitchingFunctionHook(process.nextTick, 1); global.Promise.prototype.then = this._createContextSwitchingFunctionHook(global.Promise.prototype.then, 2); global.Promise.prototype.catch = this._createContextSwitchingFunctionHook(global.Promise.prototype.catch, 1); this.enabled = true; } } addTrackingMarkerToFunction(testRunId, fn, context) { const markerFactoryBody = ` return function ${this.getMarkedFnName(testRunId)} () { context = context || this; switch (arguments.length) { case 0: return fn.call(context); case 1: return fn.call(context, arguments[0]); case 2: return fn.call(context, arguments[0], arguments[1]); case 3: return fn.call(context, arguments[0], arguments[1], arguments[2]); case 4: return fn.call(context, arguments[0], arguments[1], arguments[2], arguments[3]); default: return fn.apply(context, arguments); } }; `; return new Function('fn', 'context', markerFactoryBody)(fn, context); } getContextTestRunId() { const frames = this._getStackFrames(); // OPTIMIZATION: we start traversing from the bottom of the stack, // because we'll more likely encounter a marker there. // Async/await and Promise machinery executes lots of intrinsics // on timers (where we have a marker). And, since a timer initiates a new // stack, the marker will be at the very bottom of it. for (let i = frames.length - 1; i >= 0; i--) { const fnName = frames[i].getFunctionName(); const match = fnName && fnName.match(TRACKING_MARK_RE); if (match) return match[1]; } return null; } resolveContextTestRun() { const testRunId = this.getContextTestRunId(); if (testRunId) return this.activeTestRuns[testRunId]; return null; } addActiveTestRun(testRun) { this.activeTestRuns[testRun.id] = testRun; testRun.onAny((eventName, eventData) => this.emit(eventName, { testRun, data: eventData })); } removeActiveTestRun(id) { delete this.activeTestRuns[id]; } } // Tracker exports.default = new TestRunTracker(); module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1ydW4tdHJhY2tlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvdGVzdC1ydW4tdHJhY2tlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHdEQUFzQztBQUN0QyxtQ0FBc0M7QUFJdEMsTUFBTSxnQkFBZ0IsR0FBRyxzQ0FBc0MsQ0FBQztBQUNoRSxNQUFNLGNBQWMsR0FBSyxJQUFJLENBQUM7QUFFOUIsTUFBTSxjQUFlLFNBQVEscUJBQVk7SUFJckM7UUFDSSxLQUFLLEVBQUUsQ0FBQztRQUVSLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxjQUFjLEdBQUcsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFTyxtQ0FBbUMsQ0FBRSxjQUF3QixFQUFFLGdCQUF3QjtRQUMzRixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFFckIsT0FBTztZQUNILE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBRWhELElBQUksU0FBUyxFQUFFO2dCQUNYLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxnQkFBZ0IsRUFBRSxDQUFDLEVBQUUsRUFBRTtvQkFDdkMsSUFBSSxPQUFPLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxVQUFVO3dCQUNsQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLDJCQUEyQixDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDbkY7YUFDSjtZQUVELGFBQWE7WUFDYixPQUFPLGNBQWMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ2pELENBQUMsQ0FBQztJQUNOLENBQUM7SUFFTyxlQUFlO1FBQ25CLDJEQUEyRDtRQUMzRCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsZUFBZSxDQUFDO1FBRXpDLEtBQUssQ0FB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QUFFLFNBQWtCLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDakgsQ0FBQztJQUVNLG1CQUFtQixDQUFFLEVBQVU7UUFDbEMsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ25DLENBQUM7Q0FDSjtBQUVELFVBQVU7QUFDVixrQkFBZSxJQUFJLGNBQWMsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGdldFN0YWNrRnJhbWVzIGZyb20gJ2NhbGxzaXRlJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gJ2V2ZW50cyc7XG5pbXBvcnQgVGVzdFJ1biBmcm9tICcuLi90ZXN0LXJ1bic7XG5pbXBvcnQgVGVzdFJ1blByb3h5IGZyb20gJy4uL3NlcnZpY2VzL2NvbXBpbGVyL3Rlc3QtcnVuLXByb3h5JztcblxuY29uc3QgVFJBQ0tJTkdfTUFSS19SRSA9IC9eXFwkXFwkdGVzdGNhZmVfdGVzdF9ydW5cXCRcXCQoXFxTKylcXCRcXCQkLztcbmNvbnN0IFNUQUNLX0NBUEFDSVRZICAgPSA1MDAwO1xuXG5jbGFzcyBUZXN0UnVuVHJhY2tlciBleHRlbmRzIEV2ZW50RW1pdHRlciB7XG4gICAgcHJpdmF0ZSBlbmFibGVkOiBib29sZWFuO1xuICAgIHB1YmxpYyBhY3RpdmVUZXN0UnVuczogeyBbaWQ6IHN0cmluZ106IFRlc3RSdW4gfCBUZXN0UnVuUHJveHkgfTtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgdGhpcy5lbmFibGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuYWN0aXZlVGVzdFJ1bnMgPSB7fTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9jcmVhdGVDb250ZXh0U3dpdGNoaW5nRnVuY3Rpb25Ib29rIChjdHhTd2l0Y2hpbmdGbjogRnVuY3Rpb24sIHBhdGNoZWRBcmdzQ291bnQ6IG51bWJlcik6IGFueSB7XG4gICAgICAgIGNvbnN0IHRyYWNrZXIgPSB0aGlzO1xuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCB0ZXN0UnVuSWQgPSB0cmFja2VyLmdldENvbnRleHRUZXN0UnVuSWQoKTtcblxuICAgICAgICAgICAgaWYgKHRlc3RSdW5JZCkge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGF0Y2hlZEFyZ3NDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYXJndW1lbnRzW2ldID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzW2ldID0gdHJhY2tlci5hZGRUcmFja2luZ01hcmtlclRvRnVuY3Rpb24odGVzdFJ1bklkLCBhcmd1bWVudHNbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgcmV0dXJuIGN0eFN3aXRjaGluZ0ZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZ2V0U3RhY2tGcmFtZXMgKCk6IGdldFN0YWNrRnJhbWVzLkNhbGxTaXRlW10ge1xuICAgICAgICAvLyBOT1RFOiBpbmNyZWFzZSBzdGFjayBjYXBhY2l0eSB0byBzZWVrIGRlZXAgc3RhY2sgZW50cmllc1xuICAgICAgICBjb25zdCBzYXZlZExpbWl0ID0gRXJyb3Iuc3RhY2tUcmFjZUxpbWl0O1xuXG4gICAgICAgIEVycm9yLnN0YWNrVHJhY2VMaW1pdCA9IFNUQUNLX0NBUEFDSVRZO1xuXG4gICAgICAgIGNvbnN0IGZyYW1lcyA9IGdldFN0YWNrRnJhbWVzKCk7XG5cbiAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ID0gc2F2ZWRMaW1pdDtcblxuICAgICAgICByZXR1cm4gZnJhbWVzO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRNYXJrZWRGbk5hbWUgKHRlc3RSdW5JZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIGAkJHRlc3RjYWZlX3Rlc3RfcnVuJCQke3Rlc3RSdW5JZH0kJGA7XG4gICAgfVxuXG4gICAgcHVibGljIGVuc3VyZUVuYWJsZWQgKCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuZW5hYmxlZCkge1xuICAgICAgICAgICAgZ2xvYmFsLnNldFRpbWVvdXQgICA9IHRoaXMuX2NyZWF0ZUNvbnRleHRTd2l0Y2hpbmdGdW5jdGlvbkhvb2soZ2xvYmFsLnNldFRpbWVvdXQsIDEpO1xuICAgICAgICAgICAgZ2xvYmFsLnNldEludGVydmFsICA9IHRoaXMuX2NyZWF0ZUNvbnRleHRTd2l0Y2hpbmdGdW5jdGlvbkhvb2soZ2xvYmFsLnNldEludGVydmFsLCAxKTtcbiAgICAgICAgICAgIGdsb2JhbC5zZXRJbW1lZGlhdGUgPSB0aGlzLl9jcmVhdGVDb250ZXh0U3dpdGNoaW5nRnVuY3Rpb25Ib29rKGdsb2JhbC5zZXRJbW1lZGlhdGUsIDEpO1xuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljayAgICA9IHRoaXMuX2NyZWF0ZUNvbnRleHRTd2l0Y2hpbmdGdW5jdGlvbkhvb2socHJvY2Vzcy5uZXh0VGljaywgMSk7XG5cbiAgICAgICAgICAgIGdsb2JhbC5Qcm9taXNlLnByb3RvdHlwZS50aGVuICA9IHRoaXMuX2NyZWF0ZUNvbnRleHRTd2l0Y2hpbmdGdW5jdGlvbkhvb2soZ2xvYmFsLlByb21pc2UucHJvdG90eXBlLnRoZW4sIDIpO1xuICAgICAgICAgICAgZ2xvYmFsLlByb21pc2UucHJvdG90eXBlLmNhdGNoID0gdGhpcy5fY3JlYXRlQ29udGV4dFN3aXRjaGluZ0Z1bmN0aW9uSG9vayhnbG9iYWwuUHJvbWlzZS5wcm90b3R5cGUuY2F0Y2gsIDEpO1xuXG4gICAgICAgICAgICB0aGlzLmVuYWJsZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGFkZFRyYWNraW5nTWFya2VyVG9GdW5jdGlvbiAodGVzdFJ1bklkOiBzdHJpbmcsIGZuOiBGdW5jdGlvbiwgY29udGV4dD86IGFueSk6IEZ1bmN0aW9uIHtcbiAgICAgICAgY29uc3QgbWFya2VyRmFjdG9yeUJvZHkgPSBgXG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gJHsgdGhpcy5nZXRNYXJrZWRGbk5hbWUodGVzdFJ1bklkKSB9ICgpIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0ID0gY29udGV4dCB8fCB0aGlzO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6IHJldHVybiBmbi5jYWxsKGNvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6IHJldHVybiBmbi5jYWxsKGNvbnRleHQsIGFyZ3VtZW50c1swXSk7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjogcmV0dXJuIGZuLmNhbGwoY29udGV4dCwgYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0pO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6IHJldHVybiBmbi5jYWxsKGNvbnRleHQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6IHJldHVybiBmbi5jYWxsKGNvbnRleHQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0sIGFyZ3VtZW50c1szXSk7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBmbi5hcHBseShjb250ZXh0LCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIGA7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBGdW5jdGlvbignZm4nLCAnY29udGV4dCcsIG1hcmtlckZhY3RvcnlCb2R5KShmbiwgY29udGV4dCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldENvbnRleHRUZXN0UnVuSWQgKCk6IHN0cmluZyB8IG51bGwge1xuICAgICAgICBjb25zdCBmcmFtZXMgPSB0aGlzLl9nZXRTdGFja0ZyYW1lcygpO1xuXG4gICAgICAgIC8vIE9QVElNSVpBVElPTjogd2Ugc3RhcnQgdHJhdmVyc2luZyBmcm9tIHRoZSBib3R0b20gb2YgdGhlIHN0YWNrLFxuICAgICAgICAvLyBiZWNhdXNlIHdlJ2xsIG1vcmUgbGlrZWx5IGVuY291bnRlciBhIG1hcmtlciB0aGVyZS5cbiAgICAgICAgLy8gQXN5bmMvYXdhaXQgYW5kIFByb21pc2UgbWFjaGluZXJ5IGV4ZWN1dGVzIGxvdHMgb2YgaW50cmluc2ljc1xuICAgICAgICAvLyBvbiB0aW1lcnMgKHdoZXJlIHdlIGhhdmUgYSBtYXJrZXIpLiBBbmQsIHNpbmNlIGEgdGltZXIgaW5pdGlhdGVzIGEgbmV3XG4gICAgICAgIC8vIHN0YWNrLCB0aGUgbWFya2VyIHdpbGwgYmUgYXQgdGhlIHZlcnkgYm90dG9tIG9mIGl0LlxuICAgICAgICBmb3IgKGxldCBpID0gZnJhbWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBjb25zdCBmbk5hbWUgPSBmcmFtZXNbaV0uZ2V0RnVuY3Rpb25OYW1lKCk7XG4gICAgICAgICAgICBjb25zdCBtYXRjaCAgPSBmbk5hbWUgJiYgZm5OYW1lLm1hdGNoKFRSQUNLSU5HX01BUktfUkUpO1xuXG4gICAgICAgICAgICBpZiAobWF0Y2gpXG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoWzFdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcHVibGljIHJlc29sdmVDb250ZXh0VGVzdFJ1biAoKTogVGVzdFJ1biB8IFRlc3RSdW5Qcm94eSB8IG51bGwge1xuICAgICAgICBjb25zdCB0ZXN0UnVuSWQgPSB0aGlzLmdldENvbnRleHRUZXN0UnVuSWQoKTtcblxuICAgICAgICBpZiAodGVzdFJ1bklkKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWN0aXZlVGVzdFJ1bnNbdGVzdFJ1bklkXTtcblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkQWN0aXZlVGVzdFJ1biAodGVzdFJ1bjogVGVzdFJ1biB8IFRlc3RSdW5Qcm94eSk6IHZvaWQge1xuICAgICAgICB0aGlzLmFjdGl2ZVRlc3RSdW5zW3Rlc3RSdW4uaWRdID0gdGVzdFJ1bjtcblxuICAgICAgICB0ZXN0UnVuLm9uQW55KChldmVudE5hbWU6IHN0cmluZywgZXZlbnREYXRhOiB1bmtub3duKSA9PiB0aGlzLmVtaXQoZXZlbnROYW1lLCB7IHRlc3RSdW4sIGRhdGE6IGV2ZW50RGF0YSB9KSk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlbW92ZUFjdGl2ZVRlc3RSdW4gKGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuYWN0aXZlVGVzdFJ1bnNbaWRdO1xuICAgIH1cbn1cblxuLy8gVHJhY2tlclxuZXhwb3J0IGRlZmF1bHQgbmV3IFRlc3RSdW5UcmFja2VyKCk7XG4iXX0=