UNPKG

@badeball/cypress-configuration

Version:

[![Build status](https://github.com/badeball/cypress-configuration/actions/workflows/build.yml/badge.svg)](https://github.com/badeball/cypress-configuration/actions/workflows/build.yml) [![Npm package weekly downloads](https://badgen.net/npm/dw/@badeball/

242 lines (241 loc) 11.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.resolvePost10TestFiles = exports.resolvePost10Configuration = exports.CONFIG_FILE_NAMES = void 0; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const util_1 = __importDefault(require("util")); const glob_1 = __importDefault(require("glob")); const node_hook_1 = __importDefault(require("node-hook")); const esbuild = __importStar(require("esbuild")); const debug_1 = __importDefault(require("../debug")); const assertions_1 = require("../assertions"); const type_guards_1 = require("../type-guards"); const path_helpers_1 = require("../path-helpers"); const cypress_post10_configuration_parser_1 = require("./cypress-post10-configuration-parser"); const helpers_1 = require("./helpers"); const errors_1 = require("./errors"); exports.CONFIG_FILE_NAMES = [ "cypress.config.js", "cypress.config.cjs", "cypress.config.mjs", "cypress.config.ts", ]; function isStringEntry(entry) { return typeof entry[0] === "string" && typeof entry[1] === "string"; } function isPlainObject(value) { return (value === null || value === void 0 ? void 0 : value.constructor) === Object; } function validateConfigurationEntry(key, value) { switch (key) { case "projectRoot": if (!(0, type_guards_1.isString)(value)) { throw new Error(`Expected a string (projectRoot), but got ${util_1.default.inspect(value)}`); } return { [key]: value }; case "specPattern": if (!(0, type_guards_1.isStringOrStringArray)(value)) { throw new Error(`Expected a string or array of strings (specPattern), but got ${util_1.default.inspect(value)}`); } return { [key]: value }; case "excludeSpecPattern": if (!(0, type_guards_1.isStringOrStringArray)(value)) { throw new Error(`Expected a string or array of strings (excludeSpecPattern), but got ${util_1.default.inspect(value)}`); } return { [key]: value }; case "env": if (!isPlainObject(value)) { throw new Error(`Expected a plain object (env), but got ${util_1.default.inspect(value)}`); } return { [key]: value }; default: return {}; } } function resolvePost10Configuration(options) { var _a, _b; (0, debug_1.default)(`attempting to resolve Cypress configuration using ${util_1.default.inspect(options)}`); const { argv, env, testingType } = options; const projectPath = (0, helpers_1.resolveProjectPath)(options); const cliOrigin = Object.assign({}, ...Array.from((0, helpers_1.combine)((0, helpers_1.traverseArgvMatching)(argv, "--config", true), (0, helpers_1.traverseArgvMatching)(argv, "-c", false))) .reverse() .flatMap((argument) => { const keypairExpr = /(?:^|,)([^=]+)=([^,$]+)/g; const entries = []; let match; while ((match = keypairExpr.exec(argument)) !== null) { entries.push(validateConfigurationEntry(match[1], match[2])); } return entries; })); const envPrefixExpr = /^cypress_(.+)/i; const envOrigin = Object.assign({}, ...Object.entries(env) .filter((entry) => { return envPrefixExpr.test(entry[0]); }) .filter(isStringEntry) .map((entry) => { const match = entry[0].match(envPrefixExpr); (0, assertions_1.assert)(match, "cypress-cucumber-preprocessor: expected match after test, this is likely a bug."); return [(0, assertions_1.assertAndReturn)(match[1]), entry[1]]; }) .map((entry) => { return validateConfigurationEntry(entry[0].includes("_") ? (0, helpers_1.toCamelCase)(entry[0]) : entry[0], entry[1]); })); const cypressConfigPath = (0, path_helpers_1.ensureIsAbsolute)(projectPath, resolveConfigurationFile(options)); const configOrigin = Object.assign({}, ...Object.entries((_b = parseConfigurationFile(cypressConfigPath, (_a = options.parseDangerously) !== null && _a !== void 0 ? _a : false)[testingType]) !== null && _b !== void 0 ? _b : {}).map((entry) => validateConfigurationEntry(...entry))); const defaults = testingType === "e2e" ? { reporter: "spec", specPattern: "cypress/e2e/**/*.cy.{js,jsx,ts,tsx}", excludeSpecPattern: "*.hot-update.js", } : { reporter: "spec", specPattern: "**/*.cy.{js,jsx,ts,tsx}", excludeSpecPattern: ["/snapshots/*", "/image_snapshots/*"], }; const configuration = Object.assign(Object.assign({ testingType, projectRoot: (0, helpers_1.resolveProjectPath)(options), env: {} }, defaults), configOrigin, envOrigin, cliOrigin); (0, debug_1.default)(`resolved configuration of ${util_1.default.inspect(configuration)}`); return Object.assign(Object.assign({}, configuration), { env: resolvePre10Environment(Object.assign(Object.assign({}, options), { projectPath, configOrigin: configuration.env })) }); } exports.resolvePost10Configuration = resolvePost10Configuration; function resolvePre10Environment(options) { (0, debug_1.default)(`attempting to resolve Cypress environment using ${util_1.default.inspect(options)}`); const { argv, env, projectPath, configOrigin } = options; const envEntries = Array.from((0, helpers_1.combine)((0, helpers_1.traverseArgvMatching)(argv, "--env", true), (0, helpers_1.traverseArgvMatching)(argv, "-e", false))); if (envEntries.length > 1) { console.warn("You have specified -e / --env multiple times. This is likely a mistake, as only the last one will take affect. Multiple values should instead be comma-separated."); } const cliOrigin = Object.fromEntries(envEntries.slice(0, 1).flatMap((argument) => { const keypairExpr = /(?:^|,)([^=]+)=([^,$]+)/g; const entries = []; let match; while ((match = keypairExpr.exec(argument)) !== null) { entries.push([match[1], match[2]]); } return entries; })); const envPrefixExpr = /^cypress_(.+)/i; const envOrigin = Object.fromEntries(Object.entries(env) .filter((entry) => { return envPrefixExpr.test(entry[0]); }) .filter(isStringEntry) .map((entry) => { const match = entry[0].match(envPrefixExpr); (0, assertions_1.assert)(match, "expected match after test"); return [(0, assertions_1.assertAndReturn)(match[1]), entry[1]]; })); const cypressEnvironmentFilePath = path_1.default.join(projectPath, "cypress.env.json"); let cypressEnvOrigin = {}; if (fs_1.default.existsSync(cypressEnvironmentFilePath)) { const content = fs_1.default .readFileSync(cypressEnvironmentFilePath) .toString("utf8"); cypressEnvOrigin = JSON.parse(content); } const environment = Object.assign({}, cypressEnvOrigin, configOrigin, envOrigin, cliOrigin); (0, debug_1.default)(`resolved environment of ${util_1.default.inspect(environment)}`); return environment; } function resolveConfigurationFile(options) { const { argv } = options; return ((0, helpers_1.findArgumentValue)(argv, "--config-file", true) || (0, helpers_1.findArgumentValue)(argv, "-C", false) || findConfigurationInFS(options)); } function findConfigurationInFS(options) { const projectRoot = (0, helpers_1.resolveProjectPath)(options); const files = fs_1.default.readdirSync(projectRoot); const configFiles = files.filter((file) => exports.CONFIG_FILE_NAMES.includes(file)); if (configFiles.length === 0) { throw new errors_1.MissingConfigurationFileError("Unable to find a Cypress configuration file."); } else if (configFiles.length > 1) { throw new errors_1.MultipleConfigurationFilesError("Found multiple Cypress configuration files."); } return configFiles[0]; } function parseConfigurationFile(configFile, parseDangerously) { if (parseDangerously) { return parseConfigurationFileDangerously(configFile); } else { return (0, cypress_post10_configuration_parser_1.parsePost10Configuration)(fs_1.default.readFileSync(configFile).toString()); } } function parseConfigurationFileDangerously(configFile) { var _a; if (!fs_1.default.existsSync(configFile)) { throw new errors_1.MissingConfigurationFileError("Missing Cypress configuration file."); } const extension = path_1.default.extname(configFile); const transformer = (source, filename) => { if (filename !== configFile) { return source; } if ([".js", ".cjs"].includes(extension)) { return source; } else if (extension === ".mjs") { return esbuild.transformSync(source, { format: "cjs", }).code; } else if (extension === ".ts") { return esbuild.transformSync(source, { loader: "ts", format: "cjs", }).code; } else { throw new Error("Unknown extension " + extension); } }; node_hook_1.default.hook(extension, transformer); const result = require(configFile); node_hook_1.default.unhook(extension); return (_a = result.default) !== null && _a !== void 0 ? _a : result; } function resolvePost10TestFiles(configuration) { let { projectRoot, specPattern: specPatterns, excludeSpecPattern: excludeSpecPatterns, } = configuration; specPatterns = [specPatterns].flat(); excludeSpecPatterns = [excludeSpecPatterns] .flat() .concat("**/node_modules/**"); const globOptions = { absolute: true, nodir: true, cwd: projectRoot, ignore: excludeSpecPatterns, }; return specPatterns.flatMap((specPattern) => glob_1.default.sync(specPattern, globOptions)); } exports.resolvePost10TestFiles = resolvePost10TestFiles;