Skip to content

Commit fdb86b4

Browse files
committed
chore: bump version to 2.1.7 and add support for QaseParameters and QaseGroupParameters
- Updated package version from 2.1.6 to 2.1.7 in package.json. - Added support for QaseParameters and QaseGroupParameters tags in the storage logic. - Enhanced test cases to validate the inclusion of parameters from these tags in test results. - Updated changelog to reflect the new version and features. These changes improve the functionality of the reporter by allowing users to specify parameters directly in their test tags.
1 parent 525d729 commit fdb86b4

File tree

5 files changed

+287
-6
lines changed

5 files changed

+287
-6
lines changed

qase-cucumberjs/changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2+
3+
## What's new
4+
5+
- Added support for QaseParameters and QaseGroupParameters tags.
6+
17
28

39
## Bug fixes

qase-cucumberjs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cucumberjs-qase-reporter",
3-
"version": "2.1.6",
3+
"version": "2.1.7",
44
"description": "Qase TMS CucumberJS Reporter",
55
"homepage": "https://github.com/qase-tms/qase-javascript",
66
"main": "./dist/index.js",
@@ -40,7 +40,7 @@
4040
"license": "Apache-2.0",
4141
"dependencies": {
4242
"@cucumber/messages": "^22.0.0",
43-
"qase-javascript-commons": "~2.4.10"
43+
"qase-javascript-commons": "~2.4.16"
4444
},
4545
"peerDependencies": {
4646
"@cucumber/cucumber": ">=7.0.0"

qase-cucumberjs/src/models.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ export interface TestMetadata {
33
fields: Record<string, string>;
44
title: string | null;
55
isIgnore: boolean;
6+
parameters: Record<string, string>;
7+
group_params: Record<string, string>;
68
}
79

810
export interface ScenarioData {

qase-cucumberjs/src/storage.ts

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ const qaseIdRegExp = /^@[Qq]-?(\d+)$/;
3131
const newQaseIdRegExp = /^@[Qq]ase[Ii][Dd]=(\d+(?:,\s*\d+)*)$/;
3232
const qaseTitleRegExp = /^@[Qq]ase[Tt]itle=(.+)$/;
3333
const qaseFieldsRegExp = /^@[Qq]ase[Ff]ields=(.+)$/;
34+
const qaseParametersRegExp = /^@[Qq]ase[Pp]arameters=(.+)$/;
35+
const qaseGroupParametersRegExp = /^@[Qq]ase[Gg]roup[Pp]arameters=(.+)$/;
3436
const qaseIgnoreRegExp = /^@[Qq]ase[Ii][Gg][Nn][Oo][Rr][Ee]$/;
3537

3638
export class Storage {
@@ -278,6 +280,10 @@ export class Storage {
278280
}
279281
}
280282

283+
// Merge parameters from tags with parameters from Gherkin examples
284+
// Parameters from tags take precedence over Gherkin examples
285+
params = { ...params, ...metadata.parameters };
286+
281287
const steps = this.convertSteps(pickle.steps, tc);
282288

283289
return {
@@ -295,10 +301,10 @@ export class Storage {
295301
message: error?.message ?? null,
296302
muted: false,
297303
params: params,
298-
group_params: {},
304+
group_params: metadata.group_params,
299305
relations: relations,
300306
run_id: null,
301-
signature: this.getSignature(pickle, metadata.ids),
307+
signature: this.getSignature(pickle, metadata.ids, params),
302308
steps: steps,
303309
testops_id: metadata.ids.length > 0 ? metadata.ids : null,
304310
id: tcs.id,
@@ -386,6 +392,8 @@ export class Storage {
386392
fields: {},
387393
title: null,
388394
isIgnore: false,
395+
parameters: {},
396+
group_params: {},
389397
};
390398

391399
for (const tag of tags) {
@@ -415,6 +423,28 @@ export class Storage {
415423
}
416424
}
417425

426+
if (qaseParametersRegExp.test(tag.name)) {
427+
const value = tag.name.replace(/^@[Qq]ase[Pp]arameters=/, '');
428+
try {
429+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
430+
const record: Record<string, string> = JSON.parse(value);
431+
metadata.parameters = { ...metadata.parameters, ...record };
432+
} catch (e) {
433+
// do nothing
434+
}
435+
}
436+
437+
if (qaseGroupParametersRegExp.test(tag.name)) {
438+
const value = tag.name.replace(/^@[Qq]ase[Gg]roup[Pp]arameters=/, '');
439+
try {
440+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
441+
const record: Record<string, string> = JSON.parse(value);
442+
metadata.group_params = { ...metadata.group_params, ...record };
443+
} catch (e) {
444+
// do nothing
445+
}
446+
}
447+
418448
if (qaseIgnoreRegExp.test(tag.name)) {
419449
metadata.isIgnore = true;
420450
}
@@ -426,10 +456,11 @@ export class Storage {
426456
/**
427457
* @param {Pickle} pickle
428458
* @param {number[]} ids
459+
* @param {Record<string, string>} parameters
429460
* @private
430461
*/
431-
private getSignature(pickle: Pickle, ids: number[]): string {
432-
return generateSignature(ids, [...pickle.uri.split('/'), pickle.name], {});
462+
private getSignature(pickle: Pickle, ids: number[], parameters: Record<string, string> = {}): string {
463+
return generateSignature(ids, [...pickle.uri.split('/'), pickle.name], parameters);
433464
}
434465

435466
private getError(testCaseId: string): CompoundError | undefined {

qase-cucumberjs/test/storage.test.ts

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,185 @@ describe('Storage', () => {
343343
const result = storage.convertTestCase(testCaseFinished);
344344
expect(result).toBeUndefined();
345345
});
346+
347+
it('should include parameters from QaseParameters tag in test result', () => {
348+
const pickle: Pickle = {
349+
id: 'pickle-1',
350+
name: 'Test Pickle',
351+
language: 'en',
352+
steps: [],
353+
tags: [
354+
{ name: '@QaseParameters={"browser":"chrome","environment":"staging"}' },
355+
],
356+
astNodeIds: [],
357+
uri: 'test.feature'
358+
};
359+
storage.addPickle(pickle);
360+
361+
const testCase: TestCase = {
362+
id: 'case-1',
363+
testSteps: [],
364+
pickleId: 'pickle-1'
365+
};
366+
storage.addTestCase(testCase);
367+
368+
const testCaseStarted: TestCaseStarted = {
369+
id: 'started-1',
370+
testCaseId: 'case-1',
371+
timestamp: { seconds: 0, nanos: 0 },
372+
attempt: 1
373+
};
374+
storage.addTestCaseStarted(testCaseStarted);
375+
376+
const testCaseFinished: TestCaseFinished = {
377+
testCaseStartedId: 'started-1',
378+
timestamp: { seconds: 1, nanos: 0 },
379+
willBeRetried: false,
380+
};
381+
382+
const result = storage.convertTestCase(testCaseFinished);
383+
384+
expect(result).toBeDefined();
385+
if (result) {
386+
expect(result.params).toEqual({ browser: 'chrome', environment: 'staging' });
387+
}
388+
});
389+
390+
it('should include group_params from QaseGroupParameters tag in test result', () => {
391+
const pickle: Pickle = {
392+
id: 'pickle-1',
393+
name: 'Test Pickle',
394+
language: 'en',
395+
steps: [],
396+
tags: [
397+
{ name: '@QaseGroupParameters={"test_group":"authentication","test_type":"smoke"}' },
398+
],
399+
astNodeIds: [],
400+
uri: 'test.feature'
401+
};
402+
storage.addPickle(pickle);
403+
404+
const testCase: TestCase = {
405+
id: 'case-1',
406+
testSteps: [],
407+
pickleId: 'pickle-1'
408+
};
409+
storage.addTestCase(testCase);
410+
411+
const testCaseStarted: TestCaseStarted = {
412+
id: 'started-1',
413+
testCaseId: 'case-1',
414+
timestamp: { seconds: 0, nanos: 0 },
415+
attempt: 1
416+
};
417+
storage.addTestCaseStarted(testCaseStarted);
418+
419+
const testCaseFinished: TestCaseFinished = {
420+
testCaseStartedId: 'started-1',
421+
timestamp: { seconds: 1, nanos: 0 },
422+
willBeRetried: false,
423+
};
424+
425+
const result = storage.convertTestCase(testCaseFinished);
426+
427+
expect(result).toBeDefined();
428+
if (result) {
429+
expect(result.group_params).toEqual({ test_group: 'authentication', test_type: 'smoke' });
430+
}
431+
});
432+
433+
it('should merge parameters from tags with parameters from Gherkin examples', () => {
434+
const document: GherkinDocument = {
435+
uri: 'test.feature',
436+
feature: {
437+
location: { line: 1, column: 1 },
438+
language: 'en',
439+
keyword: 'Feature',
440+
name: 'Test Feature',
441+
description: '',
442+
children: [
443+
{
444+
scenario: {
445+
id: 'scenario-1',
446+
location: { line: 2, column: 1 },
447+
keyword: 'Scenario',
448+
name: 'Test Scenario',
449+
description: '',
450+
steps: [],
451+
tags: [],
452+
examples: [
453+
{
454+
id: 'examples-1',
455+
location: { line: 3, column: 1 },
456+
keyword: 'Examples',
457+
name: '',
458+
description: '',
459+
tags: [],
460+
tableHeader: {
461+
id: 'header-1',
462+
location: { line: 4, column: 1 },
463+
cells: [{ location: { line: 4, column: 1 }, value: 'param1' }],
464+
},
465+
tableBody: [
466+
{
467+
id: 'row-1',
468+
location: { line: 5, column: 1 },
469+
cells: [{ location: { line: 5, column: 1 }, value: 'value1' }],
470+
},
471+
],
472+
},
473+
],
474+
},
475+
},
476+
],
477+
tags: [],
478+
},
479+
comments: [],
480+
};
481+
storage.addScenario(document);
482+
483+
const pickle: Pickle = {
484+
id: 'pickle-1',
485+
name: 'Test Pickle',
486+
language: 'en',
487+
steps: [],
488+
tags: [
489+
{ name: '@QaseParameters={"param2":"value2"}' },
490+
],
491+
astNodeIds: ['scenario-1', 'row-1'],
492+
uri: 'test.feature'
493+
};
494+
storage.addPickle(pickle);
495+
496+
const testCase: TestCase = {
497+
id: 'case-1',
498+
testSteps: [],
499+
pickleId: 'pickle-1'
500+
};
501+
storage.addTestCase(testCase);
502+
503+
const testCaseStarted: TestCaseStarted = {
504+
id: 'started-1',
505+
testCaseId: 'case-1',
506+
timestamp: { seconds: 0, nanos: 0 },
507+
attempt: 1
508+
};
509+
storage.addTestCaseStarted(testCaseStarted);
510+
511+
const testCaseFinished: TestCaseFinished = {
512+
testCaseStartedId: 'started-1',
513+
timestamp: { seconds: 1, nanos: 0 },
514+
willBeRetried: false,
515+
};
516+
517+
const result = storage.convertTestCase(testCaseFinished);
518+
519+
expect(result).toBeDefined();
520+
if (result) {
521+
// Parameters from tags should merge with parameters from Gherkin examples
522+
expect(result.params).toEqual({ param1: 'value1', param2: 'value2' });
523+
}
524+
});
346525
});
347526

348527
describe('private methods', () => {
@@ -382,6 +561,69 @@ describe('Storage', () => {
382561
expect(result.fields).toEqual({});
383562
});
384563

564+
it('should parse QaseParameters tag', () => {
565+
const tags = [
566+
{ name: '@QaseParameters={"browser":"chrome","environment":"staging"}' },
567+
];
568+
569+
const result = (storage as any).parseTags(tags);
570+
571+
expect(result.parameters).toEqual({ browser: 'chrome', environment: 'staging' });
572+
});
573+
574+
it('should parse QaseGroupParameters tag', () => {
575+
const tags = [
576+
{ name: '@QaseGroupParameters={"test_group":"authentication","test_type":"smoke"}' },
577+
];
578+
579+
const result = (storage as any).parseTags(tags);
580+
581+
expect(result.group_params).toEqual({ test_group: 'authentication', test_type: 'smoke' });
582+
});
583+
584+
it('should parse both QaseParameters and QaseGroupParameters', () => {
585+
const tags = [
586+
{ name: '@QaseParameters={"browser":"chrome"}' },
587+
{ name: '@QaseGroupParameters={"test_group":"authentication"}' },
588+
];
589+
590+
const result = (storage as any).parseTags(tags);
591+
592+
expect(result.parameters).toEqual({ browser: 'chrome' });
593+
expect(result.group_params).toEqual({ test_group: 'authentication' });
594+
});
595+
596+
it('should handle invalid JSON in parameters', () => {
597+
const tags = [
598+
{ name: '@QaseParameters=invalid json' },
599+
];
600+
601+
const result = (storage as any).parseTags(tags);
602+
603+
expect(result.parameters).toEqual({});
604+
});
605+
606+
it('should handle invalid JSON in group parameters', () => {
607+
const tags = [
608+
{ name: '@QaseGroupParameters=invalid json' },
609+
];
610+
611+
const result = (storage as any).parseTags(tags);
612+
613+
expect(result.group_params).toEqual({});
614+
});
615+
616+
it('should merge multiple QaseParameters tags', () => {
617+
const tags = [
618+
{ name: '@QaseParameters={"browser":"chrome"}' },
619+
{ name: '@QaseParameters={"environment":"staging"}' },
620+
];
621+
622+
const result = (storage as any).parseTags(tags);
623+
624+
expect(result.parameters).toEqual({ browser: 'chrome', environment: 'staging' });
625+
});
626+
385627
it('should get file name from media type', () => {
386628
expect((storage as any).getFileNameFromMediaType('text/plain')).toBe('file.txt');
387629
expect((storage as any).getFileNameFromMediaType('application/json')).toBe('file.json');

0 commit comments

Comments
 (0)