@ai-testing-tool/forge-cucumberjs 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,12 @@ export type CucumberQaTagMeta = {
4
4
  title: string | null;
5
5
  ignore: boolean;
6
6
  suite: string | null;
7
+ suiteId: string | null;
8
+ planId: string | null;
9
+ planName: string | null;
10
+ fixVersion: string | null;
11
+ sprintName: string | null;
12
+ labels: string[];
7
13
  fields: Record<string, string>;
8
14
  parameters: Record<string, string>;
9
15
  /** Issue keys from tags like @AUTH-101 (FR51). */
@@ -4,7 +4,13 @@ exports.parseQaTags = parseQaTags;
4
4
  exports.resolveScenarioTitle = resolveScenarioTitle;
5
5
  const titleRe = /^@[Qq]a[Tt]itle=(.+)$/;
6
6
  const ignoreRe = /^@[Qq]a[Ii]gnore$/;
7
+ const suiteIdRe = /^@[Qq]a[Ss]uite[Ii]d=(.+)$/;
7
8
  const suiteRe = /^@[Qq]a[Ss]uite=(.+)$/;
9
+ const planIdRe = /^@[Qq]a[Pp]lan[Ii]d=(.+)$/;
10
+ const planRe = /^@[Qq]a[Pp]lan=(.+)$/;
11
+ const fixVersionRe = /^@[Qq]a[Ff]ix[Vv]ersion=(.+)$/;
12
+ const sprintNameRe = /^@[Qq]a[Ss]print[Nn]ame=(.+)$/;
13
+ const labelsRe = /^@[Qq]a[Ll]abels=(.+)$/;
8
14
  const fieldsRe = /^@[Qq]a[Ff]ields=(.+)$/;
9
15
  const parametersRe = /^@[Qq]a[Pp]arameters=(.+)$/;
10
16
  const issueKeyRe = /^@([A-Z][A-Z0-9]+-\d+)$/;
@@ -27,6 +33,12 @@ function tryParseRecord(raw) {
27
33
  return {};
28
34
  }
29
35
  }
36
+ function appendLabels(target, raw) {
37
+ for (const part of raw.split(/[\s,]+/).map((s) => s.trim()).filter(Boolean)) {
38
+ if (!target.includes(part))
39
+ target.push(part);
40
+ }
41
+ }
30
42
  /**
31
43
  * Parse `@Qa*` and issue-key tags from a pickle.
32
44
  * No competitor tag names — destination is Jira.
@@ -36,6 +48,12 @@ function parseQaTags(tags) {
36
48
  title: null,
37
49
  ignore: false,
38
50
  suite: null,
51
+ suiteId: null,
52
+ planId: null,
53
+ planName: null,
54
+ fixVersion: null,
55
+ sprintName: null,
56
+ labels: [],
39
57
  fields: {},
40
58
  parameters: {},
41
59
  issueKeys: [],
@@ -51,11 +69,41 @@ function parseQaTags(tags) {
51
69
  meta.title = titleMatch[1].replace(/_/g, ' ');
52
70
  continue;
53
71
  }
72
+ const suiteIdMatch = suiteIdRe.exec(name);
73
+ if (suiteIdMatch?.[1]) {
74
+ meta.suiteId = suiteIdMatch[1];
75
+ continue;
76
+ }
54
77
  const suiteMatch = suiteRe.exec(name);
55
78
  if (suiteMatch?.[1]) {
56
79
  meta.suite = suiteMatch[1];
57
80
  continue;
58
81
  }
82
+ const planIdMatch = planIdRe.exec(name);
83
+ if (planIdMatch?.[1]) {
84
+ meta.planId = planIdMatch[1];
85
+ continue;
86
+ }
87
+ const planMatch = planRe.exec(name);
88
+ if (planMatch?.[1]) {
89
+ meta.planName = planMatch[1].replace(/_/g, ' ');
90
+ continue;
91
+ }
92
+ const fixVersionMatch = fixVersionRe.exec(name);
93
+ if (fixVersionMatch?.[1]) {
94
+ meta.fixVersion = fixVersionMatch[1];
95
+ continue;
96
+ }
97
+ const sprintNameMatch = sprintNameRe.exec(name);
98
+ if (sprintNameMatch?.[1]) {
99
+ meta.sprintName = sprintNameMatch[1].replace(/_/g, ' ');
100
+ continue;
101
+ }
102
+ const labelsMatch = labelsRe.exec(name);
103
+ if (labelsMatch?.[1]) {
104
+ appendLabels(meta.labels, labelsMatch[1]);
105
+ continue;
106
+ }
59
107
  const fieldsMatch = fieldsRe.exec(name);
60
108
  if (fieldsMatch?.[1]) {
61
109
  meta.fields = { ...meta.fields, ...tryParseRecord(fieldsMatch[1]) };
@@ -1,4 +1,4 @@
1
- import type { JestVitestJsonReport, QaMetaWire } from '@ai-testing-tool/forge-commons';
1
+ import { type JestVitestJsonReport, type QaMetaWire } from '@ai-testing-tool/forge-commons';
2
2
  import type { ConvertedScenario } from './modules/event-storage';
3
3
  export type CucumberAssertionInput = {
4
4
  ancestorTitles: string[];
@@ -93,6 +93,24 @@ function scenarioToAssertion(scenario, attachEntries = []) {
93
93
  if (tagMeta.suite) {
94
94
  entries.push({ type: 'qa-suite', body: tagMeta.suite });
95
95
  }
96
+ if (tagMeta.suiteId) {
97
+ entries.push({ type: 'qa-suite-id', body: tagMeta.suiteId });
98
+ }
99
+ if (tagMeta.planId) {
100
+ entries.push({ type: 'qa-plan-id', body: tagMeta.planId });
101
+ }
102
+ if (tagMeta.planName) {
103
+ entries.push({ type: 'qa-plan', body: tagMeta.planName });
104
+ }
105
+ if (tagMeta.fixVersion) {
106
+ entries.push({ type: 'qa-fix-version', body: tagMeta.fixVersion });
107
+ }
108
+ if (tagMeta.sprintName) {
109
+ entries.push({ type: 'qa-sprint-name', body: tagMeta.sprintName });
110
+ }
111
+ if (tagMeta.labels.length > 0) {
112
+ entries.push({ type: 'qa-labels', body: tagMeta.labels });
113
+ }
96
114
  if (Object.keys(tagMeta.fields).length > 0) {
97
115
  entries.push({ type: 'qa-fields', body: tagMeta.fields });
98
116
  }
@@ -177,7 +195,7 @@ function toJestJsonReport(specs, startTime) {
177
195
  const testResults = specs.map((spec) => {
178
196
  const assertionResults = spec.assertions.map(mapAssertion);
179
197
  return {
180
- name: spec.name,
198
+ name: (0, forge_commons_1.normalizeReportFilePath)(spec.name),
181
199
  status: fileStatus(assertionResults),
182
200
  startTime: spec.startTime,
183
201
  endTime: spec.endTime,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-testing-tool/forge-cucumberjs",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "AI Testing Tool CucumberJS formatter — ingest or file modes via @ai-testing-tool/forge-commons",
5
5
  "keywords": [
6
6
  "ai-testing-tool",