UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

84 lines 13.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const testcafe_hammerhead_1 = __importDefault(require("testcafe-hammerhead")); const asyncToGenerator_1 = __importDefault(require("@babel/runtime/helpers/asyncToGenerator")); const lodash_1 = require("lodash"); const load_libs_1 = __importDefault(require("./babel/load-libs")); const runtime_1 = require("../errors/runtime"); const types_1 = require("../errors/types"); const format_babel_produced_code_1 = __importDefault(require("./babel/format-babel-produced-code")); const get_base_babel_options_1 = __importDefault(require("./babel/get-base-babel-options")); const ANONYMOUS_FN_RE = /^function\s*\*?\s*\(/; const ES6_OBJ_METHOD_NAME_RE = /^(\S+?)\s*\(/; const USE_STRICT_RE = /^('|")use strict('|");?/; const TRAILING_SEMICOLON_RE = /;\s*$/; const REGENERATOR_FOOTPRINTS_RE = /(_index\d+\.default|_regenerator\d+\.default|regeneratorRuntime|regenerator)(\(\))?\.(wrap|w)\(function (func\$|)\(_context\)/; const ASYNC_TO_GENERATOR_OUTPUT_CODE = (0, format_babel_produced_code_1.default)((0, asyncToGenerator_1.default)(lodash_1.noop).toString()); const CLIENT_FUNCTION_BODY_WRAPPER = code => `const func = (${code});`; const CLIENT_FUNCTION_WRAPPER = ({ code, dependencies }) => `(function(){${dependencies} ${code} return func;})();`; let loadedBabelOptions = null; function getBabelOptions() { const { presetEnvForClientFunction, transformForOfAsArray } = (0, load_libs_1.default)(); return Object.assign({}, get_base_babel_options_1.default, { presets: [{ plugins: [transformForOfAsArray] }, presetEnvForClientFunction], }); } function ensureLoadedBabelOptions() { if (!loadedBabelOptions) { const { babel } = (0, load_libs_1.default)(); const opts = getBabelOptions(); loadedBabelOptions = babel.loadOptions(opts); } return loadedBabelOptions; } function downgradeES(fnCode) { const { babel } = (0, load_libs_1.default)(); const opts = ensureLoadedBabelOptions(); const compiled = babel.transform(fnCode, opts); return compiled.code .replace(USE_STRICT_RE, '') .trim(); } function getDependenciesDefinition(dependencies) { return Object .keys(dependencies) .reduce((code, name) => { return code + `var ${name}=__dependencies$['${name}'];`; }, ''); } function makeFnCodeSuitableForParsing(fnCode) { // NOTE: 'function() {}' -> '(function() {})' if (ANONYMOUS_FN_RE.test(fnCode)) return `(${fnCode})`; // NOTE: 'myFn () {}' -> 'function myFn() {}' const match = fnCode.match(ES6_OBJ_METHOD_NAME_RE); if (match && match[1] !== 'function') return `function ${fnCode}`; return fnCode; } function containsAsyncToGeneratorOutputCode(code) { const formattedCode = (0, format_babel_produced_code_1.default)(code); return formattedCode.includes(ASYNC_TO_GENERATOR_OUTPUT_CODE); } function compileClientFunction(fnCode, dependencies, instantiationCallsiteName, compilationCallsiteName) { if (containsAsyncToGeneratorOutputCode(fnCode)) throw new runtime_1.ClientFunctionAPIError(compilationCallsiteName, instantiationCallsiteName, types_1.RUNTIME_ERRORS.regeneratorInClientFunctionCode); fnCode = makeFnCodeSuitableForParsing(fnCode); fnCode = CLIENT_FUNCTION_BODY_WRAPPER(fnCode); // NOTE: we need to recompile ES6 code for the browser if we are on newer versions of Node. fnCode = downgradeES(fnCode); fnCode = testcafe_hammerhead_1.default.processScript(fnCode, false); // NOTE: check compiled code for regenerator injection if (REGENERATOR_FOOTPRINTS_RE.test(fnCode)) throw new runtime_1.ClientFunctionAPIError(compilationCallsiteName, instantiationCallsiteName, types_1.RUNTIME_ERRORS.regeneratorInClientFunctionCode); if (!TRAILING_SEMICOLON_RE.test(fnCode)) fnCode += ';'; const dependenciesDefinition = dependencies ? getDependenciesDefinition(dependencies) : ''; return CLIENT_FUNCTION_WRAPPER({ code: fnCode, dependencies: dependenciesDefinition }); } exports.default = compileClientFunction; module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsZS1jbGllbnQtZnVuY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tcGlsZXIvY29tcGlsZS1jbGllbnQtZnVuY3Rpb24uanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw4RUFBNkM7QUFDN0MsK0ZBQXVFO0FBQ3ZFLG1DQUE4QjtBQUM5QixrRUFBOEM7QUFDOUMsK0NBQTJEO0FBQzNELDJDQUFpRDtBQUNqRCxvR0FBeUU7QUFDekUsNEZBQWdFO0FBRWhFLE1BQU0sZUFBZSxHQUFrQixzQkFBc0IsQ0FBQztBQUM5RCxNQUFNLHNCQUFzQixHQUFXLGNBQWMsQ0FBQztBQUN0RCxNQUFNLGFBQWEsR0FBb0IseUJBQXlCLENBQUM7QUFDakUsTUFBTSxxQkFBcUIsR0FBWSxPQUFPLENBQUM7QUFDL0MsTUFBTSx5QkFBeUIsR0FBUSwrSEFBK0gsQ0FBQztBQUN2SyxNQUFNLDhCQUE4QixHQUFHLElBQUEsb0NBQXVCLEVBQUMsSUFBQSwwQkFBZ0IsRUFBQyxhQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0FBRWxHLE1BQU0sNEJBQTRCLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsSUFBSSxJQUFJLENBQUM7QUFDdkUsTUFBTSx1QkFBdUIsR0FBUSxDQUFDLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsQ0FBQyxlQUFlLFlBQVksSUFBSSxJQUFJLG9CQUFvQixDQUFDO0FBRXpILElBQUksa0JBQWtCLEdBQUcsSUFBSSxDQUFDO0FBRTlCLFNBQVMsZUFBZTtJQUNwQixNQUFNLEVBQUUsMEJBQTBCLEVBQUUscUJBQXFCLEVBQUUsR0FBRyxJQUFBLG1CQUFhLEdBQUUsQ0FBQztJQUU5RSxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLGdDQUFrQixFQUFFO1FBQ3pDLE9BQU8sRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMscUJBQXFCLENB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QUFHLFlBQVksQ0FBQyxDQUFDLENBQUMseUJBQXlCLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUUzRixPQUFPLHVCQUF1QixDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsc0JBQXNCLEVBQUUsQ0FBQyxDQUFDO0FBQzNGLENBQUM7QUF2QkQsd0NBdUJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGhhbW1lcmhlYWQgZnJvbSAndGVzdGNhZmUtaGFtbWVyaGVhZCc7XG5pbXBvcnQgYXN5bmNUb0dlbmVyYXRvciBmcm9tICdAYmFiZWwvcnVudGltZS9oZWxwZXJzL2FzeW5jVG9HZW5lcmF0b3InO1xuaW1wb3J0IHsgbm9vcCB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbG9hZEJhYmVsTGlicyBmcm9tICcuL2JhYmVsL2xvYWQtbGlicyc7XG5pbXBvcnQgeyBDbGllbnRGdW5jdGlvbkFQSUVycm9yIH0gZnJvbSAnLi4vZXJyb3JzL3J1bnRpbWUnO1xuaW1wb3J0IHsgUlVOVElNRV9FUlJPUlMgfSBmcm9tICcuLi9lcnJvcnMvdHlwZXMnO1xuaW1wb3J0IGZvcm1hdEJhYmVsUHJvZHVjZWRDb2RlIGZyb20gJy4vYmFiZWwvZm9ybWF0LWJhYmVsLXByb2R1Y2VkLWNvZGUnO1xuaW1wb3J0IEJBU0VfQkFCRUxfT1BUSU9OUyBmcm9tICcuL2JhYmVsL2dldC1iYXNlLWJhYmVsLW9wdGlvbnMnO1xuXG5jb25zdCBBTk9OWU1PVVNfRk5fUkUgICAgICAgICAgICAgICAgPSAvXmZ1bmN0aW9uXFxzKlxcKj9cXHMqXFwoLztcbmNvbnN0IEVTNl9PQkpfTUVUSE9EX05BTUVfUkUgICAgICAgICA9IC9eKFxcUys/KVxccypcXCgvO1xuY29uc3QgVVNFX1NUUklDVF9SRSAgICAgICAgICAgICAgICAgID0gL14oJ3xcIil1c2Ugc3RyaWN0KCd8XCIpOz8vO1xuY29uc3QgVFJBSUxJTkdfU0VNSUNPTE9OX1JFICAgICAgICAgID0gLztcXHMqJC87XG5jb25zdCBSRUdFTkVSQVRPUl9GT09UUFJJTlRTX1JFICAgICAgPSAvKF9pbmRleFxcZCtcXC5kZWZhdWx0fF9yZWdlbmVyYXRvclxcZCtcXC5kZWZhdWx0fHJlZ2VuZXJhdG9yUnVudGltZXxyZWdlbmVyYXRvcikoXFwoXFwpKT9cXC4od3JhcHx3KVxcKGZ1bmN0aW9uIChmdW5jXFwkfClcXChfY29udGV4dFxcKS87XG5jb25zdCBBU1lOQ19UT19HRU5FUkFUT1JfT1VUUFVUX0NPREUgPSBmb3JtYXRCYWJlbFByb2R1Y2VkQ29kZShhc3luY1RvR2VuZXJhdG9yKG5vb3ApLnRvU3RyaW5nKCkpO1xuXG5jb25zdCBDTElFTlRfRlVOQ1RJT05fQk9EWV9XUkFQUEVSID0gY29kZSA9PiBgY29uc3QgZnVuYyA9ICgke2NvZGV9KTtgO1xuY29uc3QgQ0xJRU5UX0ZVTkNUSU9OX1dSQVBQRVIgICAgICA9ICh7IGNvZGUsIGRlcGVuZGVuY2llcyB9KSA9PiBgKGZ1bmN0aW9uKCl7JHtkZXBlbmRlbmNpZXN9ICR7Y29kZX0gcmV0dXJuIGZ1bmM7fSkoKTtgO1xuXG5sZXQgbG9hZGVkQmFiZWxPcHRpb25zID0gbnVsbDtcblxuZnVuY3Rpb24gZ2V0QmFiZWxPcHRpb25zICgpIHtcbiAgICBjb25zdCB7IHByZXNldEVudkZvckNsaWVudEZ1bmN0aW9uLCB0cmFuc2Zvcm1Gb3JPZkFzQXJyYXkgfSA9IGxvYWRCYWJlbExpYnMoKTtcblxuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBCQVNFX0JBQkVMX09QVElPTlMsIHtcbiAgICAgICAgcHJlc2V0czogW3sgcGx1Z2luczogW3RyYW5zZm9ybUZvck9mQXNBcnJheV0gfSwgcHJlc2V0RW52Rm9yQ2xpZW50RnVuY3Rpb25dLFxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBlbnN1cmVMb2FkZWRCYWJlbE9wdGlvbnMgKCkge1xuICAgIGlmICghbG9hZGVkQmFiZWxPcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHsgYmFiZWwgfSA9IGxvYWRCYWJlbExpYnMoKTtcbiAgICAgICAgY29uc3Qgb3B0cyAgICAgID0gZ2V0QmFiZWxPcHRpb25zKCk7XG5cbiAgICAgICAgbG9hZGVkQmFiZWxPcHRpb25zID0gYmFiZWwubG9hZE9wdGlvbnMob3B0cyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxvYWRlZEJhYmVsT3B0aW9ucztcbn1cblxuZnVuY3Rpb24gZG93bmdyYWRlRVMgKGZuQ29kZSkge1xuICAgIGNvbnN0IHsgYmFiZWwgfSA9IGxvYWRCYWJlbExpYnMoKTtcbiAgICBjb25zdCBvcHRzICAgICAgPSBlbnN1cmVMb2FkZWRCYWJlbE9wdGlvbnMoKTtcbiAgICBjb25zdCBjb21waWxlZCAgPSBiYWJlbC50cmFuc2Zvcm0oZm5Db2RlLCBvcHRzKTtcblxuICAgIHJldHVybiBjb21waWxlZC5jb2RlXG4gICAgICAgIC5yZXBsYWNlKFVTRV9TVFJJQ1RfUkUsICcnKVxuICAgICAgICAudHJpbSgpO1xufVxuXG5mdW5jdGlvbiBnZXREZXBlbmRlbmNpZXNEZWZpbml0aW9uIChkZXBlbmRlbmNpZXMpIHtcbiAgICByZXR1cm4gT2JqZWN0XG4gICAgICAgIC5rZXlzKGRlcGVuZGVuY2llcylcbiAgICAgICAgLnJlZHVjZSgoY29kZSwgbmFtZSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGNvZGUgKyBgdmFyICR7bmFtZX09X19kZXBlbmRlbmNpZXMkWycke25hbWV9J107YDtcbiAgICAgICAgfSwgJycpO1xufVxuXG5mdW5jdGlvbiBtYWtlRm5Db2RlU3VpdGFibGVGb3JQYXJzaW5nIChmbkNvZGUpIHtcbiAgICAvLyBOT1RFOiAnZnVuY3Rpb24oKSB7fScgLT4gJyhmdW5jdGlvbigpIHt9KSdcbiAgICBpZiAoQU5PTllNT1VTX0ZOX1JFLnRlc3QoZm5Db2RlKSlcbiAgICAgICAgcmV0dXJuIGAoJHtmbkNvZGV9KWA7XG5cbiAgICAvLyBOT1RFOiAnbXlGbiAoKSB7fScgLT4gJ2Z1bmN0aW9uIG15Rm4oKSB7fSdcbiAgICBjb25zdCBtYXRjaCA9IGZuQ29kZS5tYXRjaChFUzZfT0JKX01FVEhPRF9OQU1FX1JFKTtcblxuICAgIGlmIChtYXRjaCAmJiBtYXRjaFsxXSAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgcmV0dXJuIGBmdW5jdGlvbiAke2ZuQ29kZX1gO1xuXG4gICAgcmV0dXJuIGZuQ29kZTtcbn1cblxuZnVuY3Rpb24gY29udGFpbnNBc3luY1RvR2VuZXJhdG9yT3V0cHV0Q29kZSAoY29kZSkge1xuICAgIGNvbnN0IGZvcm1hdHRlZENvZGUgPSBmb3JtYXRCYWJlbFByb2R1Y2VkQ29kZShjb2RlKTtcblxuICAgIHJldHVybiBmb3JtYXR0ZWRDb2RlLmluY2x1ZGVzKEFTWU5DX1RPX0dFTkVSQVRPUl9PVVRQVVRfQ09ERSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNvbXBpbGVDbGllbnRGdW5jdGlvbiAoZm5Db2RlLCBkZXBlbmRlbmNpZXMsIGluc3RhbnRpYXRpb25DYWxsc2l0ZU5hbWUsIGNvbXBpbGF0aW9uQ2FsbHNpdGVOYW1lKSB7XG4gICAgaWYgKGNvbnRhaW5zQXN5bmNUb0dlbmVyYXRvck91dHB1dENvZGUoZm5Db2RlKSlcbiAgICAgICAgdGhyb3cgbmV3IENsaWVudEZ1bmN0aW9uQVBJRXJyb3IoY29tcGlsYXRpb25DYWxsc2l0ZU5hbWUsIGluc3RhbnRpYXRpb25DYWxsc2l0ZU5hbWUsIFJVTlRJTUVfRVJST1JTLnJlZ2VuZXJhdG9ySW5DbGllbnRGdW5jdGlvbkNvZGUpO1xuXG4gICAgZm5Db2RlID0gbWFrZUZuQ29kZVN1aXRhYmxlRm9yUGFyc2luZyhmbkNvZGUpO1xuXG5cbiAgICBmbkNvZGUgPSBDTElFTlRfRlVOQ1RJT05fQk9EWV9XUkFQUEVSKGZuQ29kZSk7XG5cbiAgICAvLyBOT1RFOiB3ZSBuZWVkIHRvIHJlY29tcGlsZSBFUzYgY29kZSBmb3IgdGhlIGJyb3dzZXIgaWYgd2UgYXJlIG9uIG5ld2VyIHZlcnNpb25zIG9mIE5vZGUuXG4gICAgZm5Db2RlID0gZG93bmdyYWRlRVMoZm5Db2RlKTtcbiAgICBmbkNvZGUgPSBoYW1tZXJoZWFkLnByb2Nlc3NTY3JpcHQoZm5Db2RlLCBmYWxzZSk7XG5cbiAgICAvLyBOT1RFOiBjaGVjayBjb21waWxlZCBjb2RlIGZvciByZWdlbmVyYXRvciBpbmplY3Rpb25cbiAgICBpZiAoUkVHRU5FUkFUT1JfRk9PVFBSSU5UU19SRS50ZXN0KGZuQ29kZSkpXG4gICAgICAgIHRocm93IG5ldyBDbGllbnRGdW5jdGlvbkFQSUVycm9yKGNvbXBpbGF0aW9uQ2FsbHNpdGVOYW1lLCBpbnN0YW50aWF0aW9uQ2FsbHNpdGVOYW1lLCBSVU5USU1FX0VSUk9SUy5yZWdlbmVyYXRvckluQ2xpZW50RnVuY3Rpb25Db2RlKTtcblxuICAgIGlmICghVFJBSUxJTkdfU0VNSUNPTE9OX1JFLnRlc3QoZm5Db2RlKSlcbiAgICAgICAgZm5Db2RlICs9ICc7JztcblxuICAgIGNvbnN0IGRlcGVuZGVuY2llc0RlZmluaXRpb24gPSBkZXBlbmRlbmNpZXMgPyBnZXREZXBlbmRlbmNpZXNEZWZpbml0aW9uKGRlcGVuZGVuY2llcykgOiAnJztcblxuICAgIHJldHVybiBDTElFTlRfRlVOQ1RJT05fV1JBUFBFUih7IGNvZGU6IGZuQ29kZSwgZGVwZW5kZW5jaWVzOiBkZXBlbmRlbmNpZXNEZWZpbml0aW9uIH0pO1xufVxuIl19