Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions src/lib/frameworks/markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
* Expected format:
* - HTML comment with YAML-like metadata for suite: <!-- suite\nid: @S123\n-->
* - Level 1 heading (#) for suite title
* - HTML comment with YAML-like metadata for test: <!-- test\nid: @T456\npriority: high\n-->
* - HTML comment with YAML-like metadata for test: <!-- test\nid: @T456\n...\n-->
* - `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 = '') => {
Expand Down Expand Up @@ -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
Expand All @@ -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++;
Expand Down
82 changes: 82 additions & 0 deletions tests/manual_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
id: @S1
-->
# Suite

<!-- test
id: @T1
tags: smoke , critical
-->

## 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 = `<!-- suite
id: @S1
-->
# S

<!-- test
tags:
-->
## 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 = `<!-- suite
id: @S1
-->
# S

<!-- test
tags: smoke
-->
## 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 = `<!-- suite
id: @S1
-->
# S

<!-- test
labels: beta , qa-team
-->

## 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 = `<!-- suite
id: @S1
-->
# S

<!-- test
labels:
-->

## L
`;
const tests = markdownParser(null, 'empty-labels.test.md', md);
expect(tests[0].labels).to.deep.equal([]);
});
});
});
102 changes: 99 additions & 3 deletions tests/updateIds_markdown_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
});

Expand Down Expand Up @@ -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 -->
## Test A

Step.`;
const contentB = `<!-- test -->
## 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 -->
## Test A

Step.`;
const contentB = `<!-- test -->
## 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', () => {
Expand Down Expand Up @@ -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
id: @T11111111
-->
## Test A

Step.`;
const contentB = `<!-- test
id: @T22222222
-->
## 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');
});
});
});
Loading