UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

95 lines 14.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const lodash_1 = require("lodash"); const strip_bom_1 = __importDefault(require("strip-bom")); const promisified_functions_1 = require("../utils/promisified-functions"); const runtime_1 = require("../errors/runtime"); const types_1 = require("../errors/types"); const compilers_1 = require("./compilers"); const SOURCE_CHUNK_LENGTH = 1000; class Compiler { constructor(sources, compilerOptions, { baseUrl, esm } = {}) { this.sources = sources; this.esm = esm; (0, compilers_1.initTestFileCompilers)(compilerOptions, { baseUrl, esm }); } static getSupportedTestFileExtensions() { return (0, lodash_1.uniq)((0, lodash_1.flattenDeep)((0, compilers_1.getTestFileCompilers)().map(compiler => compiler.getSupportedExtension()))); } static async createTestFileInfo(filename, esm = false) { let code = null; try { code = await (0, promisified_functions_1.readFile)(filename); } catch (err) { throw new runtime_1.GeneralError(types_1.RUNTIME_ERRORS.cannotFindSpecifiedTestSource, filename); } code = (0, strip_bom_1.default)(code).toString(); const compiler = (0, lodash_1.find)((0, compilers_1.getTestFileCompilers)(esm), someCompiler => someCompiler.canCompile(code, filename)); if (!compiler) return null; return { filename, code, compiler, compiledCode: null, }; } async _createTestFilesInfo(filenames) { const testFilesInfo = await Promise.all(filenames.map(filename => Compiler.createTestFileInfo(filename))); return testFilesInfo.filter(info => !!info); } async _precompileFiles(compiler, testFilesInfo) { if (!compiler.canPrecompile || this.esm && compiler.canCompileInEsm) return; const precompiledCode = await compiler.precompile(testFilesInfo); for (let i = 0; i < testFilesInfo.length; i++) testFilesInfo[i].compiledCode = precompiledCode[i]; } _getCompilerTasks(testFilesInfo) { const tasks = new WeakMap(); const compilers = []; for (const info of testFilesInfo) { const { compiler } = info; if (!tasks.has(compiler)) { compilers.push(compiler); tasks.set(compiler, []); } tasks.get(info.compiler).push(info); } return compilers.map(compiler => ({ compiler, compilerTestFilesInfo: tasks.get(compiler) })); } async _getTests({ compiler, filename, code, compiledCode }) { if (compiledCode || this.esm && compiler.canCompileInEsm) return await compiler.execute(compiledCode, filename); return await compiler.compile(code, filename); } async _compileTestFiles(filenames) { const testFilesInfo = await this._createTestFilesInfo(filenames); const compilerTasks = this._getCompilerTasks(testFilesInfo); await Promise.all(compilerTasks.map(({ compiler, compilerTestFilesInfo }) => this._precompileFiles(compiler, compilerTestFilesInfo))); const tests = []; for (const info of testFilesInfo) tests.push(await this._getTests(info)); return tests; } async getTests() { // NOTE: split sources into chunks because the fs module can't read all files // simultaneously if the number of them is too large (several thousands). const sourceChunks = (0, lodash_1.chunk)(this.sources, SOURCE_CHUNK_LENGTH); let tests = []; while (sourceChunks.length) tests = tests.concat(await this._compileTestFiles(sourceChunks.shift())); Compiler.cleanUp(); return (0, lodash_1.flattenDeep)(tests).filter(test => !!test); } static cleanUp() { (0, compilers_1.getTestFileCompilers)().forEach(compiler => compiler.cleanUp()); } } exports.default = Compiler; module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tcGlsZXIvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxtQ0FLZ0I7QUFFaEIsMERBQWlDO0FBQ2pDLDBFQUEwRDtBQUMxRCwrQ0FBaUQ7QUFDakQsMkNBQWlEO0FBQ2pELDJDQUEwRTtBQUcxRSxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQztBQUVqQyxNQUFxQixRQUFRO0lBQ3pCLFlBQWEsT0FBTyxFQUFFLGVBQWUsRUFBRSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFO1FBQ3hELElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO1FBRWYsSUFBQSxpQ0FBcUIsRUFBQyxlQUFlLEVBQUUsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRUQsTUFBTSxDQUFDLDhCQUE4QjtRQUNqQyxPQUFPLElBQUEsYUFBSSxFQUFDLElBQUEsb0JBQVcsRUFBQyxJQUFBLGdDQUFvQixHQUFFLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLHFCQUFxQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdkcsQ0FBQztJQUVELE1BQU0sQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUUsUUFBUSxFQUFFLEdBQUcsR0FBRyxLQUFLO1FBQ2xELElBQUksSUFBSSxHQUFHLElBQUksQ0FBQztRQUVoQixJQUFJO1lBQ0EsSUFBSSxHQUFHLE1BQU0sSUFBQSxnQ0FBUSxFQUFDLFFBQVEsQ0FBQyxDQUFDO1NBQ25DO1FBQ0QsT0FBTyxHQUFHLEVBQUU7WUFDUixNQUFNLElBQUksc0JBQVksQ0FBQyxzQkFBYyxDQUFDLDZCQUE2QixFQUFFLFFBQVEsQ0FBQyxDQUFDO1NBQ2xGO1FBRUQsSUFBSSxHQUFHLElBQUEs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Q0FDSjtBQS9HRCwyQkErR0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICAgIGZsYXR0ZW5EZWVwLFxuICAgIGZpbmQsXG4gICAgY2h1bmssXG4gICAgdW5pcSxcbn0gZnJvbSAnbG9kYXNoJztcblxuaW1wb3J0IHN0cmlwQm9tIGZyb20gJ3N0cmlwLWJvbSc7XG5pbXBvcnQgeyByZWFkRmlsZSB9IGZyb20gJy4uL3V0aWxzL3Byb21pc2lmaWVkLWZ1bmN0aW9ucyc7XG5pbXBvcnQgeyBHZW5lcmFsRXJyb3IgfSBmcm9tICcuLi9lcnJvcnMvcnVudGltZSc7XG5pbXBvcnQgeyBSVU5USU1FX0VSUk9SUyB9IGZyb20gJy4uL2Vycm9ycy90eXBlcyc7XG5pbXBvcnQgeyBnZXRUZXN0RmlsZUNvbXBpbGVycywgaW5pdFRlc3RGaWxlQ29tcGlsZXJzIH0gZnJvbSAnLi9jb21waWxlcnMnO1xuXG5cbmNvbnN0IFNPVVJDRV9DSFVOS19MRU5HVEggPSAxMDAwO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDb21waWxlciB7XG4gICAgY29uc3RydWN0b3IgKHNvdXJjZXMsIGNvbXBpbGVyT3B0aW9ucywgeyBiYXNlVXJsLCBlc20gfSA9IHt9ICkge1xuICAgICAgICB0aGlzLnNvdXJjZXMgPSBzb3VyY2VzO1xuICAgICAgICB0aGlzLmVzbSA9IGVzbTtcblxuICAgICAgICBpbml0VGVzdEZpbGVDb21waWxlcnMoY29tcGlsZXJPcHRpb25zLCB7IGJhc2VVcmwsIGVzbSB9KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgZ2V0U3VwcG9ydGVkVGVzdEZpbGVFeHRlbnNpb25zICgpIHtcbiAgICAgICAgcmV0dXJuIHVuaXEoZmxhdHRlbkRlZXAoZ2V0VGVzdEZpbGVDb21waWxlcnMoKS5tYXAoY29tcGlsZXIgPT4gY29tcGlsZXIuZ2V0U3VwcG9ydGVkRXh0ZW5zaW9uKCkpKSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGFzeW5jIGNyZWF0ZVRlc3RGaWxlSW5mbyAoZmlsZW5hbWUsIGVzbSA9IGZhbHNlKSB7XG4gICAgICAgIGxldCBjb2RlID0gbnVsbDtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29kZSA9IGF3YWl0IHJlYWRGaWxlKGZpbGVuYW1lKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgR2VuZXJhbEVycm9yKFJVTlRJTUVfRVJST1JTLmNhbm5vdEZpbmRTcGVjaWZpZWRUZXN0U291cmNlLCBmaWxlbmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb2RlID0gc3RyaXBCb20oY29kZSkudG9TdHJpbmcoKTtcblxuICAgICAgICBjb25zdCBjb21waWxlciA9IGZpbmQoZ2V0VGVzdEZpbGVDb21waWxlcnMoZXNtKSwgc29tZUNvbXBpbGVyID0+IHNvbWVDb21waWxlci5jYW5Db21waWxlKGNvZGUsIGZpbGVuYW1lKSk7XG5cbiAgICAgICAgaWYgKCFjb21waWxlcilcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBmaWxlbmFtZSxcbiAgICAgICAgICAgIGNvZGUsXG4gICAgICAgICAgICBjb21waWxlcixcblxuICAgICAgICAgICAgY29tcGlsZWRDb2RlOiBudWxsLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGFzeW5jIF9jcmVhdGVUZXN0RmlsZXNJbmZvIChmaWxlbmFtZXMpIHtcbiAgICAgICAgY29uc3QgdGVzdEZpbGVzSW5mbyA9IGF3YWl0IFByb21pc2UuYWxsKGZpbGVuYW1lcy5tYXAoZmlsZW5hbWUgPT4gQ29tcGlsZXIuY3JlYXRlVGVzdEZpbGVJbmZvKGZpbGVuYW1lKSkpO1xuXG4gICAgICAgIHJldHVybiB0ZXN0RmlsZXNJbmZvLmZpbHRlcihpbmZvID0+ICEhaW5mbyk7XG4gICAgfVxuXG4gICAgYXN5bmMgX3ByZWNvbXBpbGVGaWxlcyAoY29tcGlsZXIsIHRlc3RGaWxlc0luZm8pIHtcbiAgICAgICAgaWYgKCFjb21waWxlci5jYW5QcmVjb21waWxlIHx8IHRoaXMuZXNtICYmIGNvbXBpbGVyLmNhbkNvbXBpbGVJbkVzbSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBjb25zdCBwcmVjb21waWxlZENvZGUgPSBhd2FpdCBjb21waWxlci5wcmVjb21waWxlKHRlc3RGaWxlc0luZm8pO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGVzdEZpbGVzSW5mby5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIHRlc3RGaWxlc0luZm9baV0uY29tcGlsZWRDb2RlID0gcHJlY29tcGlsZWRDb2RlW2ldO1xuICAgIH1cblxuICAgIF9nZXRDb21waWxlclRhc2tzICh0ZXN0RmlsZXNJbmZvKSB7XG4gICAgICAgIGNvbnN0IHRhc2tzICAgICA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNvbXBpbGVycyA9IFtdO1xuXG4gICAgICAgIGZvciAoY29uc3QgaW5mbyBvZiB0ZXN0RmlsZXNJbmZvKSB7XG4gICAgICAgICAgICBjb25zdCB7IGNvbXBpbGVyIH0gPSBpbmZvO1xuXG4gICAgICAgICAgICBpZiAoIXRhc2tzLmhhcyhjb21waWxlcikpIHtcbiAgICAgICAgICAgICAgICBjb21waWxlcnMucHVzaChjb21waWxlcik7XG4gICAgICAgICAgICAgICAgdGFza3Muc2V0KGNvbXBpbGVyLCBbXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRhc2tzLmdldChpbmZvLmNvbXBpbGVyKS5wdXNoKGluZm8pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbXBpbGVycy5tYXAoY29tcGlsZXIgPT4gKHsgY29tcGlsZXIsIGNvbXBpbGVyVGVzdEZpbGVzSW5mbzogdGFza3MuZ2V0KGNvbXBpbGVyKSB9KSk7XG4gICAgfVxuXG4gICAgYXN5bmMgX2dldFRlc3RzICh7IGNvbXBpbGVyLCBmaWxlbmFtZSwgY29kZSwgY29tcGlsZWRDb2RlIH0pIHtcbiAgICAgICAgaWYgKGNvbXBpbGVkQ29kZSB8fCB0aGlzLmVzbSAmJiBjb21waWxlci5jYW5Db21waWxlSW5Fc20pXG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgY29tcGlsZXIuZXhlY3V0ZShjb21waWxlZENvZGUsIGZpbGVuYW1lKTtcblxuICAgICAgICByZXR1cm4gYXdhaXQgY29tcGlsZXIuY29tcGlsZShjb2RlLCBmaWxlbmFtZSk7XG4gICAgfVxuXG4gICAgYXN5bmMgX2NvbXBpbGVUZXN0RmlsZXMgKGZpbGVuYW1lcykge1xuICAgICAgICBjb25zdCB0ZXN0RmlsZXNJbmZvID0gYXdhaXQgdGhpcy5fY3JlYXRlVGVzdEZpbGVzSW5mbyhmaWxlbmFtZXMpO1xuICAgICAgICBjb25zdCBjb21waWxlclRhc2tzID0gdGhpcy5fZ2V0Q29tcGlsZXJUYXNrcyh0ZXN0RmlsZXNJbmZvKTtcblxuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChjb21waWxlclRhc2tzLm1hcCgoeyBjb21waWxlciwgY29tcGlsZXJUZXN0RmlsZXNJbmZvIH0pID0+IHRoaXMuX3ByZWNvbXBpbGVGaWxlcyhjb21waWxlciwgY29tcGlsZXJUZXN0RmlsZXNJbmZvKSkpO1xuXG4gICAgICAgIGNvbnN0IHRlc3RzID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBpbmZvIG9mIHRlc3RGaWxlc0luZm8pXG4gICAgICAgICAgICB0ZXN0cy5wdXNoKGF3YWl0IHRoaXMuX2dldFRlc3RzKGluZm8pKTtcblxuICAgICAgICByZXR1cm4gdGVzdHM7XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0VGVzdHMgKCkge1xuICAgICAgICAvLyBOT1RFOiBzcGxpdCBzb3VyY2VzIGludG8gY2h1bmtzIGJlY2F1c2UgdGhlIGZzIG1vZHVsZSBjYW4ndCByZWFkIGFsbCBmaWxlc1xuICAgICAgICAvLyBzaW11bHRhbmVvdXNseSBpZiB0aGUgbnVtYmVyIG9mIHRoZW0gaXMgdG9vIGxhcmdlIChzZXZlcmFsIHRob3VzYW5kcykuXG4gICAgICAgIGNvbnN0IHNvdXJjZUNodW5rcyA9IGNodW5rKHRoaXMuc291cmNlcywgU09VUkNFX0NIVU5LX0xFTkdUSCk7XG5cbiAgICAgICAgbGV0IHRlc3RzID0gW107XG5cbiAgICAgICAgd2hpbGUgKHNvdXJjZUNodW5rcy5sZW5ndGgpXG4gICAgICAgICAgICB0ZXN0cyA9IHRlc3RzLmNvbmNhdChhd2FpdCB0aGlzLl9jb21waWxlVGVzdEZpbGVzKHNvdXJjZUNodW5rcy5zaGlmdCgpKSk7XG5cbiAgICAgICAgQ29tcGlsZXIuY2xlYW5VcCgpO1xuXG4gICAgICAgIHJldHVybiBmbGF0dGVuRGVlcCh0ZXN0cykuZmlsdGVyKHRlc3QgPT4gISF0ZXN0KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgY2xlYW5VcCAoKSB7XG4gICAgICAgIGdldFRlc3RGaWxlQ29tcGlsZXJzKCkuZm9yRWFjaChjb21waWxlciA9PiBjb21waWxlci5jbGVhblVwKCkpO1xuICAgIH1cbn1cbiJdfQ==