diff --git a/src/lib/frameworks/markdown.js b/src/lib/frameworks/markdown.js index ff7786b8..3576abab 100644 --- a/src/lib/frameworks/markdown.js +++ b/src/lib/frameworks/markdown.js @@ -3,7 +3,8 @@ * Expected format: * - HTML comment with YAML-like metadata for suite: * - Level 1 heading (#) for suite title - * - HTML comment with YAML-like metadata for test: + * - HTML comment with YAML-like metadata for test: + * - `tags` and `labels`: comma-separated lists normalized to trimmed string arrays; all other metadata values stay plain strings * - Level 2 heading (##) for test title */ module.exports = (ast, file = '', source = '') => { @@ -82,6 +83,22 @@ module.exports = (ast, file = '', source = '') => { return tests; }; +/** Metadata keys parsed as comma-separated lists (same rules for each). */ +const COMMA_SEPARATED_LIST_KEYS = new Set(['tags', 'labels']); + +/** + * Comma-separated list; trim each segment; drop empties. + * @param {string} value + * @returns {string[]} + */ +function parseCommaSeparatedList(value) { + if (!value) return []; + return value + .split(',') + .map(t => t.trim()) + .filter(Boolean); +} + /** * Parse metadata block from HTML comment * Returns the parsed data and the end index @@ -108,7 +125,7 @@ function parseMetadataBlock(lines, startIndex) { if (match) { const key = match[1].trim(); const value = match[2].trim(); - metadata[key] = value; + metadata[key] = COMMA_SEPARATED_LIST_KEYS.has(key) ? parseCommaSeparatedList(value) : value; } i++; diff --git a/tests/manual_test.js b/tests/manual_test.js index dfdd1b13..2d51db60 100644 --- a/tests/manual_test.js +++ b/tests/manual_test.js @@ -132,4 +132,86 @@ describe('manual (markdown) parser', () => { expect(testB1.suites).to.include('Suite B @S00000001'); }); }); + + context('tags / labels comma-separated metadata (arrays)', () => { + it('should split tags by comma, trim segments', () => { + const md = ` +# Suite + + + +## Case +`; + const tests = markdownParser(null, 'tags.test.md', md); + expect(tests).to.have.length(1); + expect(tests[0].tags).to.deep.equal(['smoke', 'critical']); + }); + + it('should yield empty array when tags key has no values', () => { + const md = ` +# S + + +## T +`; + const tests = markdownParser(null, 'empty-tags.test.md', md); + expect(tests[0].tags).to.deep.equal([]); + }); + + it('should parse single tag without comma', () => { + const md = ` +# S + + +## T +`; + const tests = markdownParser(null, 'single-tag.test.md', md); + expect(tests[0].tags).to.deep.equal(['smoke']); + }); + + it('should parse labels like tags (comma split, trim)', () => { + const md = ` +# S + + + +## L +`; + const tests = markdownParser(null, 'labels.test.md', md); + expect(tests[0].labels).to.deep.equal(['beta', 'qa-team']); + }); + + it('should yield empty labels array when empty value', () => { + const md = ` +# S + + + +## L +`; + const tests = markdownParser(null, 'empty-labels.test.md', md); + expect(tests[0].labels).to.deep.equal([]); + }); + }); }); diff --git a/tests/updateIds_markdown_test.js b/tests/updateIds_markdown_test.js index 1b1db26d..8b7fe9ae 100644 --- a/tests/updateIds_markdown_test.js +++ b/tests/updateIds_markdown_test.js @@ -5,11 +5,15 @@ const { updateIdsMarkdown, cleanIdsMarkdown } = require('../src/updateIds/update describe('updateIds markdown', () => { const testFile = path.join(__dirname, 'temp-test.md'); + const testFileA = path.join(__dirname, 'temp-test-a.md'); + const testFileB = path.join(__dirname, 'temp-test-b.md'); afterEach(() => { - // Clean up test file - if (fs.existsSync(testFile)) { - fs.unlinkSync(testFile); + // Clean up test files + for (const f of [testFile, testFileA, testFileB]) { + if (fs.existsSync(f)) { + fs.unlinkSync(f); + } } }); @@ -285,6 +289,69 @@ User should be able to login.`; const updatedContent = fs.readFileSync(testFile, 'utf8'); expect(updatedContent).to.not.include('@T12345678'); }); + + it('should accept an array of patterns and update every matched file', () => { + const contentA = ` +## Test A + +Step.`; + const contentB = ` +## Test B + +Step.`; + + fs.writeFileSync(testFileA, contentA); + fs.writeFileSync(testFileB, contentB); + + const testomatioMap = { + tests: { + 'Test A': '@T11111111', + 'Test B': '@T22222222', + }, + suites: {}, + }; + + const result = updateIdsMarkdown(testomatioMap, __dirname, { + pattern: ['temp-test-a.md', 'temp-test-b.md'], + }); + + const resolved = result.map(f => path.resolve(f)); + expect(resolved).to.include(path.resolve(testFileA)); + expect(resolved).to.include(path.resolve(testFileB)); + + expect(fs.readFileSync(testFileA, 'utf8')).to.include('id: @T11111111'); + expect(fs.readFileSync(testFileB, 'utf8')).to.include('id: @T22222222'); + }); + + it('should accept an array of glob patterns', () => { + const contentA = ` +## Test A + +Step.`; + const contentB = ` +## Test B + +Step.`; + + fs.writeFileSync(testFileA, contentA); + fs.writeFileSync(testFileB, contentB); + + const testomatioMap = { + tests: { + 'Test A': '@T11111111', + 'Test B': '@T22222222', + }, + suites: {}, + }; + + const result = updateIdsMarkdown(testomatioMap, __dirname, { + pattern: ['temp-test-a.md', 'temp-test-*.md'], + }); + + const resolved = result.map(f => path.resolve(f)); + expect(resolved).to.include(path.resolve(testFileA)); + expect(resolved).to.include(path.resolve(testFileB)); + }); }); describe('cleanIdsMarkdown', () => { @@ -333,5 +400,34 @@ User should be able to login.`; expect(updatedContent).to.not.include('id: @S87654321'); expect(updatedContent).to.include('priority: high'); }); + + it('should accept an array of patterns', () => { + const contentA = ` +## Test A + +Step.`; + const contentB = ` +## Test B + +Step.`; + + fs.writeFileSync(testFileA, contentA); + fs.writeFileSync(testFileB, contentB); + + const result = cleanIdsMarkdown({}, __dirname, { + pattern: ['temp-test-a.md', 'temp-test-b.md'], + }); + + const resolved = result.map(f => path.resolve(f)); + expect(resolved).to.include(path.resolve(testFileA)); + expect(resolved).to.include(path.resolve(testFileB)); + + expect(fs.readFileSync(testFileA, 'utf8')).to.not.include('@T11111111'); + expect(fs.readFileSync(testFileB, 'utf8')).to.not.include('@T22222222'); + }); }); });