cucumberjs-qase-reporter 2.0.0-beta.0 → 2.0.0-beta.1

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.
@@ -0,0 +1,2 @@
1
+ import { CucumberQaseReporter } from './reporter';
2
+ export = CucumberQaseReporter;
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ const reporter_1 = require("./reporter");
3
+ module.exports = reporter_1.CucumberQaseReporter;
@@ -0,0 +1,86 @@
1
+ import { Formatter, IFormatterOptions, Status } from '@cucumber/cucumber';
2
+ import { ConfigType, ConfigLoader, TestStatusEnum } from 'qase-javascript-commons';
3
+ type TestStepResultStatus = (typeof Status)[keyof typeof Status];
4
+ export type CucumberQaseOptionsType = IFormatterOptions & {
5
+ qase?: ConfigType;
6
+ };
7
+ /**
8
+ * @class CucumberQaseReporter
9
+ * @extends Formatter
10
+ */
11
+ export declare class CucumberQaseReporter extends Formatter {
12
+ /**
13
+ * @type {Record<TestStepResultStatus, TestStatusEnum | null>}
14
+ */
15
+ static statusMap: Record<TestStepResultStatus, TestStatusEnum | null>;
16
+ /**
17
+ * @type {RegExp}
18
+ */
19
+ static qaseIdRegExp: RegExp;
20
+ /**
21
+ * @param {readonly PickleTag[]} tagsList
22
+ * @returns {number[]}
23
+ * @private
24
+ */
25
+ private static getCaseIds;
26
+ /**
27
+ * @type {Record<string, PickleInfoType>}
28
+ * @private
29
+ */
30
+ private pickleInfo;
31
+ /**
32
+ * @type {Record<string, TestCaseStarted>}
33
+ * @private
34
+ */
35
+ private testCaseStarts;
36
+ /**
37
+ * @type {Record<string, >}
38
+ * @private
39
+ */
40
+ private testCaseStartedResult;
41
+ /**
42
+ * @type {Record<string, string[]>}
43
+ * @private
44
+ */
45
+ private testCaseStartedErrors;
46
+ /**
47
+ * @type {Record<string, string>}
48
+ * @private
49
+ */
50
+ private testCaseScenarioId;
51
+ /**
52
+ * @type {Record<string, string>}
53
+ * @private
54
+ */
55
+ private scenarios;
56
+ /**
57
+ * @type {Record<string, string>}
58
+ * @private
59
+ */
60
+ private attachments;
61
+ /**
62
+ * @type {ReporterInterface}
63
+ * @private
64
+ */
65
+ private reporter;
66
+ /**
67
+ * @type {EventEmitter}
68
+ * @private
69
+ */
70
+ private eventBroadcaster;
71
+ /**
72
+ * @param {CucumberQaseOptionsType} options
73
+ * @param {ConfigLoaderInterface} configLoader
74
+ */
75
+ constructor(options: CucumberQaseOptionsType, configLoader?: ConfigLoader<Partial<ConfigType> & Record<string, unknown>>);
76
+ /**
77
+ * @private
78
+ */
79
+ private bindEventListeners;
80
+ /**
81
+ * @returns {Promise<void>}
82
+ * @private
83
+ */
84
+ private publishResults;
85
+ }
86
+ export {};
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CucumberQaseReporter = void 0;
4
+ const cucumber_1 = require("@cucumber/cucumber");
5
+ const qase_javascript_commons_1 = require("qase-javascript-commons");
6
+ /**
7
+ * @class CucumberQaseReporter
8
+ * @extends Formatter
9
+ */
10
+ class CucumberQaseReporter extends cucumber_1.Formatter {
11
+ /**
12
+ * @param {readonly PickleTag[]} tagsList
13
+ * @returns {number[]}
14
+ * @private
15
+ */
16
+ static getCaseIds(tagsList) {
17
+ return tagsList.reduce((acc, tagInfo) => {
18
+ const ids = Array.from(tagInfo.name.matchAll(CucumberQaseReporter.qaseIdRegExp))
19
+ .map(([, id]) => Number(id))
20
+ .filter((id) => id !== undefined);
21
+ acc.push(...ids);
22
+ return acc;
23
+ }, []);
24
+ }
25
+ /**
26
+ * @param {CucumberQaseOptionsType} options
27
+ * @param {ConfigLoaderInterface} configLoader
28
+ */
29
+ constructor(options, configLoader = new qase_javascript_commons_1.ConfigLoader()) {
30
+ const { qase, ...formatterOptions } = options;
31
+ const config = configLoader.load();
32
+ super(formatterOptions);
33
+ /**
34
+ * @type {Record<string, PickleInfoType>}
35
+ * @private
36
+ */
37
+ this.pickleInfo = {};
38
+ /**
39
+ * @type {Record<string, TestCaseStarted>}
40
+ * @private
41
+ */
42
+ this.testCaseStarts = {};
43
+ /**
44
+ * @type {Record<string, >}
45
+ * @private
46
+ */
47
+ this.testCaseStartedResult = {};
48
+ /**
49
+ * @type {Record<string, string[]>}
50
+ * @private
51
+ */
52
+ this.testCaseStartedErrors = {};
53
+ /**
54
+ * @type {Record<string, string>}
55
+ * @private
56
+ */
57
+ this.testCaseScenarioId = {};
58
+ /**
59
+ * @type {Record<string, string>}
60
+ * @private
61
+ */
62
+ this.scenarios = {};
63
+ /**
64
+ * @type {Record<string, string>}
65
+ * @private
66
+ */
67
+ this.attachments = {};
68
+ this.reporter = new qase_javascript_commons_1.QaseReporter({
69
+ ...(0, qase_javascript_commons_1.composeOptions)(qase, config),
70
+ frameworkPackage: '@cucumber/cucumber',
71
+ frameworkName: 'cucumberjs',
72
+ reporterName: 'cucumberjs-qase-reporter',
73
+ });
74
+ this.eventBroadcaster = formatterOptions.eventBroadcaster;
75
+ this.bindEventListeners();
76
+ }
77
+ /**
78
+ * @private
79
+ */
80
+ bindEventListeners() {
81
+ this.eventBroadcaster.on('envelope', (envelope) => {
82
+ if (envelope.gherkinDocument) {
83
+ if (envelope.gherkinDocument.feature) {
84
+ const { children, name } = envelope.gherkinDocument.feature;
85
+ children.forEach(({ scenario }) => {
86
+ if (scenario) {
87
+ this.scenarios[scenario.id] = name;
88
+ }
89
+ });
90
+ }
91
+ }
92
+ else if (envelope.pickle) {
93
+ this.pickleInfo[envelope.pickle.id] = {
94
+ caseIds: CucumberQaseReporter.getCaseIds(envelope.pickle.tags),
95
+ name: envelope.pickle.name,
96
+ lastAstNodeId: envelope.pickle.astNodeIds[envelope.pickle.astNodeIds.length - 1],
97
+ };
98
+ }
99
+ else if (envelope.attachment) {
100
+ if (envelope.attachment.testCaseStartedId &&
101
+ envelope.attachment.fileName) {
102
+ this.attachments[envelope.attachment.testCaseStartedId] =
103
+ envelope.attachment.fileName;
104
+ }
105
+ }
106
+ else if (envelope.testRunFinished) {
107
+ void this.publishResults();
108
+ }
109
+ else if (envelope.testCase) {
110
+ this.testCaseScenarioId[envelope.testCase.id] =
111
+ envelope.testCase.pickleId;
112
+ }
113
+ else if (envelope.testCaseStarted) {
114
+ this.testCaseStarts[envelope.testCaseStarted.id] =
115
+ envelope.testCaseStarted;
116
+ this.testCaseStartedResult[envelope.testCaseStarted.id] =
117
+ qase_javascript_commons_1.TestStatusEnum.passed;
118
+ }
119
+ else if (envelope.testStepFinished) {
120
+ const stepFin = envelope.testStepFinished;
121
+ const oldStatus = this.testCaseStartedResult[stepFin.testCaseStartedId];
122
+ const newStatus = CucumberQaseReporter.statusMap[stepFin.testStepResult.status];
123
+ if (newStatus === null) {
124
+ return;
125
+ }
126
+ if (newStatus !== qase_javascript_commons_1.TestStatusEnum.passed) {
127
+ if (stepFin.testStepResult.message) {
128
+ const errors = this.testCaseStartedErrors[stepFin.testCaseStartedId] ?? [];
129
+ if (!this.testCaseStartedErrors[stepFin.testCaseStartedId]) {
130
+ this.testCaseStartedErrors[stepFin.testCaseStartedId] = errors;
131
+ }
132
+ errors.push(stepFin.testStepResult.message);
133
+ }
134
+ if (oldStatus) {
135
+ if (oldStatus !== qase_javascript_commons_1.TestStatusEnum.failed) {
136
+ this.testCaseStartedResult[stepFin.testCaseStartedId] = newStatus;
137
+ }
138
+ }
139
+ else {
140
+ this.testCaseStartedResult[stepFin.testCaseStartedId] = newStatus;
141
+ }
142
+ }
143
+ }
144
+ else if (envelope.testCaseFinished) {
145
+ const tcs = this.testCaseStarts[envelope.testCaseFinished.testCaseStartedId];
146
+ if (!tcs) {
147
+ return;
148
+ }
149
+ const pickleId = this.testCaseScenarioId[tcs.testCaseId];
150
+ if (!pickleId) {
151
+ return;
152
+ }
153
+ const info = this.pickleInfo[pickleId];
154
+ if (!info) {
155
+ return;
156
+ }
157
+ let error;
158
+ if (this.testCaseStartedErrors[tcs.id]?.length) {
159
+ error = new Error(this.testCaseStartedErrors[tcs.id]?.join('\n\n'));
160
+ }
161
+ this.reporter.addTestResult({
162
+ id: tcs.id,
163
+ testOpsId: info.caseIds,
164
+ title: info.name,
165
+ suiteTitle: info.lastAstNodeId && this.scenarios[info.lastAstNodeId],
166
+ status: this.testCaseStartedResult[envelope.testCaseFinished.testCaseStartedId] ?? qase_javascript_commons_1.TestStatusEnum.passed,
167
+ startTime: tcs.timestamp.seconds,
168
+ endTime: envelope.testCaseFinished.timestamp.seconds,
169
+ duration: Math.abs(envelope.testCaseFinished.timestamp.seconds - tcs.timestamp.seconds),
170
+ error,
171
+ });
172
+ }
173
+ });
174
+ }
175
+ /**
176
+ * @returns {Promise<void>}
177
+ * @private
178
+ */
179
+ async publishResults() {
180
+ await this.reporter.publish();
181
+ }
182
+ }
183
+ exports.CucumberQaseReporter = CucumberQaseReporter;
184
+ /**
185
+ * @type {Record<TestStepResultStatus, TestStatusEnum | null>}
186
+ */
187
+ CucumberQaseReporter.statusMap = {
188
+ [cucumber_1.Status.PASSED]: qase_javascript_commons_1.TestStatusEnum.passed,
189
+ [cucumber_1.Status.FAILED]: qase_javascript_commons_1.TestStatusEnum.failed,
190
+ [cucumber_1.Status.SKIPPED]: qase_javascript_commons_1.TestStatusEnum.skipped,
191
+ [cucumber_1.Status.AMBIGUOUS]: null,
192
+ [cucumber_1.Status.PENDING]: qase_javascript_commons_1.TestStatusEnum.blocked,
193
+ [cucumber_1.Status.UNDEFINED]: null,
194
+ [cucumber_1.Status.UNKNOWN]: null,
195
+ };
196
+ /**
197
+ * @type {RegExp}
198
+ */
199
+ CucumberQaseReporter.qaseIdRegExp = /^@[Qq]-?(\d+)$/g;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cucumberjs-qase-reporter",
3
- "version": "2.0.0-beta.0",
3
+ "version": "2.0.0-beta.1",
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.0.0-beta.0"
43
+ "qase-javascript-commons": "^2.0.0-beta.1"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@cucumber/cucumber": ">=7.0.0"