Mocha/Cypress Test Name and Tag Extractor
The `find-test-names-tags` package, currently at stable version 1.0.4, is a utility designed for parsing JavaScript test files, specifically those written for Mocha and Cypress frameworks. Its primary function is to extract comprehensive information about test suites and individual test cases, including their names and any associated tags. A significant feature is its ability to compute "effective tags" for each test, which involves aggregating tags from the test itself and its parent suites. This allows for powerful filtering capabilities, enabling users to isolate tests based on specific tags or combinations thereof. The package also provides command-line interfaces for printing structured test outlines, including marking pending tests and displaying their tags. While a precise release cadence isn't specified, the package appears to be actively maintained and developed. It stands out by offering fine-grained control over test metadata extraction and analysis, making it valuable for dynamic test reporting, selective test execution in CI/CD pipelines, or building custom test dashboards. It effectively bridges the gap between raw test code and actionable test metadata.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'structure')
cause This error typically occurs when trying to access `result.structure` after calling `getTestNames()` without the `true` argument, which means the `structure` property was not populated.fixEnsure you call `const result = getTestNames(specSourceCode, true)` to correctly populate the `structure` property. -
TypeError: getTestNames is not a function
cause This indicates an incorrect import statement. The package primarily uses CommonJS named exports, and attempting to use an ESM `import` or an incorrect `require` pattern will lead to this error.fixUse the CommonJS destructuring assignment: `const { getTestNames } = require('find-test-names-tags')`.
Warnings
- gotcha When `getTestNames` encounters test names defined by variables instead of literal strings, it will extract and process them, but the name in the output will be reported as `<unknown test>`.
- gotcha To utilize functions like `setEffectiveTags` and access the nested test structure, you *must* pass `true` as the second argument to `getTestNames`. Omitting this argument returns a flat list of names, lacking the hierarchical structure required for tag propagation.
Install
-
npm install find-test-names-tags -
yarn add find-test-names-tags -
pnpm add find-test-names-tags
Imports
- getTestNames
import { getTestNames } from 'find-test-names-tags'const { getTestNames } = require('find-test-names-tags') - setEffectiveTags
import { setEffectiveTags } from 'find-test-names-tags'const { setEffectiveTags } = require('find-test-names-tags') - filterByEffectiveTags
import { filterByEffectiveTags } from 'find-test-names-tags'const { filterByEffectiveTags } = require('find-test-names-tags')
Quickstart
const specSourceCode = `
describe(['@user'], 'User Features', () => {
describe(['@auth'], 'Authentication', () => {
it(['@smoke'], 'should allow login', () => {
// test implementation
});
it(['@regression', '@critical'], 'should handle failed login attempts', () => {
// test implementation
});
});
describe('Profile', () => {
const dynamicName = 'should update profile';
it(dynamicName, () => {
// test implementation
});
});
});
`;
const { getTestNames, setEffectiveTags, filterByEffectiveTags } = require('find-test-names-tags');
// Get the full test structure (important: pass true for structure)
const result = getTestNames(specSourceCode, true);
console.log('Parsed structure root keys:', Object.keys(result));
// Compute effective tags for each test within the structure
setEffectiveTags(result.structure);
console.log('Effective tags for "should allow login":', result.structure[0].suites[0].tests[0].effectiveTags);
// Filter tests by effective tags (e.g., find all smoke tests)
const smokeTests = filterByEffectiveTags(result.structure, ['@smoke'], []);
console.log('Found smoke tests:', smokeTests.map(t => t.name));
// Filter by multiple tags, excluding others (e.g., regression but not critical)
const regressionExcludingCritical = filterByEffectiveTags(specSourceCode, ['@regression'], ['@critical']);
console.log('Regression tests (excluding critical):', regressionExcludingCritical.map(t => t.name));