UNPKG

@mmisty/cypress-grep

Version:

Filters tests by tags/title using substring or regular expressions (can find dynamic tags)

189 lines (188 loc) 8.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setupSelectTests = exports.prepareTestTitle = exports.origins = void 0; const functions_1 = require("../utils/functions"); const envVars_1 = require("../common/envVars"); const logs_1 = require("../common/logs"); const register_1 = require("@mmisty/cypress-tags/register"); const tags_1 = require("@mmisty/cypress-tags/utils/tags"); // todo rewrite // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types const origins = () => ({ originIt: it, originItOnly: it.only, originItSkip: it.skip, originDescribe: describe, originOnly: describe.only, originSkip: describe.skip, }); exports.origins = origins; // search by infoToo const tagsSearchLine = (allTags) => { const tagsLine = (tags) => tags.map(t => { var _a, _b; return (_b = t.tag + ((_a = t.info) === null || _a === void 0 ? void 0 : _a.map(x => x).join(''))) !== null && _b !== void 0 ? _b : ''; }).join(' '); return allTags.length > 0 ? ` ${tagsLine(allTags)}` : ''; }; const prepareTestTitle = (test) => { if (!test) { return 'null'; } return `${(0, tags_1.removeTagsFromTitle)(test.fullTitle())}${tagsSearchLine(test.tags || [])}`.replace(/\s\s*/g, ' '); }; exports.prepareTestTitle = prepareTestTitle; function filterTests(testRoot, suiteRoot, regexp, isPrerun, settings, onFilteredTest, onExcludedTest) { // Remove filtered tests and their parent suites suiteRoot.eachTest((test) => { const isEqualTitleWithTags = (t1, t2) => { const t1Full = (0, exports.prepareTestTitle)(t1); const t2Full = (0, exports.prepareTestTitle)(t2); return t1Full === t2Full; }; // when root test we filter suites again, so we don't need to filter other tests than the root if (testRoot && !isEqualTitleWithTags(testRoot, test)) { return; } const fullTitleWithTags = (0, exports.prepareTestTitle)(test); if (regexp.test(fullTitleWithTags)) { onFilteredTest(test); if (!isPrerun) { return; } } else { onExcludedTest(test); } // Remove not matched test if (test.parent) { if (!isPrerun && settings.showExcludedTests) { test.parent.tests.forEach(t => { if (isEqualTitleWithTags(t, test)) { t.pending = true; } }); } else { test.parent.tests = test.parent.tests.filter(t => !isEqualTitleWithTags(t, test)); } } // Remove empty parent suites recursively let suite = test.parent; while (suite && suite.tests.length === 0 && suite.suites.length === 0) { if (suite.parent) { suite.parent.suites = suite.parent.suites.filter(t => !isEqualTitleWithTags(t, suite)); } suite = suite.parent; } }); } const createOnExcluded = (isPrerun, list) => (test) => { var _a; list.push({ match: false, filteredTitle: (_a = (0, exports.prepareTestTitle)(test)) !== null && _a !== void 0 ? _a : '' }); }; const createOnFiltered = (isPrerun, list) => (test) => { var _a, _b, _c; if (!isPrerun) { list.push({ match: true, filteredTitle: (_a = (0, exports.prepareTestTitle)(test)) !== null && _a !== void 0 ? _a : '' }); return; } // titlePath has the title path generated by concatenating the parent's title path with the title. // 0 - is '' - root suite that is being created implicitly, 1 is what we need // 1 will contain path to spec file const filePath = (_b = test.titlePath()[1]) === null || _b === void 0 ? void 0 : _b.replace(/\/\/+/g, '/'); list.push({ match: true, filteredTitle: (_c = (0, exports.prepareTestTitle)(test)) !== null && _c !== void 0 ? _c : '', filePath, tags: test.tags, title: (0, tags_1.removeTagsFromTitle)(test.title), }); }; const createFilterSuiteTests = (settings, isPrerun, onCount) => /** * * @param regexp * @param filtered * @param suite * @param test - test when it is root */ (regexp, filtered, suite, test) => { filterTests(test, suite, regexp, isPrerun, settings, createOnFiltered(isPrerun, filtered), createOnExcluded(isPrerun, filtered)); const count = (0, functions_1.uniq)(filtered.filter(t => t.match).map(t => t.filteredTitle)).length; onCount(count); if (settings.debugLog) { const filteredUniq = (0, functions_1.uniq)(filtered.map(t => ` ${t.match ? ' + ' : ' - '}${t.filteredTitle}`)); const message = ['', `Filtered tests (${count})`, '', filteredUniq.join('\n')]; // eslint-disable-next-line no-console console.log(message.join('\n')); } }; const turnOffBeforeHook = () => { global.before = () => { // ignore }; }; const setupSelectTests = (selector, settings, onCount, isPrerun) => { var _a; const grep = (_a = Cypress.env(envVars_1.grepEnvVars.GREP)) !== null && _a !== void 0 ? _a : ''; if (settings.debugLog) { // eslint-disable-next-line no-console console.log(`${logs_1.pkgName} ----- Setup SELECT Tests --- ${selector().toString()} `); } if (isPrerun) { settings.showTagsInTitle = true; settings.showExcludedTests = false; // some tests uses visit in before turnOffBeforeHook(); } Cypress.env('cyTagsShowTagsInTitle', settings.showTagsInTitle); (0, register_1.registerTags)(); const originalSuites = (0, exports.origins)(); const filteredSuites = []; const filteredTests = []; const filterSuite = createFilterSuiteTests(settings, isPrerun, onCount); function itWithTags(...args) { var _a; const regexp = selector(); const test = originalSuites.originIt(...args); // for tests that doesn't have parent suite if (test.parent && test.parent.title === '' && !((_a = test.parent) === null || _a === void 0 ? void 0 : _a.parent)) { filterSuite(regexp, filteredTests, test.parent, test); } return test; } function descWithTags(...args) { const regexp = selector(); const suite = originalSuites.originDescribe(...args); if (suite && suite.parent && suite.parent.title === '' && !suite.parent.parent) { // this will run for every parent suite in file // current suite does not contain info about all suites before execution filterSuite(regexp, filteredSuites, suite); } return suite; } if (isPrerun && grep) { it(`${logs_1.pkgName} auto-generated test to write results`, () => { const uniqTests = (arr) => arr.filter((obj, index, self) => self.map(s => s.filteredTitle).indexOf(obj.filteredTitle) === index); const all = uniqTests([...filteredSuites, ...filteredTests]); const match = all.filter(t => t.match); const result = { total: all.length, filtered: match.length, grep, tests: match }; if (match.length === 0 && settings.failOnNotFound) { const msg = [ `Not found any tests matching ${envVars_1.grepEnvVars.GREP} '${grep}' satisfying specPattern ${Cypress.env('originalSpecPattern')}`, `To disable this error set environment variable \`${envVars_1.grepEnvVars.failOnNotFound}\` to false or set \`failOnNotFound\` to \`false\` in registerCypressGrep`, ]; throw new Error(msg.join('\n')); } // note: 'after' hook is not being called when there are no tests // when no tests filtered and failOnNotFound is false - // all tests would be executed after prerun since no file is created cy.task('writeTempFileWithSelectedTests', result); }); } global.describe = descWithTags; global.describe.only = originalSuites.originOnly; global.describe.skip = originalSuites.originSkip; global.it = itWithTags; global.it.only = originalSuites.originItOnly; global.it.skip = originalSuites.originItSkip; }; exports.setupSelectTests = setupSelectTests;