@mmisty/cypress-grep
Version:
Filters tests by tags/title using substring or regular expressions (can find dynamic tags)
236 lines (235 loc) • 9.18 kB
JavaScript
;
var _a;
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { execSync } = require('child_process');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { existsSync, rmSync, readFileSync } = require('fs');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const yargs = require('yargs');
const packagename = '[cypress-grep]';
const argv = yargs(process.argv.slice(2))
.options({
script: {
type: 'string',
default: 'npx cypress run',
demandOption: true,
describe: "script that runs tests. ex. 'npm run cy:run' or 'npx cypress run'",
alias: 's',
},
grep: {
type: 'string',
demandOption: false,
describe: 'grep - tags or test title (see docs https://www.npmjs.com/package/@mmisty/cypress-grep)',
alias: 'g',
},
'prefilter-file': {
type: 'string',
demandOption: true,
default: './filtered_tests.json',
describe: 'file where prefiltered results will be stored',
alias: 'p',
},
session: {
type: 'string',
default: 400000 + Math.round(Math.random() * 250000),
describe: 'seesion number (to not have conflicts with parallel runs), default random number',
alias: 'ss',
},
'only-prefilter': {
type: 'boolean',
default: false,
describe: 'only prefilter, no run - will prefilter tests and create file with results',
alias: 'f',
},
'only-run': {
type: 'boolean',
default: false,
describe: 'will run prefiltered tests from file specified by --prefilter-file or --p option ',
alias: 'r',
},
'delete-prefiltered': {
type: 'boolean',
default: true,
describe: 'whether to delete pre-filtered results file or keep',
alias: 'd',
},
'show-excluded-tests': {
// sets GREP_showExcludedTests
type: 'boolean',
default: undefined,
describe: 'show excluded tests as skipped or not show them at all (for not showing --no-show-excluded-tests or --not-e)',
alias: 'e',
},
'show-tags-title': {
// sets GREP_showTagsInTitle
type: 'boolean',
default: undefined,
describe: 'show tags in test title',
alias: 't',
},
})
.help('help')
.help('h')
.parseSync();
const { script: scriptInput, grep: grepInput, prefilterFile: prefilterFileInput, session: randomSession, deletePrefiltered, onlyPrefilter, onlyRun, showExcludedTests, showTagsTitle, } = argv;
const fileSpecPatternOriginal = `spec_pattern${randomSession}.json`;
let grep = !grepInput && process.env.CYPRESS_GREP ? process.env.CYPRESS_GREP : grepInput;
let script = Array.isArray(scriptInput) ? scriptInput[scriptInput.length - 1] : scriptInput;
let prefilterFile = Array.isArray(prefilterFileInput)
? prefilterFileInput[prefilterFileInput.length - 1]
: prefilterFileInput;
if (!onlyRun && prefilterFile.indexOf(randomSession) === -1) {
const extPos = `${prefilterFile}`.lastIndexOf('.');
const ext = prefilterFile.slice(extPos);
prefilterFile = `${prefilterFile.slice(0, extPos)}${randomSession}${ext}`;
}
const getGrepEnvVariableStr = grepInputT => {
if (grepInputT) {
return `CYPRESS_GREP='${grepInputT}'`;
}
return '';
};
/**
* Get original spec pattern
* @return {undefined|string|string[]}
*/
const getSpecPattern = file => {
const getRes = () => {
if (existsSync(file)) {
try {
return JSON.parse(readFileSync(file).toString()).specPattern;
}
catch (e) {
// ignore
}
}
return undefined;
};
const res = getRes();
try {
if (existsSync(fileSpecPatternOriginal)) {
rmSync(fileSpecPatternOriginal);
}
}
catch (e) {
// ignore
}
return res;
};
/**
* Get spec pattern env variable
*/
const getSpecPatternVar = (origSpecPattern, grepInputT, onlyRunInput) => {
if (origSpecPattern && !grepInputT) {
// when no grep need to run original spec pattern
return `CYPRESS_SPEC_PATTERN="[${origSpecPattern}]"`;
}
if (origSpecPattern && onlyRunInput) {
return `CYPRESS_SPEC_PATTERN="[${origSpecPattern}]"`;
}
if (!grepInputT) {
return '';
}
return 'CYPRESS_SPEC_PATTERN="[]"';
};
const execute = (vars, scriptInput) => {
const args = [...vars, scriptInput].filter(t => t !== '').join(' ');
console.log(`${packagename} execute: "${args}"`);
execSync(`${vars.filter(t => t !== '').join(' ')} ${scriptInput}`, { stdio: 'inherit', env: process.env });
};
try {
let grepExpression = getGrepEnvVariableStr(grep);
// console.log('grep: ' + (grepExpression || '-'));
// console.log('script: ' + script);
// console.log('prefilterFile: ' + (prefilterFile || '-'));
const started = Date.now();
let resultsFileEnvVariableStr = `CYPRESS_GREP_RESULTS_FILE='${prefilterFile}'`;
if (!onlyPrefilter && (onlyRun || !grep)) {
if (onlyRun && !existsSync(prefilterFile)) {
console.log(`${packagename} Will not run since no prefilter file found ${prefilterFile}`);
process.exit(0);
return;
}
if (!existsSync(prefilterFile) && !grep) {
console.log(`${packagename} Will run all tests: prefilter tests by adding \`--grep \` for faster filtering (for help \`cy-grep --help\`)`);
resultsFileEnvVariableStr = '';
}
else {
if (existsSync(prefilterFile)) {
// run all tests from prefiltered file or all
console.log(`${packagename} Will run tests from ${prefilterFile}`);
const existingGrep = grep;
try {
// update grep from prefiltered file
grep = JSON.parse(readFileSync(prefilterFile)).grep;
}
catch (e) {
console.log(`${packagename} Could not read/parse ${prefilterFile}: ${e.message}`);
}
if (existingGrep) {
grep = `(${grep}&(${existingGrep}))`;
}
grepExpression = getGrepEnvVariableStr(grep);
}
else {
resultsFileEnvVariableStr = '';
console.log(`${packagename} Will run without pre-filtering tests since file ${prefilterFile} doesn't exist\n` +
`${packagename} -> Prefilter tests for faster filtering first by adding --f (or removing --r) options`);
}
}
}
else {
console.log(`${packagename} PRE-FILTERING MODE ${onlyPrefilter ? 'only prefilter' : ''}=== `);
execute([
grepExpression,
resultsFileEnvVariableStr,
'CYPRESS_GREP_PRE_FILTER=true',
`CYPRESS_GREP_SESSION=${randomSession}`,
], script);
const prefilteringDuration = `${(Date.now() - started) / 1000}s`;
if (onlyPrefilter) {
console.log(`${packagename} FINISHED pre-filtering only (in ${prefilteringDuration}), results in ${prefilterFile}, to run execute with --r option === `);
process.exit(0);
}
else {
console.log(`${packagename} pre-filtering done in ${prefilteringDuration}`);
}
}
let specPattern = getSpecPattern(fileSpecPatternOriginal);
let specString = getSpecPatternVar(specPattern, grep, onlyRun);
if (process.env['CYPRESS_GREP_failOnNotFound'] === 'false') {
if (prefilterFile && existsSync(prefilterFile) && ((_a = JSON.parse(readFileSync(prefilterFile)).tests) === null || _a === void 0 ? void 0 : _a.length) === 0) {
console.log(`${packagename} Not found any specs matching ${grepExpression}`);
console.log(`${packagename} To throw error when not found set CYPRESS_GREP_failOnNotFound to true`);
console.log(`${packagename} FINISHED (exit code: 0) === `);
if (!onlyRun && !onlyPrefilter && deletePrefiltered && existsSync(prefilterFile)) {
rmSync(prefilterFile);
}
process.exit(0);
return;
}
}
console.log(`${packagename} Running tests === `);
// to use from cypress config when not set
const exclTests = showExcludedTests !== undefined ? `CYPRESS_GREP_showExcludedTests=${showExcludedTests === true}` : '';
const showTags = showTagsTitle !== undefined ? `CYPRESS_GREP_showTagsInTitle=${showTagsTitle === true}` : '';
execute([
grepExpression,
resultsFileEnvVariableStr,
'CYPRESS_GREP_PRE_FILTER=false',
`CYPRESS_GREP_SESSION=${randomSession}`,
specString,
exclTests,
showTags,
], script);
if (!onlyRun && !onlyPrefilter && deletePrefiltered && existsSync(prefilterFile)) {
rmSync(prefilterFile);
}
console.log(`${packagename} FINISHED === `);
}
catch (err) {
console.log(`${packagename} FINISHED (exit code: 1) === `);
// console.log(err);
process.exit(1);
}