@badeball/cypress-configuration
Version:
[](https://github.com/badeball/cypress-configuration/actions/workflows/build.yml) [ • 11.2 kB
JavaScript
;
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;