cucumberjs-qase-reporter 2.1.8 → 2.2.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.
package/README.md CHANGED
@@ -80,6 +80,12 @@ https://app.qase.io/run/QASE_PROJECT_CODE
80
80
  <img src="./screenshots/demo.gif">
81
81
  </p>
82
82
 
83
+ ### Multi-Project Support
84
+
85
+ Qase CucumberJS Reporter supports sending test results to multiple Qase projects simultaneously. Use tags in feature files: `@qaseid.PROJ1(1) @qaseid.PROJ2(2)`.
86
+
87
+ For detailed information, configuration, and examples, see the [Multi-Project Support Guide](docs/MULTI_PROJECT.md).
88
+
83
89
  ## Configuration
84
90
 
85
91
  Qase Cucumber JS reporter can be configured in multiple ways:
package/changelog.md CHANGED
@@ -1,3 +1,15 @@
1
+ # qase-cucumberjs@2.2.0
2
+
3
+ ## What's new
4
+
5
+ - Added support for multi-project support.
6
+
7
+ # qase-cucumberjs@2.1.9
8
+
9
+ ## What's new
10
+
11
+ - Added support for QaseSuite tag.
12
+
1
13
  # qase-cucumberjs@2.1.8
2
14
 
3
15
  ## What's new
package/dist/models.d.ts CHANGED
@@ -1,10 +1,14 @@
1
+ import type { TestopsProjectMapping } from 'qase-javascript-commons';
1
2
  export interface TestMetadata {
2
3
  ids: number[];
4
+ /** Multi-project mapping (from @qaseid.PROJ(ids) tags). */
5
+ projectMapping: TestopsProjectMapping;
3
6
  fields: Record<string, string>;
4
7
  title: string | null;
5
8
  isIgnore: boolean;
6
9
  parameters: Record<string, string>;
7
10
  group_params: Record<string, string>;
11
+ suite: string | null;
8
12
  }
9
13
  export interface ScenarioData {
10
14
  name: string;
package/dist/storage.js CHANGED
@@ -10,6 +10,7 @@ const qaseTitleRegExp = /^@[Qq]ase[Tt]itle=(.+)$/;
10
10
  const qaseFieldsRegExp = /^@[Qq]ase[Ff]ields=(.+)$/;
11
11
  const qaseParametersRegExp = /^@[Qq]ase[Pp]arameters=(.+)$/;
12
12
  const qaseGroupParametersRegExp = /^@[Qq]ase[Gg]roup[Pp]arameters=(.+)$/;
13
+ const qaseSuiteRegExp = /^@[Qq]ase[Ss]uite=(.+)$/;
13
14
  const qaseIgnoreRegExp = /^@[Qq]ase[Ii][Gg][Nn][Oo][Rr][Ee]$/;
14
15
  class Storage {
15
16
  /**
@@ -198,7 +199,20 @@ class Storage {
198
199
  let relations = null;
199
200
  let params = {};
200
201
  const nodeId = pickle.astNodeIds[0];
201
- if (nodeId != undefined && this.scenarios[nodeId] != undefined) {
202
+ // If suite is specified in metadata, use it (split by tab for sub-suites)
203
+ if (metadata.suite) {
204
+ const suiteParts = metadata.suite.split('\t').filter(part => part.trim().length > 0);
205
+ relations = {
206
+ suite: {
207
+ data: suiteParts.map((suite) => ({
208
+ title: suite.trim(),
209
+ public_id: null,
210
+ })),
211
+ },
212
+ };
213
+ }
214
+ else if (nodeId != undefined && this.scenarios[nodeId] != undefined) {
215
+ // Otherwise, use feature name as suite
202
216
  relations = {
203
217
  suite: {
204
218
  data: [
@@ -209,6 +223,9 @@ class Storage {
209
223
  ],
210
224
  },
211
225
  };
226
+ }
227
+ // Extract parameters from Gherkin examples
228
+ if (nodeId != undefined && this.scenarios[nodeId] != undefined) {
212
229
  for (const id of pickle.astNodeIds) {
213
230
  if (this.scenarios[nodeId]?.parameters[id] != undefined) {
214
231
  params = { ...params, ...this.scenarios[nodeId]?.parameters[id] };
@@ -219,7 +236,8 @@ class Storage {
219
236
  // Parameters from tags take precedence over Gherkin examples
220
237
  params = { ...params, ...metadata.parameters };
221
238
  const steps = this.convertSteps(pickle.steps, tc);
222
- return {
239
+ const hasProjectMapping = Object.keys(metadata.projectMapping).length > 0;
240
+ const result = {
223
241
  attachments: this.attachments[testCase.testCaseStartedId] ?? [],
224
242
  author: null,
225
243
  execution: {
@@ -240,9 +258,11 @@ class Storage {
240
258
  signature: this.getSignature(pickle, metadata.ids, params),
241
259
  steps: steps,
242
260
  testops_id: metadata.ids.length > 0 ? metadata.ids : null,
261
+ testops_project_mapping: hasProjectMapping ? metadata.projectMapping : null,
243
262
  id: tcs.id,
244
263
  title: metadata.title ?? pickle.name,
245
264
  };
265
+ return result;
246
266
  }
247
267
  /**
248
268
  * Convert test steps to test result steps
@@ -309,13 +329,17 @@ class Storage {
309
329
  [cucumber_1.Status.UNKNOWN]: qase_javascript_commons_1.StepStatusEnum.skipped,
310
330
  };
311
331
  parseTags(tags) {
332
+ const tagNames = tags.map((t) => t.name);
333
+ const { legacyIds, projectMapping } = (0, qase_javascript_commons_1.parseProjectMappingFromTags)(tagNames);
312
334
  const metadata = {
313
- ids: [],
335
+ ids: [...legacyIds],
336
+ projectMapping: { ...projectMapping },
314
337
  fields: {},
315
338
  title: null,
316
339
  isIgnore: false,
317
340
  parameters: {},
318
341
  group_params: {},
342
+ suite: null,
319
343
  };
320
344
  for (const tag of tags) {
321
345
  if (qaseIdRegExp.test(tag.name)) {
@@ -323,7 +347,8 @@ class Storage {
323
347
  continue;
324
348
  }
325
349
  if (newQaseIdRegExp.test(tag.name)) {
326
- metadata.ids.push(...(tag.name.replace(/^@[Qq]ase[Ii][Dd]=/, '')).split(',').map(Number));
350
+ const idsStr = tag.name.replace(/^@[Qq]ase[Ii][Dd]=/, '');
351
+ metadata.ids.push(...idsStr.split(',').map((s) => Number(s.trim())));
327
352
  continue;
328
353
  }
329
354
  if (qaseTitleRegExp.test(tag.name)) {
@@ -363,6 +388,10 @@ class Storage {
363
388
  // do nothing
364
389
  }
365
390
  }
391
+ if (qaseSuiteRegExp.test(tag.name)) {
392
+ metadata.suite = tag.name.replace(/^@[Qq]ase[Ss]uite=/, '');
393
+ continue;
394
+ }
366
395
  if (qaseIgnoreRegExp.test(tag.name)) {
367
396
  metadata.isIgnore = true;
368
397
  }
@@ -0,0 +1,75 @@
1
+ # Multi-Project Support in CucumberJS
2
+
3
+ Qase CucumberJS Reporter supports sending test results to multiple Qase projects simultaneously. This feature allows you to report the same scenario execution to different projects with different test case IDs, which is useful when:
4
+
5
+ * You need to report the same scenario to different projects
6
+ * Different projects track the same functionality with different test case IDs
7
+ * You want to maintain separate test runs for different environments or teams
8
+
9
+ ## Configuration
10
+
11
+ For detailed configuration options, refer to the [qase-javascript-commons README](../../qase-javascript-commons/README.md#multi-project-support).
12
+
13
+ ### Basic Multi-Project Configuration
14
+
15
+ Set `mode` to `testops_multi` in your `qase.config.json` and add the `testops_multi` section with `default_project` and `projects`.
16
+
17
+ ## Using Tags in Feature Files
18
+
19
+ Map scenarios to projects and case IDs using tags in your `.feature` files.
20
+
21
+ ### Multi-project tags: `@qaseid.PROJECT_CODE(ids)`
22
+
23
+ Use one or more tags per scenario. Each tag specifies a project code and one or more test case IDs:
24
+
25
+ ```gherkin
26
+ Feature: Multi-project example
27
+
28
+ @qaseid.DEVX(1)
29
+ @qaseid.DEMO(2)
30
+ Scenario: Scenario reported to two projects
31
+ Given I have a step
32
+ ```
33
+
34
+ ### Single project (legacy)
35
+
36
+ For a single project you can still use the legacy tag format:
37
+
38
+ ```gherkin
39
+ @QaseID=3
40
+ Scenario: Scenario with legacy single-project tag
41
+ Given I have a step
42
+ ```
43
+
44
+ ### Scenarios without Qase ID
45
+
46
+ Scenarios with no `@qaseid` or `@QaseID` tags are sent to the `default_project` from your configuration. The result is sent without linking to a test case (no case ID).
47
+
48
+ ## Tag Format
49
+
50
+ * **Multi-project**: `@qaseid.PROJECT_CODE(id1,id2,...)` — project code must match `testops_multi.projects[].code`.
51
+ * **Legacy single-project**: `@QaseID=123` or `@qaseid(123)` — sent to `default_project` with that ID.
52
+
53
+ ## Important Notes
54
+
55
+ 1. **Project codes must match**: The project code in `@qaseid.PROJ1(1)` must match a `code` in `testops_multi.projects`.
56
+ 2. **Mode**: Set `mode` to `testops_multi` in `qase.config.json`.
57
+ 3. **Default project**: Scenarios without any Qase tags are sent to `default_project` without a case ID.
58
+ 4. **Multiple tags**: You can combine multiple `@qaseid.PROJ(ids)` tags to report one scenario to multiple projects.
59
+
60
+ ## Examples
61
+
62
+ See the [multi-project CucumberJS example](../../examples/multiProject/cucumberjs/) for a complete runnable setup.
63
+
64
+ ## Troubleshooting
65
+
66
+ ### Results not appearing in projects
67
+
68
+ * Verify `mode` is `testops_multi` in `qase.config.json`.
69
+ * Check that project codes in tags (e.g. `@qaseid.DEVX(1)`) match `testops_multi.projects[].code` exactly (case-sensitive).
70
+ * Ensure all projects are listed in `testops_multi.projects`.
71
+
72
+ ### Scenarios sent to wrong project
73
+
74
+ * For scenarios without tags, check the `default_project` setting.
75
+ * Ensure tag spelling and project codes match the configuration exactly.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cucumberjs-qase-reporter",
3
- "version": "2.1.8",
3
+ "version": "2.2.0",
4
4
  "description": "Qase TMS CucumberJS Reporter",
5
5
  "homepage": "https://github.com/qase-tms/qase-javascript",
6
6
  "main": "./dist/index.js",
@@ -40,7 +40,7 @@
40
40
  "license": "Apache-2.0",
41
41
  "dependencies": {
42
42
  "@cucumber/messages": "^22.0.0",
43
- "qase-javascript-commons": "~2.4.16"
43
+ "qase-javascript-commons": "~2.5.0"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@cucumber/cucumber": ">=7.0.0"