cypress-qase-reporter 3.0.2 → 3.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.
- package/README.md +15 -59
- package/changelog.md +14 -0
- package/dist/cucumber.d.ts +30 -0
- package/dist/cucumber.js +61 -7
- package/dist/fileSearcher.js +17 -7
- package/dist/hooks.d.ts +0 -1
- package/dist/hooks.js +3 -4
- package/dist/index.cjs.d.ts +1 -1
- package/dist/index.cjs.js +2 -1
- package/dist/metadata/models.d.ts +0 -1
- package/dist/metadata.js +6 -0
- package/dist/mocha.d.ts +0 -90
- package/dist/reporter.d.ts +0 -1
- package/dist/reporter.js +1 -3
- package/dist/utils/tagParser.js +18 -9
- package/docs/cucumber.md +329 -0
- package/docs/usage.md +62 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -138,6 +138,10 @@ parameterize your tests.
|
|
|
138
138
|
- `qase.step` - create a step in the test case
|
|
139
139
|
- `qase.attach` - attach a file or content to the test case
|
|
140
140
|
|
|
141
|
+
#### Cucumber-specific
|
|
142
|
+
|
|
143
|
+
- `addCucumberStep(stepName)` - manually add a Cucumber step to Qase report (useful for `@badeball/cypress-cucumber-preprocessor`)
|
|
144
|
+
|
|
141
145
|
For detailed instructions on using annotations and methods, refer to [Usage](docs/usage.md).
|
|
142
146
|
|
|
143
147
|
For example:
|
|
@@ -255,71 +259,23 @@ module.exports = cypress.defineConfig({
|
|
|
255
259
|
Check out the example of configuration for multiple reporters in the
|
|
256
260
|
[demo project](../examples/cypress/cypress.config.js).
|
|
257
261
|
|
|
258
|
-
|
|
262
|
+
## Cucumber/Gherkin Integration
|
|
259
263
|
|
|
260
|
-
|
|
261
|
-
import cypress from 'cypress';
|
|
262
|
-
import { afterSpecHook } from 'cypress-qase-reporter/hooks';
|
|
263
|
-
|
|
264
|
-
const cucumber = require('cypress-cucumber-preprocessor').default;
|
|
264
|
+
If you use Cucumber with Gherkin feature files in your Cypress tests, Qase reporter provides full support for both the legacy `cypress-cucumber-preprocessor` and the modern `@badeball/cypress-cucumber-preprocessor`.
|
|
265
265
|
|
|
266
|
-
|
|
267
|
-
reporter: 'cypress-multi-reporters',
|
|
268
|
-
reporterOptions: {
|
|
269
|
-
reporterEnabled: 'cypress-mochawesome-reporter, cypress-qase-reporter',
|
|
270
|
-
cypressMochawesomeReporterReporterOptions: {
|
|
271
|
-
charts: true,
|
|
272
|
-
},
|
|
273
|
-
cypressQaseReporterReporterOptions: {
|
|
274
|
-
debug: true,
|
|
266
|
+
The reporter can automatically:
|
|
275
267
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
268
|
+
- Extract test cases from feature files
|
|
269
|
+
- Report individual Gherkin steps (Given/When/Then) with their execution status
|
|
270
|
+
- Link test results to Qase test cases using `@QaseID` tags
|
|
271
|
+
- Attach screenshots and videos to test results
|
|
280
272
|
|
|
281
|
-
|
|
282
|
-
uploadAttachments: true,
|
|
273
|
+
**📚 For detailed instructions, configuration examples, and troubleshooting, see the [Cucumber Integration Guide](docs/cucumber.md).**
|
|
283
274
|
|
|
284
|
-
|
|
285
|
-
complete: true,
|
|
286
|
-
},
|
|
287
|
-
},
|
|
275
|
+
**Quick links:**
|
|
288
276
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
screenshotsFolder: 'cypress/screenshots',
|
|
292
|
-
videosFolder: 'cypress/videos',
|
|
293
|
-
uploadDelay: 10, // Delay in seconds before uploading video files (default: 10)
|
|
294
|
-
},
|
|
295
|
-
},
|
|
296
|
-
},
|
|
297
|
-
},
|
|
298
|
-
video: false,
|
|
299
|
-
e2e: {
|
|
300
|
-
setupNodeEvents(on, config) {
|
|
301
|
-
on('file:preprocessor', cucumber());
|
|
302
|
-
require('cypress-qase-reporter/plugin')(on, config);
|
|
303
|
-
require('cypress-qase-reporter/metadata')(on);
|
|
304
|
-
on('after:spec', async (spec, results) => {
|
|
305
|
-
await afterSpecHook(spec, config);
|
|
306
|
-
});
|
|
307
|
-
},
|
|
308
|
-
specPattern: 'cypress/e2e/*.feature',
|
|
309
|
-
},
|
|
310
|
-
});
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
And add the following lines in `support/e2e.js` file:
|
|
314
|
-
|
|
315
|
-
```javascript
|
|
316
|
-
import { enableCucumberSupport } from "cypress-qase-reporter";
|
|
317
|
-
|
|
318
|
-
enableCucumberSupport();
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
Check out the example of configuration for multiple reporters in the
|
|
322
|
-
[demo project](../examples/cypressCucumber/cypress.config.js).
|
|
277
|
+
- [Example project for @badeball/cypress-cucumber-preprocessor](../examples/cypressBadeballCucumber/)
|
|
278
|
+
- [Example project for cypress-cucumber-preprocessor (legacy)](../examples/cypressCucumber/)
|
|
323
279
|
|
|
324
280
|
## Requirements
|
|
325
281
|
|
package/changelog.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# cypress-qase-reporter@3.1.0
|
|
2
|
+
|
|
3
|
+
## What's new
|
|
4
|
+
|
|
5
|
+
- Added support for Cucumber steps reporting for `@badeball/cypress-cucumber-preprocessor`.
|
|
6
|
+
- Added `addCucumberStep` function to manually add a Cucumber step to Qase report.
|
|
7
|
+
|
|
8
|
+
# cypress-qase-reporter@3.0.3
|
|
9
|
+
|
|
10
|
+
## What's new
|
|
11
|
+
|
|
12
|
+
- Added support for status filter in the test run.
|
|
13
|
+
- Improved error handling.
|
|
14
|
+
|
|
1
15
|
# cypress-qase-reporter@3.0.2
|
|
2
16
|
|
|
3
17
|
## What's new
|
package/dist/cucumber.d.ts
CHANGED
|
@@ -1 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enable automatic Cucumber step reporting for cypress-cucumber-preprocessor (legacy).
|
|
3
|
+
* This function automatically captures Gherkin steps and reports them to Qase.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```javascript
|
|
7
|
+
* // In cypress/support/e2e.js
|
|
8
|
+
* import { enableCucumberSupport } from 'cypress-qase-reporter/cucumber';
|
|
9
|
+
*
|
|
10
|
+
* enableCucumberSupport();
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
1
13
|
export declare const enableCucumberSupport: () => void;
|
|
14
|
+
/**
|
|
15
|
+
* Manually add a cucumber step to Qase report.
|
|
16
|
+
* Use this function in Before/After hooks or directly in step definitions
|
|
17
|
+
* when using @badeball/cypress-cucumber-preprocessor.
|
|
18
|
+
*
|
|
19
|
+
* @param stepName - The name of the step (e.g., "Given I am on the homepage")
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* import { Before } from '@badeball/cypress-cucumber-preprocessor';
|
|
24
|
+
* import { addCucumberStep } from 'cypress-qase-reporter/cucumber';
|
|
25
|
+
*
|
|
26
|
+
* Before(function() {
|
|
27
|
+
* addCucumberStep(this.pickle.name);
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare const addCucumberStep: (stepName: string) => void;
|
package/dist/cucumber.js
CHANGED
|
@@ -1,25 +1,79 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/// <reference types="cypress" />
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.enableCucumberSupport = void 0;
|
|
4
|
+
exports.addCucumberStep = exports.enableCucumberSupport = void 0;
|
|
4
5
|
const CUCUMBER_TASK_NAME = 'qaseCucumberStepStart';
|
|
6
|
+
/**
|
|
7
|
+
* Enable automatic Cucumber step reporting for cypress-cucumber-preprocessor (legacy).
|
|
8
|
+
* This function automatically captures Gherkin steps and reports them to Qase.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```javascript
|
|
12
|
+
* // In cypress/support/e2e.js
|
|
13
|
+
* import { enableCucumberSupport } from 'cypress-qase-reporter/cucumber';
|
|
14
|
+
*
|
|
15
|
+
* enableCucumberSupport();
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
5
18
|
const enableCucumberSupport = () => {
|
|
6
|
-
registerCypressEventListeners();
|
|
7
|
-
};
|
|
8
|
-
exports.enableCucumberSupport = enableCucumberSupport;
|
|
9
|
-
const registerCypressEventListeners = () => {
|
|
10
19
|
Cypress.on('log:added', handleLogAdded);
|
|
11
20
|
};
|
|
21
|
+
exports.enableCucumberSupport = enableCucumberSupport;
|
|
12
22
|
const handleLogAdded = (_, entry) => {
|
|
13
23
|
if (isCucumberStep(entry)) {
|
|
14
24
|
processCucumberStep(entry);
|
|
15
25
|
}
|
|
16
26
|
};
|
|
17
|
-
const isCucumberStep = (
|
|
27
|
+
const isCucumberStep = (entry) => {
|
|
28
|
+
const { attributes: { name, event, instrument } } = entry;
|
|
18
29
|
return instrument === 'command' && !event && name === 'step';
|
|
19
30
|
};
|
|
20
|
-
const processCucumberStep = (
|
|
31
|
+
const processCucumberStep = (entry) => {
|
|
32
|
+
const { attributes: { displayName, message } } = entry;
|
|
21
33
|
sendTaskMessage(`${displayName ?? ''} ${message}`);
|
|
22
34
|
};
|
|
23
35
|
const sendTaskMessage = (message) => {
|
|
24
36
|
cy.task(CUCUMBER_TASK_NAME, message, { log: false });
|
|
25
37
|
};
|
|
38
|
+
/**
|
|
39
|
+
* Manually add a cucumber step to Qase report.
|
|
40
|
+
* Use this function in Before/After hooks or directly in step definitions
|
|
41
|
+
* when using @badeball/cypress-cucumber-preprocessor.
|
|
42
|
+
*
|
|
43
|
+
* @param stepName - The name of the step (e.g., "Given I am on the homepage")
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* import { Before } from '@badeball/cypress-cucumber-preprocessor';
|
|
48
|
+
* import { addCucumberStep } from 'cypress-qase-reporter/cucumber';
|
|
49
|
+
*
|
|
50
|
+
* Before(function() {
|
|
51
|
+
* addCucumberStep(this.pickle.name);
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
const addCucumberStep = (stepName) => {
|
|
56
|
+
// Use Cypress.log to avoid command queue issues
|
|
57
|
+
// The step will be collected by MetadataManager
|
|
58
|
+
try {
|
|
59
|
+
if (stepName && stepName.trim()) {
|
|
60
|
+
Cypress.log({
|
|
61
|
+
name: 'qase:step',
|
|
62
|
+
message: stepName,
|
|
63
|
+
consoleProps: () => ({
|
|
64
|
+
Step: stepName,
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
// Also send to task for backend collection
|
|
68
|
+
// We need to wrap this in a way that doesn't interfere with command queue
|
|
69
|
+
cy.then(() => {
|
|
70
|
+
cy.task(CUCUMBER_TASK_NAME, stepName, { log: false });
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
// Silently fail if Cypress is not available
|
|
76
|
+
console.debug('Failed to add cucumber step:', e);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
exports.addCucumberStep = addCucumberStep;
|
package/dist/fileSearcher.js
CHANGED
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
36
|
exports.FileSearcher = void 0;
|
|
27
37
|
const fs = __importStar(require("fs"));
|
package/dist/hooks.d.ts
CHANGED
package/dist/hooks.js
CHANGED
|
@@ -4,7 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
5
|
};
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
7
|
+
exports.beforeRunHook = beforeRunHook;
|
|
8
|
+
exports.afterRunHook = afterRunHook;
|
|
9
|
+
exports.afterSpecHook = afterSpecHook;
|
|
8
10
|
const qase_javascript_commons_1 = require("qase-javascript-commons");
|
|
9
11
|
const configSchema_1 = require("./configSchema");
|
|
10
12
|
const resultsManager_1 = require("./metadata/resultsManager");
|
|
@@ -28,7 +30,6 @@ async function beforeRunHook(options) {
|
|
|
28
30
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
29
31
|
await reporter.startTestRunAsync();
|
|
30
32
|
}
|
|
31
|
-
exports.beforeRunHook = beforeRunHook;
|
|
32
33
|
async function afterRunHook(options) {
|
|
33
34
|
const configLoader = new qase_javascript_commons_1.ConfigLoader(configSchema_1.configSchema);
|
|
34
35
|
const config = configLoader.load();
|
|
@@ -44,7 +45,6 @@ async function afterRunHook(options) {
|
|
|
44
45
|
});
|
|
45
46
|
await reporter.complete();
|
|
46
47
|
}
|
|
47
|
-
exports.afterRunHook = afterRunHook;
|
|
48
48
|
async function afterSpecHook(spec, options) {
|
|
49
49
|
const results = resultsManager_1.ResultsManager.getResults();
|
|
50
50
|
if (results) {
|
|
@@ -131,4 +131,3 @@ async function afterSpecHook(spec, options) {
|
|
|
131
131
|
}
|
|
132
132
|
resultsManager_1.ResultsManager.clear();
|
|
133
133
|
}
|
|
134
|
-
exports.afterSpecHook = afterSpecHook;
|
package/dist/index.cjs.d.ts
CHANGED
package/dist/index.cjs.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ResultsManager = exports.enableCucumberSupport = exports.qase = void 0;
|
|
3
|
+
exports.ResultsManager = exports.addCucumberStep = exports.enableCucumberSupport = exports.qase = void 0;
|
|
4
4
|
var mocha_1 = require("./mocha");
|
|
5
5
|
Object.defineProperty(exports, "qase", { enumerable: true, get: function () { return mocha_1.qase; } });
|
|
6
6
|
var cucumber_1 = require("./cucumber");
|
|
7
7
|
Object.defineProperty(exports, "enableCucumberSupport", { enumerable: true, get: function () { return cucumber_1.enableCucumberSupport; } });
|
|
8
|
+
Object.defineProperty(exports, "addCucumberStep", { enumerable: true, get: function () { return cucumber_1.addCucumberStep; } });
|
|
8
9
|
var resultsManager_1 = require("./metadata/resultsManager");
|
|
9
10
|
Object.defineProperty(exports, "ResultsManager", { enumerable: true, get: function () { return resultsManager_1.ResultsManager; } });
|
package/dist/metadata.js
CHANGED
package/dist/mocha.d.ts
CHANGED
|
@@ -1,104 +1,14 @@
|
|
|
1
|
-
/// <reference types="cypress" />
|
|
2
|
-
/// <reference types="cypress" />
|
|
3
|
-
/// <reference types="cypress" />
|
|
4
|
-
/// <reference types="cypress" />
|
|
5
|
-
/// <reference types="node" />
|
|
6
1
|
import { Test } from 'mocha';
|
|
7
2
|
export declare const qase: {
|
|
8
3
|
(caseId: number | string | number[] | string[], test: Test): Test;
|
|
9
|
-
/**
|
|
10
|
-
* Set a title for the test case
|
|
11
|
-
* @param {string} value
|
|
12
|
-
* @example
|
|
13
|
-
* it('test', () => {
|
|
14
|
-
* qase.title("Title");
|
|
15
|
-
* cy.visit('https://example.com');
|
|
16
|
-
* });
|
|
17
|
-
*/
|
|
18
4
|
title(value: string): Cypress.Chainable<JQuery<void>>;
|
|
19
|
-
/**
|
|
20
|
-
* Set fields for the test case
|
|
21
|
-
* @param {Record<string, string>} values
|
|
22
|
-
* @example
|
|
23
|
-
* it('test', () => {
|
|
24
|
-
* qase.fields({description: "Description"});
|
|
25
|
-
* cy.visit('https://example.com');
|
|
26
|
-
* });
|
|
27
|
-
*/
|
|
28
5
|
fields(values: Record<string, string>): Cypress.Chainable<JQuery<void>>;
|
|
29
|
-
/**
|
|
30
|
-
* Ignore the test case result in Qase
|
|
31
|
-
* @example
|
|
32
|
-
* it('test', () => {
|
|
33
|
-
* qase.ignore();
|
|
34
|
-
* cy.visit('https://example.com');
|
|
35
|
-
* });
|
|
36
|
-
*/
|
|
37
6
|
ignore(): Cypress.Chainable<JQuery<void>>;
|
|
38
|
-
/**
|
|
39
|
-
* Set parameters for the test case
|
|
40
|
-
* @param {Record<string, string>} values
|
|
41
|
-
* @example
|
|
42
|
-
* it('test', () => {
|
|
43
|
-
* qase.parameters({param01: "value01"});
|
|
44
|
-
* cy.visit('https://example.com');
|
|
45
|
-
* });
|
|
46
|
-
*/
|
|
47
7
|
parameters(values: Record<string, string>): Cypress.Chainable<JQuery<void>>;
|
|
48
|
-
/**
|
|
49
|
-
* Set group parameters for the test case
|
|
50
|
-
* @param {Record<string, string>} values
|
|
51
|
-
* @example
|
|
52
|
-
* it('test', () => {
|
|
53
|
-
* qase.groupParameters({param01: "value01"});
|
|
54
|
-
* cy.visit('https://example.com');
|
|
55
|
-
* });
|
|
56
|
-
*/
|
|
57
8
|
groupParameters(values: Record<string, string>): Cypress.Chainable<JQuery<void>>;
|
|
58
|
-
/**
|
|
59
|
-
* Set a suite for the test case
|
|
60
|
-
* @param {string} value
|
|
61
|
-
* @example
|
|
62
|
-
* it('test', () => {
|
|
63
|
-
* qase.suite("Suite 01");
|
|
64
|
-
* cy.visit('https://example.com');
|
|
65
|
-
* });
|
|
66
|
-
*/
|
|
67
9
|
suite(value: string): Cypress.Chainable<JQuery<void>>;
|
|
68
|
-
/**
|
|
69
|
-
* Set a comment for the test case
|
|
70
|
-
* @param {string} value
|
|
71
|
-
* @example
|
|
72
|
-
* it('test', () => {
|
|
73
|
-
* qase.comment("Some comment");
|
|
74
|
-
* cy.visit('https://example.com');
|
|
75
|
-
* });
|
|
76
|
-
*/
|
|
77
10
|
comment(value: string): Cypress.Chainable<JQuery<void>>;
|
|
78
|
-
/**
|
|
79
|
-
* Add a step to the test case
|
|
80
|
-
* @param {string} name
|
|
81
|
-
* @param {() => T | PromiseLike<T>} body
|
|
82
|
-
* @example
|
|
83
|
-
* it('test', () => {
|
|
84
|
-
* qase.step("Some step", () => {
|
|
85
|
-
* // some actions
|
|
86
|
-
* });
|
|
87
|
-
* cy.visit('https://example.com');
|
|
88
|
-
* });
|
|
89
|
-
*/
|
|
90
11
|
step<T = void>(name: string, body: () => T | PromiseLike<T>): Cypress.Chainable<JQuery<void>>;
|
|
91
|
-
/**
|
|
92
|
-
* Attach a file to the test case or the step
|
|
93
|
-
* @param attach
|
|
94
|
-
* @example
|
|
95
|
-
* it('test', () => {
|
|
96
|
-
* qase.attach({ name: 'attachment.txt', content: 'Hello, world!', contentType: 'text/plain' });
|
|
97
|
-
* qase.attach({ paths: '/path/to/file'});
|
|
98
|
-
* qase.attach({ paths: ['/path/to/file', '/path/to/another/file']});
|
|
99
|
-
* cy.visit('https://example.com');
|
|
100
|
-
* });
|
|
101
|
-
*/
|
|
102
12
|
attach(attach: {
|
|
103
13
|
name?: string;
|
|
104
14
|
paths?: string | string[];
|
package/dist/reporter.d.ts
CHANGED
package/dist/reporter.js
CHANGED
|
@@ -198,9 +198,7 @@ class CypressQaseReporter extends mocha_1.reporters.Base {
|
|
|
198
198
|
steps: steps,
|
|
199
199
|
id: (0, uuid_1.v4)(),
|
|
200
200
|
execution: {
|
|
201
|
-
status: test.state
|
|
202
|
-
? CypressQaseReporter.statusMap[test.state]
|
|
203
|
-
: qase_javascript_commons_1.TestStatusEnum.invalid,
|
|
201
|
+
status: (0, qase_javascript_commons_1.determineTestStatus)(test.err || null, test.state || 'failed'),
|
|
204
202
|
start_time: this.testBeginTime / 1000,
|
|
205
203
|
end_time: end_time / 1000,
|
|
206
204
|
duration: duration,
|
package/dist/utils/tagParser.js
CHANGED
|
@@ -15,15 +15,25 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.extractTags =
|
|
36
|
+
exports.extractTags = extractTags;
|
|
27
37
|
const fs = __importStar(require("fs"));
|
|
28
38
|
/**
|
|
29
39
|
* Extracts tags for a given scenario name from a Gherkin feature file.
|
|
@@ -58,4 +68,3 @@ function extractTags(filePath, scenarioName) {
|
|
|
58
68
|
}
|
|
59
69
|
return tags;
|
|
60
70
|
}
|
|
61
|
-
exports.extractTags = extractTags;
|
package/docs/cucumber.md
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# Cucumber/Gherkin Integration with Qase Reporter
|
|
2
|
+
|
|
3
|
+
This guide explains how to integrate Qase reporter with Cucumber/Gherkin tests in Cypress using either the legacy `cypress-cucumber-preprocessor` or the newer `@badeball/cypress-cucumber-preprocessor`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Choosing a Preprocessor](#choosing-a-preprocessor)
|
|
10
|
+
- [Configuration for @badeball/cypress-cucumber-preprocessor (Recommended)](#configuration-for-badeballcypress-cucumber-preprocessor-recommended)
|
|
11
|
+
- [Configuration for cypress-cucumber-preprocessor (Legacy)](#configuration-for-cypress-cucumber-preprocessor-legacy)
|
|
12
|
+
- [Cucumber Steps Reporting](#cucumber-steps-reporting)
|
|
13
|
+
- [Examples](#examples)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Choosing a Preprocessor
|
|
18
|
+
|
|
19
|
+
There are two Cucumber preprocessors available for Cypress:
|
|
20
|
+
|
|
21
|
+
- **`@badeball/cypress-cucumber-preprocessor`** (Recommended) - Actively maintained, modern implementation
|
|
22
|
+
- **`cypress-cucumber-preprocessor`** (Legacy) - Original implementation, now deprecated
|
|
23
|
+
|
|
24
|
+
This guide covers both, but we recommend using `@badeball/cypress-cucumber-preprocessor` for new projects.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Configuration for @badeball/cypress-cucumber-preprocessor (Recommended)
|
|
29
|
+
|
|
30
|
+
### Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install -D @badeball/cypress-cucumber-preprocessor
|
|
34
|
+
npm install -D @bahmutov/cypress-esbuild-preprocessor
|
|
35
|
+
npm install -D cypress-qase-reporter
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Cypress Configuration
|
|
39
|
+
|
|
40
|
+
Update your `cypress.config.js`:
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
import cypress from 'cypress';
|
|
44
|
+
import { afterSpecHook } from 'cypress-qase-reporter/hooks';
|
|
45
|
+
const createBundler = require('@bahmutov/cypress-esbuild-preprocessor');
|
|
46
|
+
const addCucumberPreprocessorPlugin = require('@badeball/cypress-cucumber-preprocessor').addCucumberPreprocessorPlugin;
|
|
47
|
+
const createEsbuildPlugin = require('@badeball/cypress-cucumber-preprocessor/esbuild').createEsbuildPlugin;
|
|
48
|
+
|
|
49
|
+
module.exports = cypress.defineConfig({
|
|
50
|
+
reporter: 'cypress-multi-reporters',
|
|
51
|
+
reporterOptions: {
|
|
52
|
+
reporterEnabled: 'cypress-qase-reporter',
|
|
53
|
+
cypressQaseReporterReporterOptions: {
|
|
54
|
+
debug: true,
|
|
55
|
+
testops: {
|
|
56
|
+
api: {
|
|
57
|
+
token: 'api_token',
|
|
58
|
+
},
|
|
59
|
+
project: 'project_code',
|
|
60
|
+
uploadAttachments: true,
|
|
61
|
+
run: {
|
|
62
|
+
complete: true,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
framework: {
|
|
66
|
+
cypress: {
|
|
67
|
+
screenshotsFolder: 'cypress/screenshots',
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
video: false,
|
|
73
|
+
e2e: {
|
|
74
|
+
specPattern: 'cypress/e2e/**/*.feature',
|
|
75
|
+
async setupNodeEvents(on, config) {
|
|
76
|
+
// 1. Set up the Cucumber preprocessor FIRST
|
|
77
|
+
await addCucumberPreprocessorPlugin(on, config);
|
|
78
|
+
on(
|
|
79
|
+
'file:preprocessor',
|
|
80
|
+
createBundler({
|
|
81
|
+
plugins: [createEsbuildPlugin(config)],
|
|
82
|
+
})
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
// 2. Set up the Qase reporter plugin
|
|
86
|
+
require('cypress-qase-reporter/plugin')(on, config);
|
|
87
|
+
require('cypress-qase-reporter/metadata')(on);
|
|
88
|
+
|
|
89
|
+
// 3. Register the after:spec hook
|
|
90
|
+
on('after:spec', async (spec, results) => {
|
|
91
|
+
await afterSpecHook(spec, config);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
return config;
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Cucumber Steps Reporting
|
|
101
|
+
|
|
102
|
+
To automatically capture and report Gherkin steps to Qase, create a hooks file.
|
|
103
|
+
|
|
104
|
+
Create `cypress/support/step_definitions/hooks.js`:
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
import { BeforeStep } from '@badeball/cypress-cucumber-preprocessor';
|
|
108
|
+
import { addCucumberStep } from 'cypress-qase-reporter/cucumber';
|
|
109
|
+
|
|
110
|
+
// Automatically report each Gherkin step to Qase
|
|
111
|
+
BeforeStep(function({ pickleStep }) {
|
|
112
|
+
const keyword = pickleStep.keyword || '';
|
|
113
|
+
const stepText = `${keyword}${pickleStep.text}`;
|
|
114
|
+
addCucumberStep(stepText);
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This hook will automatically:
|
|
119
|
+
- Capture each Gherkin step (Given/When/Then/And/But)
|
|
120
|
+
- Report it to Qase with the correct execution status (passed/failed)
|
|
121
|
+
- Include step details in your test results
|
|
122
|
+
|
|
123
|
+
**Note:** Step reporting is optional. If you only need test-level results without individual step details, you can skip this configuration.
|
|
124
|
+
|
|
125
|
+
### Manual Step Reporting (Alternative)
|
|
126
|
+
|
|
127
|
+
If you prefer more control, you can manually add steps in your step definitions:
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
import { Given, When, Then } from '@badeball/cypress-cucumber-preprocessor';
|
|
131
|
+
import { addCucumberStep } from 'cypress-qase-reporter/cucumber';
|
|
132
|
+
|
|
133
|
+
Given('I am on the homepage', () => {
|
|
134
|
+
addCucumberStep('Given I am on the homepage');
|
|
135
|
+
cy.visit('https://example.com');
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
When('I click the button', () => {
|
|
139
|
+
addCucumberStep('When I click the button');
|
|
140
|
+
cy.get('button').click();
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
Then('I should see the result', () => {
|
|
144
|
+
addCucumberStep('Then I should see the result');
|
|
145
|
+
cy.get('.result').should('be.visible');
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Configuration for cypress-cucumber-preprocessor (Legacy)
|
|
152
|
+
|
|
153
|
+
### Installation
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
npm install -D cypress-cucumber-preprocessor
|
|
157
|
+
npm install -D cypress-qase-reporter
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Cypress Configuration
|
|
161
|
+
|
|
162
|
+
Update your `cypress.config.js`:
|
|
163
|
+
|
|
164
|
+
```javascript
|
|
165
|
+
import cypress from 'cypress';
|
|
166
|
+
import { afterSpecHook } from 'cypress-qase-reporter/hooks';
|
|
167
|
+
|
|
168
|
+
module.exports = cypress.defineConfig({
|
|
169
|
+
reporter: 'cypress-multi-reporters',
|
|
170
|
+
reporterOptions: {
|
|
171
|
+
reporterEnabled: 'cypress-qase-reporter',
|
|
172
|
+
cypressQaseReporterReporterOptions: {
|
|
173
|
+
debug: true,
|
|
174
|
+
testops: {
|
|
175
|
+
api: {
|
|
176
|
+
token: 'api_token',
|
|
177
|
+
},
|
|
178
|
+
project: 'project_code',
|
|
179
|
+
uploadAttachments: true,
|
|
180
|
+
run: {
|
|
181
|
+
complete: true,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
framework: {
|
|
185
|
+
cypress: {
|
|
186
|
+
screenshotsFolder: 'cypress/screenshots',
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
video: false,
|
|
192
|
+
e2e: {
|
|
193
|
+
specPattern: '**/*.feature',
|
|
194
|
+
async setupNodeEvents(on, config) {
|
|
195
|
+
require('cypress-qase-reporter/plugin')(on, config);
|
|
196
|
+
require('cypress-qase-reporter/metadata')(on);
|
|
197
|
+
|
|
198
|
+
on('after:spec', async (spec, results) => {
|
|
199
|
+
await afterSpecHook(spec, config);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
return config;
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Cucumber Steps Reporting
|
|
209
|
+
|
|
210
|
+
For the legacy preprocessor, add the following to your `cypress/support/e2e.js` file:
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
import { enableCucumberSupport } from 'cypress-qase-reporter/cucumber';
|
|
214
|
+
|
|
215
|
+
enableCucumberSupport();
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
This will automatically capture all Gherkin steps and report them to Qase. No additional configuration is needed.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Cucumber Steps Reporting
|
|
223
|
+
|
|
224
|
+
### What Gets Reported
|
|
225
|
+
|
|
226
|
+
When you enable Cucumber steps reporting, the following information is sent to Qase for each step:
|
|
227
|
+
|
|
228
|
+
- **Step text** - The full Gherkin step (e.g., "Given I am on the homepage")
|
|
229
|
+
- **Step status** - Whether the step passed or failed
|
|
230
|
+
- **Step timing** - When the step started execution
|
|
231
|
+
- **Step attachments** - Any screenshots or files attached during the step
|
|
232
|
+
|
|
233
|
+
### Example Feature File
|
|
234
|
+
|
|
235
|
+
```gherkin
|
|
236
|
+
Feature: User Login
|
|
237
|
+
|
|
238
|
+
@QaseID(1)
|
|
239
|
+
Scenario: Successful login
|
|
240
|
+
Given I am on the login page
|
|
241
|
+
When I enter valid credentials
|
|
242
|
+
And I click the login button
|
|
243
|
+
Then I should see the dashboard
|
|
244
|
+
And I should see my username
|
|
245
|
+
|
|
246
|
+
@QaseID(2)
|
|
247
|
+
Scenario: Failed login
|
|
248
|
+
Given I am on the login page
|
|
249
|
+
When I enter invalid credentials
|
|
250
|
+
And I click the login button
|
|
251
|
+
Then I should see an error message
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Adding Qase IDs
|
|
255
|
+
|
|
256
|
+
You can associate Qase test case IDs with your scenarios using tags:
|
|
257
|
+
|
|
258
|
+
- Single ID: `@QaseID(123)`
|
|
259
|
+
- Multiple IDs: `@QaseID(123,456)`
|
|
260
|
+
|
|
261
|
+
The Qase reporter will automatically extract these IDs and link the test results to the corresponding test cases in Qase.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Examples
|
|
266
|
+
|
|
267
|
+
### Complete Working Examples
|
|
268
|
+
|
|
269
|
+
Check out our example projects:
|
|
270
|
+
|
|
271
|
+
- **[@badeball/cypress-cucumber-preprocessor Example](../../examples/cypressBadeballCucumber/)** - Modern implementation with automatic step reporting
|
|
272
|
+
- **[cypress-cucumber-preprocessor Example](../../examples/cypressCucumber/)** - Legacy implementation
|
|
273
|
+
|
|
274
|
+
Each example includes:
|
|
275
|
+
- Complete Cypress configuration
|
|
276
|
+
- Feature files with Gherkin scenarios
|
|
277
|
+
- Step definitions
|
|
278
|
+
- Qase reporter integration
|
|
279
|
+
- Automatic step reporting setup
|
|
280
|
+
|
|
281
|
+
### Running the Examples
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
# Navigate to the example directory
|
|
285
|
+
cd examples/cypressBadeballCucumber
|
|
286
|
+
|
|
287
|
+
# Install dependencies
|
|
288
|
+
npm install
|
|
289
|
+
|
|
290
|
+
# Set your Qase credentials in cypress.config.js
|
|
291
|
+
|
|
292
|
+
# Run tests
|
|
293
|
+
npm test
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Troubleshooting
|
|
299
|
+
|
|
300
|
+
### Steps are not being reported
|
|
301
|
+
|
|
302
|
+
**For @badeball/cypress-cucumber-preprocessor:**
|
|
303
|
+
- Ensure you've created the `hooks.js` file with the `BeforeStep` hook
|
|
304
|
+
- Verify the file is in `cypress/support/step_definitions/` directory
|
|
305
|
+
- Check that you're importing `addCucumberStep` from `'cypress-qase-reporter/cucumber'`
|
|
306
|
+
|
|
307
|
+
**For cypress-cucumber-preprocessor (legacy):**
|
|
308
|
+
- Verify you've called `enableCucumberSupport()` in `cypress/support/e2e.js`
|
|
309
|
+
- Ensure you're importing from `'cypress-qase-reporter/cucumber'`
|
|
310
|
+
|
|
311
|
+
### Cypress command queue errors
|
|
312
|
+
|
|
313
|
+
If you see errors like "Cypress detected that you returned a promise from a command", make sure you're using the provided `addCucumberStep` function, which properly handles the Cypress command queue.
|
|
314
|
+
|
|
315
|
+
### Test results not appearing in Qase
|
|
316
|
+
|
|
317
|
+
- Verify your API token is correct in `cypress.config.js`
|
|
318
|
+
- Check that your project code matches your Qase project
|
|
319
|
+
- Enable `debug: true` in reporter options to see detailed logs
|
|
320
|
+
- Ensure `mode: 'testops'` is set in your configuration
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## Additional Resources
|
|
325
|
+
|
|
326
|
+
- [Qase Reporter Configuration](../README.md#configuration)
|
|
327
|
+
- [Qase Reporter Usage Guide](./usage.md)
|
|
328
|
+
- [@badeball/cypress-cucumber-preprocessor Documentation](https://github.com/badeball/cypress-cucumber-preprocessor)
|
|
329
|
+
- [Cypress Documentation](https://docs.cypress.io/)
|
package/docs/usage.md
CHANGED
|
@@ -194,3 +194,65 @@ it('test', () => {
|
|
|
194
194
|
cy.visit('https://example.com');
|
|
195
195
|
});
|
|
196
196
|
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Cucumber Steps Reporting
|
|
201
|
+
|
|
202
|
+
### For @badeball/cypress-cucumber-preprocessor
|
|
203
|
+
|
|
204
|
+
When using `@badeball/cypress-cucumber-preprocessor`, you can automatically report Cucumber/Gherkin steps to Qase using the `addCucumberStep` function in a `BeforeStep` hook.
|
|
205
|
+
|
|
206
|
+
#### Automatic Step Reporting
|
|
207
|
+
|
|
208
|
+
Create a file `cypress/support/step_definitions/hooks.js`:
|
|
209
|
+
|
|
210
|
+
```javascript
|
|
211
|
+
import { BeforeStep } from '@badeball/cypress-cucumber-preprocessor';
|
|
212
|
+
import { addCucumberStep } from 'cypress-qase-reporter/cucumber';
|
|
213
|
+
|
|
214
|
+
// Automatically report each Gherkin step to Qase
|
|
215
|
+
BeforeStep(function({ pickleStep }) {
|
|
216
|
+
const keyword = pickleStep.keyword || '';
|
|
217
|
+
const stepText = `${keyword}${pickleStep.text}`;
|
|
218
|
+
addCucumberStep(stepText);
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
This will automatically capture each step (Given/When/Then/And/But) and report it to Qase with its execution status.
|
|
223
|
+
|
|
224
|
+
#### Manual Step Reporting
|
|
225
|
+
|
|
226
|
+
Alternatively, you can manually add steps in your step definitions:
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
import { Given, When, Then } from '@badeball/cypress-cucumber-preprocessor';
|
|
230
|
+
import { addCucumberStep } from 'cypress-qase-reporter/cucumber';
|
|
231
|
+
|
|
232
|
+
Given('I am on the homepage', () => {
|
|
233
|
+
addCucumberStep('Given I am on the homepage');
|
|
234
|
+
cy.visit('https://example.com');
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
When('I click the button', () => {
|
|
238
|
+
addCucumberStep('When I click the button');
|
|
239
|
+
cy.get('button').click();
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
Then('I should see the result', () => {
|
|
243
|
+
addCucumberStep('Then I should see the result');
|
|
244
|
+
cy.get('.result').should('be.visible');
|
|
245
|
+
});
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### For cypress-cucumber-preprocessor (legacy)
|
|
249
|
+
|
|
250
|
+
For the legacy `cypress-cucumber-preprocessor`, steps are automatically captured. Add the following to your `support/e2e.js` file:
|
|
251
|
+
|
|
252
|
+
```javascript
|
|
253
|
+
import { enableCucumberSupport } from 'cypress-qase-reporter/cucumber';
|
|
254
|
+
|
|
255
|
+
enableCucumberSupport();
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
No additional configuration is needed - all Gherkin steps will be automatically reported to Qase.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cypress-qase-reporter",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Qase Cypress Reporter",
|
|
5
5
|
"homepage": "https://github.com/qase-tms/qase-javascript",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"author": "Qase Team <support@qase.io>",
|
|
52
52
|
"license": "Apache-2.0",
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"qase-javascript-commons": "~2.4.
|
|
54
|
+
"qase-javascript-commons": "~2.4.5",
|
|
55
55
|
"uuid": "^9.0.1"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|