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 +6 -0
- package/changelog.md +12 -0
- package/dist/models.d.ts +4 -0
- package/dist/storage.js +33 -4
- package/docs/MULTI_PROJECT.md +75 -0
- package/package.json +2 -2
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
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
43
|
+
"qase-javascript-commons": "~2.5.0"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@cucumber/cucumber": ">=7.0.0"
|