"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = __importDefault(require("path")); const read_file_relative_1 = require("read-file-relative"); const mustache_1 = __importDefault(require("mustache")); const testcafe_hammerhead_1 = require("testcafe-hammerhead"); const command_1 = __importDefault(require("./command")); const type_1 = __importDefault(require("../test-run-error/type")); const formattable_adapter_1 = __importDefault(require("../test-run-error/formattable-adapter")); // Const const TEST_RUN_TEMPLATE = (0, read_file_relative_1.readSync)('../client/test-run/index.js.mustache'); const IFRAME_TEST_RUN_TEMPLATE = (0, read_file_relative_1.readSync)('../client/test-run/iframe.js.mustache'); const ASYNC_SERVICE_MESSAGE_HANDLERS = [command_1.default.takeScreenshot, command_1.default.fatalError, command_1.default.assertionFailed, command_1.default.done]; class LegacyTestRun extends testcafe_hammerhead_1.Session { constructor({ test, browserConnection, screenshotCapturer, opts }) { var uploadsRoot = path_1.default.dirname(test.fixture.path); super(uploadsRoot); this.methodLock = Promise.resolve(); this.unstable = false; this.opts = opts; this.test = test; this.browserConnection = browserConnection; this.isFileDownloading = false; this.errs = []; this.nativeDialogsInfo = null; this.nativeDialogsInfoTimeStamp = 0; this.stepsSharedData = {}; this.screenshotCapturer = screenshotCapturer; this.injectable.scripts.push('/testcafe-core.js'); this.injectable.scripts.push('/testcafe-ui.js'); this.injectable.scripts.push('/testcafe-automation.js'); this.injectable.scripts.push('/testcafe-legacy-runner.js'); this.injectable.styles.push('/testcafe-ui-styles.css'); } static makeBlocking(target, methodName) { const method = target[methodName]; target[methodName] = function (...args) { this.methodLock = this.methodLock .then(() => method.apply(this, args)); return this.methodLock; }; } async getPayloadScript() { var sharedJs = this.test.fixture.getSharedJs(); return mustache_1.default.render(TEST_RUN_TEMPLATE, { stepNames: JSON.stringify(this.test.stepData.names), testSteps: this.test.stepData.js, sharedJs: sharedJs, testRunId: this.id, browserId: this.browserConnection.id, browserHeartbeatUrl: this.browserConnection.heartbeatUrl, browserStatusUrl: this.browserConnection.statusDoneUrl, takeScreenshots: this.screenshotCapturer.enabled, takeScreenshotsOnFails: this.opts.takeScreenshotsOnFails, skipJsErrors: this.opts.skipJsErrors, nativeDialogsInfo: JSON.stringify(this.nativeDialogsInfo), selectorTimeout: this.opts.selectorTimeout, canUseDefaultWindowActions: JSON.stringify(await this.browserConnection.canUseDefaultWindowActions()) }); } async getIframePayloadScript(iframeWithoutSrc) { var sharedJs = this.test.fixture.getSharedJs(); var payloadScript = mustache_1.default.render(IFRAME_TEST_RUN_TEMPLATE, { sharedJs: sharedJs, takeScreenshotsOnFails: this.opts.takeScreenshotsOnFails, skipJsErrors: this.opts.skipJsErrors, nativeDialogsInfo: JSON.stringify(this.nativeDialogsInfo), selectorTimeout: this.opts.selectorTimeout }); return iframeWithoutSrc ? 'var isIFrameWithoutSrc = true;' + payloadScript : payloadScript; } async _takeScreenshot(msg) { try { return await this.screenshotCapturer.captureAction(msg); } catch (e) { // NOTE: swallow the error silently if we can't take screenshots for some // reason (e.g. we don't have permissions to write a screenshot file). return null; } } async _addError(err) { var screenshotPath = null; var callsite = err.__sourceIndex !== void 0 && err.__sourceIndex !== null && this.test.sourceIndex[err.__sourceIndex]; try { screenshotPath = await this.screenshotCapturer.captureError(err); } catch (e) { // NOTE: swallow the error silently if we can't take screenshots for some // reason (e.g. we don't have permissions to write a screenshot file). } var errAdapter = new formattable_adapter_1.default(err, { userAgent: this.browserConnection.userAgent, screenshotPath: screenshotPath, callsite: callsite }); this.errs.push(errAdapter); } async _fatalError(err) { await this._addError(err); this.emit('done'); } getAuthCredentials() { return this.test.fixture.authCredentials; } handleFileDownload() { this.isFileDownloading = true; } handleAttachment() { } handlePageError(ctx, errMsg) { this._fatalError({ type: type_1.default.pageNotLoaded, message: errMsg }); ctx.redirect(this.browserConnection.forcedIdleUrl); } async start() { // NOTE: required to keep API similar to TestRun. Just do nothing here. this.emit('start'); } async initialize() { // NOTE: required to keep API compatible to the regular TestRun } // Service message handlers // Asynchronous [command_1.default.takeScreenshot](msg) { return this._takeScreenshot(msg); } [command_1.default.fatalError](msg) { return this._fatalError(msg.err); } [command_1.default.assertionFailed](msg) { return this._addError(msg.err); } [command_1.default.done]() { this.emit('done'); } // Synchronous [command_1.default.setStepsSharedData](msg) { this.stepsSharedData = msg.stepsSharedData; } [command_1.default.getStepsSharedData]() { return this.stepsSharedData; } [command_1.default.getAndUncheckFileDownloadingFlag]() { var isFileDownloading = this.isFileDownloading; this.isFileDownloading = false; return isFileDownloading; } [command_1.default.waitForFileDownload]() { // NOTE: required to keep API similar to TestRun. Just do nothing here. } [command_1.default.nativeDialogsInfoSet](msg) { if (msg.timeStamp >= this.nativeDialogsInfoTimeStamp) { //NOTE: the server can get messages in the wrong sequence if they was sent with a little distance (several milliseconds), // we don't take to account old messages this.nativeDialogsInfoTimeStamp = msg.timeStamp; this.nativeDialogsInfo = msg.info; } } } exports.default = LegacyTestRun; for (const handler of ASYNC_SERVICE_MESSAGE_HANDLERS) LegacyTestRun.makeBlocking(LegacyTestRun.prototype, handler);