@mmisty/cypress-grep
Version:
Filters tests by tags/title using substring or regular expressions (can find dynamic tags)
194 lines (193 loc) • 9.17 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;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.pluginGrep = void 0;
const fs_1 = require("fs");
const all_tests_combine_1 = require("./all-tests-combine");
const utils_1 = require("./utils");
const functions_1 = require("../utils/functions");
const tasks_1 = require("./tasks");
const envVars_1 = require("../common/envVars");
const path_1 = __importStar(require("path"));
const logs_1 = require("../common/logs");
const defaultSpecPattern = 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}';
const parentFolder = (specPattern, config) => {
if (config.parentTestsFolder) {
return config.parentTestsFolder;
}
if (config.env[envVars_1.grepEnvVars.GREP_TESTS_FOLDER] &&
(0, fs_1.existsSync)(path_1.default.resolve(config.env[envVars_1.grepEnvVars.GREP_TESTS_FOLDER]))) {
return config.env[envVars_1.grepEnvVars.GREP_TESTS_FOLDER];
}
console.log(`${logs_1.pkgName} parent tests folder will be detected automatically. ` +
`You can set '${envVars_1.grepEnvVars.GREP_TESTS_FOLDER}' env var with relative path to project root `);
return (0, utils_1.getRootFolder)(specPattern, config.projectRoot);
};
const onAfterRunDelete = (on, filePath) => {
// check whether this will be overridden
on('after:run', () => {
if ((0, fs_1.existsSync)(filePath)) {
console.log(`${logs_1.pkgName} deleting ${filePath}`);
(0, fs_1.rmSync)(filePath);
}
});
};
const lastUpdatedDate = (file) => {
const { mtime } = (0, fs_1.statSync)(file);
return mtime;
};
const warningWhenFilteredResultExistMore = (timeExistMin, filteredSpecs) => {
const ms = timeExistMin * 1000 * 60;
const updated = lastUpdatedDate(filteredSpecs);
const duration = Date.now() - updated.getTime();
if (duration > ms) {
const messsage = [
`${logs_1.pkgName} File with filtered tests exist more than ${timeExistMin}min,` +
' will filter tests basing on the result from it',
`${logs_1.pkgName} Delete file '${filteredSpecs}' if you want to filter from all`,
];
console.warn(messsage.join('\n'));
}
};
const warningNoResultsFileNoGrep = (grep) => {
if (grep) {
console.warn(`${logs_1.pkgName} to run prefiltered tests use env var ${envVars_1.grepEnvVars.GREP_PRE_FILTER}=true` +
`\n${logs_1.pkgName} This time will filter tests one by one by ${envVars_1.grepEnvVars.GREP}='${grep}'.`);
}
};
/**
* This will add prefiltering capabilities and speed up the execution
* of tests when utilizing grep
* */
const pluginGrep = (on, config) => {
var _a, _b, _c, _d;
const specPattern = config.specPattern || defaultSpecPattern;
config.env['originalSpecPattern'] = specPattern;
const parentTestsFolder = parentFolder(specPattern, config);
const isPreFilter = (0, envVars_1.isTrue)((_a = config.env[envVars_1.grepEnvVars.GREP_PRE_FILTER]) !== null && _a !== void 0 ? _a : false);
const isDeleteAllFile = (0, envVars_1.isTrue)((_b = config.env[envVars_1.grepEnvVars.GREP_DELETE_ALL_FILE]) !== null && _b !== void 0 ? _b : true);
const grep = config.env[envVars_1.grepEnvVars.GREP];
const randomSession = config.env[envVars_1.grepEnvVars.GREP_SESSION];
const filteredSpecs = (_c = config.env[envVars_1.grepEnvVars.GREP_RESULTS_FILE]) !== null && _c !== void 0 ? _c : `${config.projectRoot}/filtered_test_paths${randomSession}.json`;
const allFileName = (_d = config.env[envVars_1.grepEnvVars.GREP_ALL_TESTS_NAME]) !== null && _d !== void 0 ? _d : `all-tests${randomSession}.js`;
const allTestsFile = `${parentTestsFolder}/${allFileName}`;
on('task', (0, tasks_1.taskWrite)(config, parentTestsFolder, filteredSpecs));
console.log(`${logs_1.pkgName} grep: ${grep !== null && grep !== void 0 ? grep : 'not set'}`);
console.log(`${logs_1.pkgName} parent tests folder: '${parentTestsFolder}'`);
console.log(`${logs_1.pkgName} grep: session number ${randomSession}`);
if (!(0, fs_1.existsSync)((0, path_1.dirname)(filteredSpecs))) {
(0, fs_1.mkdirSync)((0, path_1.dirname)(filteredSpecs), { recursive: true });
}
if (!isPreFilter) {
if (!(0, fs_1.existsSync)(filteredSpecs)) {
warningNoResultsFileNoGrep(config.env[envVars_1.grepEnvVars.GREP]);
// todo make option to exist early here when not found
return;
}
let filteredSpecsResult = {};
try {
filteredSpecsResult = JSON.parse((0, fs_1.readFileSync)(filteredSpecs).toString());
config.env['filteredSpecsResult'] = filteredSpecsResult;
}
catch (_e) {
// ignore
}
warningWhenFilteredResultExistMore(1, filteredSpecs);
updateSpecPattern(specPattern, config, filteredSpecs);
return;
}
(0, fs_1.writeFileSync)(`spec_pattern${randomSession}.json`, JSON.stringify({ specPattern: specPattern }));
config.reporter = 'spec';
config.video = false;
config.env['REDIRECT_BROWSER_LOG'] = false;
if ((0, fs_1.existsSync)(filteredSpecs)) {
(0, fs_1.rmSync)(filteredSpecs);
}
if (!grep) {
// exit early to normal run
console.warn(`${logs_1.pkgName} to prefilter specs specify env var GREP. Now will select all tests`);
// cannot set cypress to exit early
// so just go through one auto generated spec to speed up (will be skipped anyway)
(0, all_tests_combine_1.createOneTestsFile)(allTestsFile);
config.specPattern = `${allTestsFile}`;
onAfterRunDelete(on, allTestsFile);
return;
}
// create all tests file
const file = (0, all_tests_combine_1.createAllTestsFile)(allTestsFile, parentTestsFolder, specPattern);
changeSpecPatternOneFile(config, file);
if (isDeleteAllFile) {
onAfterRunDelete(on, allTestsFile);
}
};
exports.pluginGrep = pluginGrep;
const changeSpecsForRun = (specPattern, config, newValue) => {
const specs = typeof newValue === 'string' ? [newValue] : newValue.map(t => t);
const specsNew = specs.map(s => ({
name: path_1.default.basename(s),
relative: s,
absolute: path_1.default.resolve(config.projectRoot, s),
}));
config.specPattern = specsNew.map(t => t.relative);
console.log(`${logs_1.pkgName} Spec Pattern: ${config.specPattern}`);
};
const changeSpecPatternOneFile = (config, newValue) => {
config.specPattern = newValue;
console.log(`${logs_1.pkgName} New specs Pattern is now: ${config.specPattern}`);
};
const parsePrefilteredSpecs = (filteredSpecs) => {
const testsJson = (0, fs_1.readFileSync)(filteredSpecs);
try {
return JSON.parse(testsJson.toString());
}
catch (e) {
throw new Error(`${logs_1.pkgName} could not parse '${filteredSpecs}'`);
}
};
const updateSpecPattern = (specPattern, config, filteredSpecs) => {
const testParsed = parsePrefilteredSpecs(filteredSpecs);
// todo setting parent test folder
const uniqPaths = (0, functions_1.uniq)(testParsed.tests.map(f => {
var _a;
if ((0, fs_1.existsSync)(path_1.default.resolve(f.filePath))) {
return f.filePath;
}
const pathTest = path_1.default.join((_a = testParsed.parentFolder) !== null && _a !== void 0 ? _a : '', f.filePath);
if ((0, fs_1.existsSync)(path_1.default.resolve(pathTest))) {
return path_1.default.resolve(pathTest);
}
throw new Error(`${logs_1.pkgName} could not find '${f.filePath}' or '${pathTest}' `);
}));
if (uniqPaths.length === 0) {
console.warn(`${logs_1.pkgName} Not found any tests with ` +
`grep='${config.env[envVars_1.grepEnvVars.GREP]}' and specPattern='${JSON.stringify(specPattern)}'`);
}
else {
const specsCount = `specs files: ${uniqPaths.length} with total tests: ${testParsed.tests.length}`;
const message = [`${logs_1.pkgName} Pre-filtered spec files for grep '${testParsed.grep}': ${specsCount}`];
console.info(message.join('\n'));
}
changeSpecsForRun(specPattern, config, uniqPaths);
};