Innovenergy_trunk/frontend/node_modules/testcafe/lib/services/compiler/service.js

361 lines
60 KiB
JavaScript
Raw Normal View History

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const compiler_1 = __importDefault(require("../../compiler"));
const test_run_proxy_1 = __importDefault(require("./test-run-proxy"));
const test_controller_1 = __importDefault(require("../../api/test-controller"));
const test_structure_1 = require("../serialization/test-structure");
const io_1 = require("./io");
const proxy_1 = require("../utils/ipc/proxy");
const transport_1 = require("../utils/ipc/transport");
const protocol_1 = require("./protocol");
const process_title_1 = __importDefault(require("../process-title"));
const hook_method_names_1 = __importDefault(require("../../api/request-hooks/hook-method-names"));
const testcafe_hammerhead_1 = require("testcafe-hammerhead");
const user_variables_1 = __importDefault(require("../../api/user-variables"));
const execute_js_expression_1 = require("../../test-run/execute-js-expression");
const test_run_1 = require("../../errors/test-run");
const utils_1 = require("../../errors/test-run/render-error-template/utils");
const setup_sourcemap_support_1 = require("../../utils/setup-sourcemap-support");
const handle_errors_1 = require("../../utils/handle-errors");
const errors_1 = require("../../shared/errors");
const lodash_1 = require("lodash");
(0, setup_sourcemap_support_1.setupSourceMapSupport)();
// This is hack for supporting the 'import { t } from "testcafe"' expression in tests.
// It caused by using the 'esm' module.
require('../../api/test-controller/proxy');
class CompilerService {
constructor() {
process.title = process_title_1.default.service;
const input = fs_1.default.createReadStream('', { fd: io_1.SERVICE_INPUT_FD });
const output = fs_1.default.createWriteStream('', { fd: io_1.SERVICE_OUTPUT_FD });
this.proxy = new proxy_1.IPCProxy(new transport_1.ServiceTransport(input, output, io_1.SERVICE_SYNC_FD));
this.state = this._initState();
this._runnableConfigurationUnitsRelations = {};
this._registerErrorHandlers();
this._setupRoutes();
this.ready();
}
_initState() {
return {
testRuns: {},
fixtureCtxs: {},
units: {},
options: {},
roles: new Map(),
};
}
async _handleUnexpectedError(ErrorCtor, error) {
const message = (0, handle_errors_1.formatError)(ErrorCtor, error);
const type = ErrorCtor.name;
await this.addUnexpectedError({ type, message });
}
_registerErrorHandlers() {
process.on('unhandledRejection', async (e) => this._handleUnexpectedError(test_run_1.UnhandledPromiseRejectionError, e));
process.on('uncaughtException', async (e) => this._handleUnexpectedError(test_run_1.UncaughtExceptionError, e));
}
_getFixtureCtx(unit) {
const fixtureId = (0, test_structure_1.isTest)(unit) ? unit.fixture.id : unit.id;
return this.state.fixtureCtxs[fixtureId];
}
_getTestCtx({ testRunId }, unit) {
const testRunProxy = this._getTargetTestRun(testRunId);
testRunProxy.fixtureCtx = this._getFixtureCtx(unit);
return testRunProxy;
}
_getContext(args, unit) {
const { testRunId } = args;
if (testRunId)
return this._getTestCtx(args, unit);
return this._getFixtureCtx(unit);
}
_setupRoutes() {
this.proxy.register([
this.getTests,
this.runTestFn,
this.cleanUp,
this.setUserVariables,
this.setOptions,
this.onRequestHookEvent,
this.setMock,
this.setConfigureResponseEventOptions,
this.setHeaderOnConfigureResponseEvent,
this.removeHeaderOnConfigureResponseEvent,
this.executeRequestFilterRulePredicate,
this.executeMockPredicate,
this.getWarningMessages,
this.addRequestEventListeners,
this.removeRequestEventListeners,
this.initializeTestRunData,
this.getAssertionActualValue,
this.executeRoleInitFn,
this.getCtx,
this.getFixtureCtx,
this.setCtx,
this.setFixtureCtx,
this.updateRoleProperty,
this.executeJsExpression,
this.executeAsyncJsExpression,
this.addUnexpectedError,
this.checkWindow,
this.removeTestRunFromState,
this.removeFixtureCtxsFromState,
this.removeUnitsFromState,
], this);
}
_getFunction(unit, functionName) {
if ((0, test_structure_1.isTest)(unit) && (0, protocol_1.isTestFunctionProperty)(functionName))
return unit[functionName];
if ((0, test_structure_1.isFixture)(unit) && (0, protocol_1.isFixtureFunctionProperty)(functionName))
return unit[functionName];
throw new Error(`Cannot find '${functionName}' function for ${typeof unit}`);
}
_wrapEventMethods({ name, testId, hookId, eventData }) {
if (name === hook_method_names_1.default.onRequest)
this._wrapSetMockFn({ testId, hookId, event: eventData });
else if (name === hook_method_names_1.default._onConfigureResponse)
this._wrapConfigureResponseEventMethods(eventData);
}
_wrapSetMockFn({ testId, hookId, event }) {
event.setMock = async (mock) => {
await this.setMock({
responseEventId: event.id,
ruleId: event.requestFilterRule.id,
testId,
hookId,
mock,
});
};
}
_wrapConfigureResponseEventMethods(event) {
event.setHeader = async (name, value) => {
await this.setHeaderOnConfigureResponseEvent({
eventId: event.id,
headerName: name,
headerValue: value,
});
};
event.removeHeader = async (name) => {
await this.removeHeaderOnConfigureResponseEvent({
eventId: event.id,
headerName: name,
});
};
}
_initializeTestRunProxy({ testRunId, test, browser, activeWindowId, messageBus }) {
const testRunProxy = new test_run_proxy_1.default({
dispatcher: this,
id: testRunId,
options: this.state.options,
test,
browser,
activeWindowId,
messageBus,
});
this.state.testRuns[testRunId] = testRunProxy;
}
_initializeFixtureCtx(test) {
const fixtureId = test.fixture.id;
if (this.state.fixtureCtxs[fixtureId])
return;
this.state.fixtureCtxs[fixtureId] = Object.create(null);
}
_getTargetTestRun(testRunId) {
return this.state.testRuns[testRunId];
}
_getTargetRole(roleId) {
return this.state.roles.get(roleId);
}
async setUserVariables(value) {
user_variables_1.default.value = value;
}
_getUnitIds(tests) {
const testIds = tests.map(test => test.id);
const fixtureIds = tests.map(test => { var _a; return (_a = test.fixture) === null || _a === void 0 ? void 0 : _a.id; });
const testFileIds = tests.map(test => test.testFile.id);
return (0, lodash_1.uniq)([...testIds, ...fixtureIds, ...testFileIds]);
}
async setOptions({ value }) {
this.state.options = value;
}
async ready() {
this.proxy.call(this.ready);
}
async cleanUp() {
await compiler_1.default.cleanUp();
}
async getTests({ sourceList, compilerOptions, runnableConfigurationId }, baseUrl) {
const compiler = new compiler_1.default(sourceList, compilerOptions, { isCompilerServiceMode: true, baseUrl, experimentalEsm: false });
const tests = await compiler.getTests();
const units = (0, test_structure_1.flatten)(tests);
const unitIds = this._getUnitIds(tests);
this._runnableConfigurationUnitsRelations[runnableConfigurationId] = unitIds;
Object.assign(this.state.units, units);
return (0, test_structure_1.serialize)(units);
}
async runTestFn(args) {
const { id, functionName } = args;
const unit = this.state.units[id];
const context = this._getContext(args, unit);
const functionObject = this._getFunction(unit, functionName);
if (!functionObject)
throw new Error(`Cannot find the "${functionName}" of ${typeof unit}`);
return await functionObject(context);
}
executeCommandSync({ id, command, callsite }) {
return this.proxy.callSync(this.executeCommand, { id, command, callsite });
}
async executeCommand({ command, id, callsite }) {
return this.proxy.call(this.executeCommand, { id, command, callsite });
}
async onRequestHookEvent({ name, testId, hookId, eventData }) {
this._wrapEventMethods({ name, testId, hookId, eventData });
const test = this.state.units[testId];
const targetHook = test.requestHooks.find(hook => hook.id === hookId);
// @ts-ignore
await targetHook[name].call(targetHook, eventData);
if (name === hook_method_names_1.default._onConfigureResponse && targetHook._responseEventConfigureOpts) {
const { opts, id: eventId } = eventData;
await this.setConfigureResponseEventOptions({ eventId, opts });
}
}
async setMock({ testId, hookId, ruleId, responseEventId, mock }) {
await this.proxy.call(this.setMock, { testId, hookId, ruleId, responseEventId, mock });
}
async setConfigureResponseEventOptions({ eventId, opts }) {
await this.proxy.call(this.setConfigureResponseEventOptions, { eventId, opts });
}
async setHeaderOnConfigureResponseEvent({ eventId, headerName, headerValue }) {
await this.proxy.call(this.setHeaderOnConfigureResponseEvent, { eventId, headerName, headerValue });
}
async removeHeaderOnConfigureResponseEvent({ eventId, headerName }) {
await this.proxy.call(this.removeHeaderOnConfigureResponseEvent, { eventId, headerName });
}
async executeRequestFilterRulePredicate({ testId, hookId, ruleId, requestInfo }) {
const test = this.state.units[testId];
const targetHook = test.requestHooks.find(hook => hook.id === hookId);
const targetRule = targetHook._requestFilterRules.find(rule => rule.id === ruleId);
const result = await targetRule.options.call(targetRule, requestInfo);
return !!result;
}
async executeMockPredicate({ testId, hookId, ruleId, requestInfo, res }) {
const test = this.state.units[testId];
const requestMock = test.requestHooks.find(hook => hook.id === hookId);
const responseMock = requestMock.mocks.get(ruleId);
testcafe_hammerhead_1.responseMockSetBodyMethod.add(res);
res = Object.assign(res, await responseMock.body(requestInfo, res));
testcafe_hammerhead_1.responseMockSetBodyMethod.remove(res);
return res;
}
async getWarningMessages({ testRunId }) {
// NOTE: In case of raising an error into ReporterPluginHost methods,
// TestRun has time to start.
const targetTestRun = this._getTargetTestRun(testRunId);
return targetTestRun ? targetTestRun.warningLog.messageInfos : [];
}
async addRequestEventListeners({ hookId, hookClassName, rules }) {
return await this.proxy.call(this.addRequestEventListeners, { hookId, hookClassName, rules });
}
async removeRequestEventListeners({ rules }) {
return await this.proxy.call(this.removeRequestEventListeners, { rules });
}
async initializeTestRunData({ testRunId, testId, browser, activeWindowId, messageBus }) {
// NOTE: In case of raising an error into ReporterPluginHost methods,
// TestRun has time to start.
const test = this.state.units[testId];
if (!test)
return;
this._initializeTestRunProxy({ testRunId, test, browser, activeWindowId, messageBus });
this._initializeFixtureCtx(test);
}
enableDebugForNonDebugCommands() {
test_controller_1.default.enableDebugForNonDebugCommands();
}
disableDebugForNonDebugCommands() {
test_controller_1.default.disableDebugForNonDebugCommands();
}
async getAssertionActualValue({ testRunId, commandId }) {
return this._getTargetTestRun(testRunId).getAssertionActualValue(commandId);
}
async executeRoleInitFn({ testRunId, roleId }) {
const role = this._getTargetRole(roleId);
const testRunProxy = this._getTargetTestRun(testRunId);
return role._initFn(testRunProxy);
}
async getCtx({ testRunId }) {
return this._getTargetTestRun(testRunId).ctx;
}
async getFixtureCtx({ testRunId }) {
return this._getTargetTestRun(testRunId).fixtureCtx;
}
async setCtx({ testRunId, value }) {
this._getTargetTestRun(testRunId).ctx = value;
}
async setFixtureCtx({ testRunId, value }) {
this._getTargetTestRun(testRunId).fixtureCtx = value;
}
onRoleAppeared(role) {
if (this.state.roles.has(role.id))
return;
this.state.roles.set(role.id, role);
}
async updateRoleProperty({ roleId, name, value }) {
const role = this._getTargetRole(roleId);
// @ts-ignore
role[name] = value;
}
async executeJsExpression({ expression, testRunId, options }) {
const testRunProxy = this._getTargetTestRun(testRunId);
return (0, execute_js_expression_1.executeJsExpression)(expression, testRunProxy, options);
}
async executeAsyncJsExpression({ expression, testRunId, callsite }) {
const testRunProxy = this._getTargetTestRun(testRunId);
return (0, execute_js_expression_1.executeAsyncJsExpression)(expression, testRunProxy, callsite, async (err) => {
if (err instanceof test_run_1.UncaughtTestCafeErrorInCustomScript === false)
return;
const targetError = err;
if (!(0, utils_1.shouldRenderHtmlWithoutStack)(targetError))
return;
testRunProxy.restoreOriginCallsiteForError(targetError);
// @ts-ignore
err.errCallsite = (0, utils_1.renderHtmlWithoutStack)(targetError);
});
}
async executeAssertionFn({ testRunId, commandId }) {
return this
._getTargetTestRun(testRunId)
.executeAssertionFn(commandId);
}
async addUnexpectedError({ type, message }) {
return this.proxy.call(this.addUnexpectedError, { type, message });
}
async checkWindow({ testRunId, commandId, url, title }) {
try {
return this
._getTargetTestRun(testRunId)
.checkWindow(commandId, { title, url });
}
catch (err) {
throw new errors_1.SwitchToWindowPredicateError(err.message);
}
}
async removeTestRunFromState({ testRunId }) {
delete this.state.testRuns[testRunId];
}
async removeFixtureCtxsFromState({ fixtureIds }) {
for (const fixtureId of fixtureIds)
delete this.state.fixtureCtxs[fixtureId];
}
async removeUnitsFromState({ runnableConfigurationId }) {
const unitIds = this._runnableConfigurationUnitsRelations[runnableConfigurationId];
for (const unitId of unitIds)
delete this.state.units[unitId];
delete this._runnableConfigurationUnitsRelations[runnableConfigurationId];
}
}
exports.default = new CompilerService();
module.exports = exports.default;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2aWNlcy9jb21waWxlci9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNENBQW9CO0FBQ3BCLDhEQUFzQztBQUN0QyxzRUFBNEM7QUFDNUMsZ0ZBQXVEO0FBRXZELG9FQU95QztBQUV6Qyw2QkFJYztBQUVkLDhDQUE4QztBQUM5QyxzREFBMEQ7QUFFMUQseUNBTW9CO0FBZ0NwQixxRUFBNEM7QUFFNUMsa0dBQStFO0FBRS9FLDZEQU82QjtBQUs3Qiw4RUFBcUQ7QUFDckQsZ0ZBQXFHO0FBRXJHLG9EQUsrQjtBQUUvQiw2RUFBeUg7QUFDekgsaUZBQTRFO0FBQzVFLDZEQUF3RDtBQUN4RCxnREFBbUU7QUFHbkUsbUNBQThCO0FBRTlCLElBQUEsK0NBQXFCLEdBQUUsQ0FBQztBQUV4QixzRkFBc0Y7QUFDdEYsdUNBQXVDO0FBQ3ZDLE9BQU8sQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0FBc0IzQyxNQUFNLGVBQWU7SUFLakI7UUFDSSxPQUFPLENBQUMsS0FBSyxHQUFHLHVCQUFZLENBQUMsT0FBTyxDQUFDO1FBRXJDLE1BQU0sS0FBSyxHQUFJLFlBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUscUJBQWdCLEVBQUUsQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sTUFBTSxHQUFHLFlBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsc0JBQWlCLEVBQUUsQ0FBQyxDQUFDO1FBRW5FLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxnQkFBUSxDQUFDLElBQUksNEJBQWdCLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxvQkFBZSxDQUFDLENBQUMsQ0FBQztRQUNoRixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUUvQixJQUFJLENBQUMsb0NBQW9D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