171 lines
7.1 KiB
JavaScript
171 lines
7.1 KiB
JavaScript
|
"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);
|