qase-javascript-commons 2.0.0-beta.9 → 2.0.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 +16 -2
- package/changelog.md +76 -0
- package/dist/qase.d.ts +30 -8
- package/dist/qase.js +33 -18
- package/dist/reporters/abstract-reporter.d.ts +6 -24
- package/dist/reporters/abstract-reporter.js +4 -13
- package/dist/reporters/index.d.ts +1 -1
- package/dist/reporters/report-reporter.d.ts +4 -3
- package/dist/reporters/report-reporter.js +3 -3
- package/dist/reporters/testops-reporter.d.ts +7 -2
- package/dist/reporters/testops-reporter.js +30 -12
- package/dist/utils/logger.d.ts +6 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
# Qase JavaScript Commons
|
|
2
2
|
|
|
3
|
-
This
|
|
3
|
+
This module is an SDK for developing test reporters for Qase TMS.
|
|
4
|
+
It's using `qaseio` as an API client, and all Qase reporters are, in turn,
|
|
5
|
+
using this package.
|
|
6
|
+
You should use it if you're developing your own test reporter for a special-purpose framework.
|
|
7
|
+
|
|
8
|
+
To report results from tests using a popular framework or test runner,
|
|
9
|
+
don't install this module directly and
|
|
10
|
+
use the corresponding reporter module instead:
|
|
11
|
+
|
|
12
|
+
* [CucumberJS](https://github.com/qase-tms/qase-javascript/tree/main/qase-cucumberjs#readme)
|
|
13
|
+
* [Cypress](https://github.com/qase-tms/qase-javascript/tree/main/qase-cypress#readme)
|
|
14
|
+
* [Jest](https://github.com/qase-tms/qase-javascript/tree/main/qase-jest#readme)
|
|
15
|
+
* [Newman](https://github.com/qase-tms/qase-javascript/tree/main/qase-newman#readme)
|
|
16
|
+
* [Playwright](https://github.com/qase-tms/qase-javascript/tree/main/qase-playwright#readme)
|
|
17
|
+
* [TestCafe](https://github.com/qase-tms/qase-javascript/tree/main/qase-testcafe#readme)
|
|
4
18
|
|
|
5
19
|
## Installation
|
|
6
20
|
|
|
7
21
|
```bash
|
|
8
|
-
npm install qase-javascript-commons
|
|
22
|
+
npm install qase-javascript-commons
|
|
9
23
|
```
|
|
10
24
|
|
|
11
25
|
## Configuration
|
package/changelog.md
CHANGED
|
@@ -1,3 +1,79 @@
|
|
|
1
|
+
# qase-javascript-commons@2.0.0
|
|
2
|
+
|
|
3
|
+
## What's new
|
|
4
|
+
|
|
5
|
+
This is the first release version of the Qase JavaScript SDK.
|
|
6
|
+
It is numbered `2.0.0` (and not `1.0.0`) to match the release series of
|
|
7
|
+
test reporters for Playwright, Cypress, Jest and other frameworks.
|
|
8
|
+
|
|
9
|
+
### Annotating test with field data
|
|
10
|
+
|
|
11
|
+
Tests can now be annotated with data for system and custom fields in Qase.
|
|
12
|
+
This feature is already implemented in the Playwright reporter:
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
test('Test with annotated fields', () => {
|
|
16
|
+
qase.id(1);
|
|
17
|
+
qase.fields({ 'severity': 'high', 'priority': 'medium' })
|
|
18
|
+
// ...
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Parametrized tests
|
|
23
|
+
|
|
24
|
+
Qase JavaScript SDK enables annotating tests with parameters, and passing parameter values to Qase.
|
|
25
|
+
Parameterized tests can report to a single test case, but each parameter variation is registered as
|
|
26
|
+
a standalone result, with its own run history.
|
|
27
|
+
|
|
28
|
+
### Attachments from files and variables
|
|
29
|
+
|
|
30
|
+
Reporters can now upload attachments of various data types to Qase,
|
|
31
|
+
both from files and from variables.
|
|
32
|
+
It enables flexible and meticulous logging, such as collecting full HTTP request data,
|
|
33
|
+
including URL, headers, and payload.
|
|
34
|
+
|
|
35
|
+
### Uploading results in flexible batches, asynchronously
|
|
36
|
+
|
|
37
|
+
Test reporters can now upload results in batches, while tests are still running.
|
|
38
|
+
It helps bring test results faster and enables acting on them long before the test run is complete.
|
|
39
|
+
|
|
40
|
+
### Uniform configuration
|
|
41
|
+
|
|
42
|
+
Qase JavaScript SDK brings configuration with config files and environment variables
|
|
43
|
+
to a common standard, used with Qase reporters in all languages and frameworks.
|
|
44
|
+
|
|
45
|
+
For details, see the Configuration section in the README.
|
|
46
|
+
|
|
47
|
+
### Latest API
|
|
48
|
+
|
|
49
|
+
Qase JavaScript SDK is using the latest Qase API client,
|
|
50
|
+
employing the full power of the stable v1 API version,
|
|
51
|
+
and enabling the use of experimental v2 API, tailored for uploading
|
|
52
|
+
huge amounts of test results.
|
|
53
|
+
|
|
54
|
+
# qase-javascript-commons@2.0.0-beta.12
|
|
55
|
+
|
|
56
|
+
## What's new
|
|
57
|
+
|
|
58
|
+
Fixed an issue when the result has empty step action. Now the reporter will mark such steps as "Unnamed step" and will
|
|
59
|
+
log a warning message.
|
|
60
|
+
|
|
61
|
+
# qase-javascript-commons@2.0.0-beta.11
|
|
62
|
+
|
|
63
|
+
## What's new
|
|
64
|
+
|
|
65
|
+
* The `useV2` option in the reporter's configuration will now enable using the experimental v2 API.
|
|
66
|
+
Before this fix, v1 API was used despite the configuration.
|
|
67
|
+
|
|
68
|
+
* Attachments from test steps will now be uploaded to Qase.
|
|
69
|
+
Before this fix, the reporter uploaded only the attachments made outside of any step scope.
|
|
70
|
+
|
|
71
|
+
# qase-javascript-commons@2.0.0-beta.10
|
|
72
|
+
|
|
73
|
+
## What's new
|
|
74
|
+
|
|
75
|
+
Fixed an issue when the results published before the test run creation.
|
|
76
|
+
|
|
1
77
|
# qase-javascript-commons@2.0.0-beta.9
|
|
2
78
|
|
|
3
79
|
## What's new
|
package/dist/qase.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import { AbstractReporter } from './reporters';
|
|
2
1
|
import { OptionsType } from './options';
|
|
3
2
|
import { TestResultType } from './models';
|
|
3
|
+
export interface ReporterInterface {
|
|
4
|
+
addTestResult(result: TestResultType): Promise<void>;
|
|
5
|
+
publish(): Promise<void>;
|
|
6
|
+
startTestRun(): void;
|
|
7
|
+
isCaptureLogs(): boolean;
|
|
8
|
+
}
|
|
4
9
|
/**
|
|
5
10
|
* @class QaseReporter
|
|
6
11
|
* @implements AbstractReporter
|
|
7
12
|
*/
|
|
8
|
-
export declare class QaseReporter
|
|
13
|
+
export declare class QaseReporter implements ReporterInterface {
|
|
14
|
+
private static instance;
|
|
9
15
|
/**
|
|
10
16
|
* @param {string} frameworkPackage
|
|
11
17
|
* @param {string} frameworkName
|
|
@@ -15,15 +21,20 @@ export declare class QaseReporter extends AbstractReporter {
|
|
|
15
21
|
*/
|
|
16
22
|
private static createHeaders;
|
|
17
23
|
/**
|
|
18
|
-
* @type {
|
|
24
|
+
* @type {InternalReporterInterface}
|
|
19
25
|
* @private
|
|
20
26
|
*/
|
|
21
27
|
private readonly upstreamReporter?;
|
|
22
28
|
/**
|
|
23
|
-
* @type {
|
|
29
|
+
* @type {InternalReporterInterface}
|
|
24
30
|
* @private
|
|
25
31
|
*/
|
|
26
32
|
private readonly fallbackReporter?;
|
|
33
|
+
/**
|
|
34
|
+
* @type {boolean | undefined}
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
private readonly captureLogs;
|
|
27
38
|
/**
|
|
28
39
|
* @type {boolean}
|
|
29
40
|
* @private
|
|
@@ -34,14 +45,21 @@ export declare class QaseReporter extends AbstractReporter {
|
|
|
34
45
|
* @private
|
|
35
46
|
*/
|
|
36
47
|
private useFallback;
|
|
48
|
+
private readonly logger;
|
|
49
|
+
private startTestRunOperation?;
|
|
37
50
|
/**
|
|
38
51
|
* @param {OptionsType} options
|
|
39
52
|
*/
|
|
40
|
-
constructor(
|
|
53
|
+
private constructor();
|
|
41
54
|
/**
|
|
42
|
-
* @returns {
|
|
55
|
+
* @returns {void}
|
|
56
|
+
*/
|
|
57
|
+
startTestRun(): void;
|
|
58
|
+
/**
|
|
59
|
+
* @param {OptionsType} options
|
|
60
|
+
* @returns {QaseReporter}
|
|
43
61
|
*/
|
|
44
|
-
|
|
62
|
+
static getInstance(options: OptionsType): QaseReporter;
|
|
45
63
|
/**
|
|
46
64
|
* @param {TestResultType} result
|
|
47
65
|
*/
|
|
@@ -51,6 +69,10 @@ export declare class QaseReporter extends AbstractReporter {
|
|
|
51
69
|
* @private
|
|
52
70
|
*/
|
|
53
71
|
private addTestResultToFallback;
|
|
72
|
+
/**
|
|
73
|
+
* @returns {boolean}
|
|
74
|
+
*/
|
|
75
|
+
isCaptureLogs(): boolean;
|
|
54
76
|
/**
|
|
55
77
|
* @returns {Promise<void>}
|
|
56
78
|
*/
|
|
@@ -63,7 +85,7 @@ export declare class QaseReporter extends AbstractReporter {
|
|
|
63
85
|
* @todo implement mode registry
|
|
64
86
|
* @param {ModeEnum} mode
|
|
65
87
|
* @param {OptionsType} options
|
|
66
|
-
* @returns {
|
|
88
|
+
* @returns {InternalReporterInterface}
|
|
67
89
|
* @private
|
|
68
90
|
*/
|
|
69
91
|
private createReporter;
|
package/dist/qase.js
CHANGED
|
@@ -16,6 +16,7 @@ const writer_1 = require("./writer");
|
|
|
16
16
|
const get_package_version_1 = require("./utils/get-package-version");
|
|
17
17
|
const custom_boundary_1 = require("./utils/custom-boundary");
|
|
18
18
|
const disabled_exception_1 = require("./utils/disabled-exception");
|
|
19
|
+
const logger_1 = require("./utils/logger");
|
|
19
20
|
/**
|
|
20
21
|
* @type {Record<TestStatusEnum, (test: TestResultType) => string>}
|
|
21
22
|
*/
|
|
@@ -31,7 +32,7 @@ const resultLogMap = {
|
|
|
31
32
|
* @class QaseReporter
|
|
32
33
|
* @implements AbstractReporter
|
|
33
34
|
*/
|
|
34
|
-
class QaseReporter
|
|
35
|
+
class QaseReporter {
|
|
35
36
|
/**
|
|
36
37
|
* @param {string} frameworkPackage
|
|
37
38
|
* @param {string} frameworkName
|
|
@@ -68,9 +69,6 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
68
69
|
* @param {OptionsType} options
|
|
69
70
|
*/
|
|
70
71
|
constructor(options) {
|
|
71
|
-
const env = (0, env_1.envToConfig)((0, env_schema_1.default)({ schema: env_1.envValidationSchema }));
|
|
72
|
-
const composedOptions = (0, options_1.composeOptions)(options, env);
|
|
73
|
-
super({ debug: composedOptions.debug, captureLogs: composedOptions.captureLogs });
|
|
74
72
|
/**
|
|
75
73
|
* @type {boolean}
|
|
76
74
|
* @private
|
|
@@ -81,7 +79,11 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
81
79
|
* @private
|
|
82
80
|
*/
|
|
83
81
|
this.useFallback = false;
|
|
82
|
+
const env = (0, env_1.envToConfig)((0, env_schema_1.default)({ schema: env_1.envValidationSchema }));
|
|
83
|
+
const composedOptions = (0, options_1.composeOptions)(options, env);
|
|
84
|
+
this.logger = new logger_1.Logger({ debug: composedOptions.debug });
|
|
84
85
|
this.logger.logDebug(`Config: ${JSON.stringify(composedOptions)}`);
|
|
86
|
+
this.captureLogs = composedOptions.captureLogs;
|
|
85
87
|
try {
|
|
86
88
|
this.upstreamReporter = this.createReporter(
|
|
87
89
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
@@ -120,13 +122,13 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
124
|
/**
|
|
123
|
-
* @returns {
|
|
125
|
+
* @returns {void}
|
|
124
126
|
*/
|
|
125
|
-
|
|
127
|
+
startTestRun() {
|
|
126
128
|
if (!this.disabled) {
|
|
127
129
|
this.logger.logDebug('Starting test run');
|
|
128
130
|
try {
|
|
129
|
-
|
|
131
|
+
this.startTestRunOperation = this.upstreamReporter?.startTestRun();
|
|
130
132
|
}
|
|
131
133
|
catch (error) {
|
|
132
134
|
this.logger.logError('Unable to start test run in the upstream reporter: ', error);
|
|
@@ -135,7 +137,7 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
135
137
|
return;
|
|
136
138
|
}
|
|
137
139
|
try {
|
|
138
|
-
|
|
140
|
+
this.startTestRunOperation = this.fallbackReporter?.startTestRun();
|
|
139
141
|
}
|
|
140
142
|
catch (error) {
|
|
141
143
|
this.logger.logError('Unable to start test run in the fallback reporter: ', error);
|
|
@@ -144,6 +146,16 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
144
146
|
}
|
|
145
147
|
}
|
|
146
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* @param {OptionsType} options
|
|
151
|
+
* @returns {QaseReporter}
|
|
152
|
+
*/
|
|
153
|
+
static getInstance(options) {
|
|
154
|
+
if (!QaseReporter.instance) {
|
|
155
|
+
QaseReporter.instance = new QaseReporter(options);
|
|
156
|
+
}
|
|
157
|
+
return QaseReporter.instance;
|
|
158
|
+
}
|
|
147
159
|
/**
|
|
148
160
|
* @param {TestResultType} result
|
|
149
161
|
*/
|
|
@@ -184,11 +196,18 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
184
196
|
this.disabled = true;
|
|
185
197
|
}
|
|
186
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* @returns {boolean}
|
|
201
|
+
*/
|
|
202
|
+
isCaptureLogs() {
|
|
203
|
+
return this.captureLogs ?? false;
|
|
204
|
+
}
|
|
187
205
|
/**
|
|
188
206
|
* @returns {Promise<void>}
|
|
189
207
|
*/
|
|
190
208
|
async publish() {
|
|
191
209
|
if (!this.disabled) {
|
|
210
|
+
await this.startTestRunOperation;
|
|
192
211
|
this.logger.logDebug('Publishing test run results');
|
|
193
212
|
if (this.useFallback) {
|
|
194
213
|
await this.publishFallback();
|
|
@@ -226,14 +245,14 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
226
245
|
* @todo implement mode registry
|
|
227
246
|
* @param {ModeEnum} mode
|
|
228
247
|
* @param {OptionsType} options
|
|
229
|
-
* @returns {
|
|
248
|
+
* @returns {InternalReporterInterface}
|
|
230
249
|
* @private
|
|
231
250
|
*/
|
|
232
251
|
createReporter(mode, options) {
|
|
233
|
-
const { frameworkPackage, frameworkName, reporterName, environment, report = {}, testops = {},
|
|
252
|
+
const { frameworkPackage, frameworkName, reporterName, environment, report = {}, testops = {}, } = options;
|
|
234
253
|
switch (mode) {
|
|
235
254
|
case options_1.ModeEnum.testops: {
|
|
236
|
-
const { api: { token, headers, ...api } = {}, project, run: { title, description, ...run } = {}, plan = {}, batch = {}, uploadAttachments, } = testops;
|
|
255
|
+
const { api: { token, headers, ...api } = {}, project, run: { title, description, ...run } = {}, plan = {}, batch = {}, useV2, uploadAttachments, } = testops;
|
|
237
256
|
if (!token) {
|
|
238
257
|
throw new Error(`Either "testops.api.token" parameter or "${env_1.EnvApiEnum.token}" environment variable is required in "testops" mode`);
|
|
239
258
|
}
|
|
@@ -248,7 +267,7 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
248
267
|
},
|
|
249
268
|
...api,
|
|
250
269
|
}, custom_boundary_1.CustomBoundaryFormData);
|
|
251
|
-
return new reporters_1.TestOpsReporter({
|
|
270
|
+
return new reporters_1.TestOpsReporter(this.logger, {
|
|
252
271
|
project,
|
|
253
272
|
uploadAttachments,
|
|
254
273
|
run: {
|
|
@@ -258,17 +277,13 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
258
277
|
},
|
|
259
278
|
plan,
|
|
260
279
|
batch,
|
|
261
|
-
|
|
262
|
-
captureLogs: commonOptions.captureLogs,
|
|
280
|
+
useV2,
|
|
263
281
|
}, apiClient, typeof environment === 'number' ? environment : undefined);
|
|
264
282
|
}
|
|
265
283
|
case options_1.ModeEnum.report: {
|
|
266
284
|
const localOptions = report.connections?.[writer_1.DriverEnum.local];
|
|
267
285
|
const writer = new writer_1.FsWriter(localOptions);
|
|
268
|
-
return new reporters_1.ReportReporter(
|
|
269
|
-
debug: commonOptions.debug,
|
|
270
|
-
captureLogs: commonOptions.captureLogs,
|
|
271
|
-
}, writer, typeof environment === 'number' ? environment.toString() : environment, testops.run?.id);
|
|
286
|
+
return new reporters_1.ReportReporter(this.logger, writer, typeof environment === 'number' ? environment.toString() : environment, testops.run?.id);
|
|
272
287
|
}
|
|
273
288
|
case options_1.ModeEnum.off:
|
|
274
289
|
throw new disabled_exception_1.DisabledException();
|
|
@@ -1,32 +1,18 @@
|
|
|
1
1
|
import { TestResultType } from '../models';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
logError(message: string, error?: unknown): void;
|
|
5
|
-
logDebug(message: string): void;
|
|
6
|
-
}
|
|
7
|
-
export interface ReporterOptionsType {
|
|
8
|
-
debug?: boolean | undefined;
|
|
9
|
-
captureLogs?: boolean | undefined;
|
|
10
|
-
}
|
|
11
|
-
export interface ReporterInterface {
|
|
2
|
+
import { LoggerInterface } from '../utils/logger';
|
|
3
|
+
export interface InternalReporterInterface {
|
|
12
4
|
addTestResult(result: TestResultType): Promise<void>;
|
|
13
5
|
publish(): Promise<void>;
|
|
14
6
|
startTestRun(): Promise<void>;
|
|
15
7
|
getTestResults(): TestResultType[];
|
|
16
8
|
setTestResults(results: TestResultType[]): void;
|
|
17
|
-
isCaptureLogs(): boolean;
|
|
18
9
|
}
|
|
19
10
|
/**
|
|
20
11
|
* @abstract
|
|
21
12
|
* @class AbstractReporter
|
|
22
|
-
* @implements
|
|
13
|
+
* @implements InternalReporterInterface
|
|
23
14
|
*/
|
|
24
|
-
export declare abstract class AbstractReporter implements
|
|
25
|
-
/**
|
|
26
|
-
* @type {boolean | undefined}
|
|
27
|
-
* @private
|
|
28
|
-
*/
|
|
29
|
-
private readonly captureLogs;
|
|
15
|
+
export declare abstract class AbstractReporter implements InternalReporterInterface {
|
|
30
16
|
/**
|
|
31
17
|
* @type {LoggerInterface}
|
|
32
18
|
* @private
|
|
@@ -46,18 +32,14 @@ export declare abstract class AbstractReporter implements ReporterInterface {
|
|
|
46
32
|
*/
|
|
47
33
|
abstract startTestRun(): Promise<void>;
|
|
48
34
|
/**
|
|
49
|
-
* @param {ReporterOptionsType} options
|
|
50
35
|
* @protected
|
|
36
|
+
* @param {LoggerInterface} logger
|
|
51
37
|
*/
|
|
52
|
-
protected constructor(
|
|
38
|
+
protected constructor(logger: LoggerInterface);
|
|
53
39
|
/**
|
|
54
40
|
* @returns {TestResultType[]}
|
|
55
41
|
*/
|
|
56
42
|
getTestResults(): TestResultType[];
|
|
57
|
-
/**
|
|
58
|
-
* @returns {boolean}
|
|
59
|
-
*/
|
|
60
|
-
isCaptureLogs(): boolean;
|
|
61
43
|
/**
|
|
62
44
|
* @param {TestResultType} result
|
|
63
45
|
*/
|
|
@@ -2,26 +2,23 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AbstractReporter = void 0;
|
|
4
4
|
const uuid_1 = require("uuid");
|
|
5
|
-
const logger_1 = require("../utils/logger");
|
|
6
5
|
/**
|
|
7
6
|
* @abstract
|
|
8
7
|
* @class AbstractReporter
|
|
9
|
-
* @implements
|
|
8
|
+
* @implements InternalReporterInterface
|
|
10
9
|
*/
|
|
11
10
|
class AbstractReporter {
|
|
12
11
|
/**
|
|
13
|
-
* @param {ReporterOptionsType} options
|
|
14
12
|
* @protected
|
|
13
|
+
* @param {LoggerInterface} logger
|
|
15
14
|
*/
|
|
16
|
-
constructor(
|
|
15
|
+
constructor(logger) {
|
|
17
16
|
/**
|
|
18
17
|
* @type {TestResultType[]}
|
|
19
18
|
* @protected
|
|
20
19
|
*/
|
|
21
20
|
this.results = [];
|
|
22
|
-
|
|
23
|
-
this.captureLogs = captureLogs;
|
|
24
|
-
this.logger = new logger_1.Logger({ debug });
|
|
21
|
+
this.logger = logger;
|
|
25
22
|
}
|
|
26
23
|
/**
|
|
27
24
|
* @returns {TestResultType[]}
|
|
@@ -29,12 +26,6 @@ class AbstractReporter {
|
|
|
29
26
|
getTestResults() {
|
|
30
27
|
return this.results;
|
|
31
28
|
}
|
|
32
|
-
/**
|
|
33
|
-
* @returns {boolean}
|
|
34
|
-
*/
|
|
35
|
-
isCaptureLogs() {
|
|
36
|
-
return this.captureLogs ?? false;
|
|
37
|
-
}
|
|
38
29
|
/**
|
|
39
30
|
* @param {TestResultType} result
|
|
40
31
|
*/
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { AbstractReporter, type
|
|
1
|
+
export { AbstractReporter, type InternalReporterInterface, } from './abstract-reporter';
|
|
2
2
|
export { ReportReporter } from './report-reporter';
|
|
3
3
|
export { TestOpsReporter, type TestOpsOptionsType } from './testops-reporter';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { AbstractReporter
|
|
1
|
+
import { AbstractReporter } from './abstract-reporter';
|
|
2
2
|
import { WriterInterface } from '../writer';
|
|
3
|
+
import { LoggerInterface } from '../utils/logger';
|
|
3
4
|
/**
|
|
4
5
|
* @class ReportReporter
|
|
5
6
|
* @extends AbstractReporter
|
|
@@ -10,12 +11,12 @@ export declare class ReportReporter extends AbstractReporter {
|
|
|
10
11
|
private readonly runId;
|
|
11
12
|
private startTime;
|
|
12
13
|
/**
|
|
13
|
-
* @param {
|
|
14
|
+
* @param {LoggerInterface} logger
|
|
14
15
|
* @param {WriterInterface} writer
|
|
15
16
|
* @param {string | undefined} environment
|
|
16
17
|
* @param {number | undefined} runId
|
|
17
18
|
*/
|
|
18
|
-
constructor(
|
|
19
|
+
constructor(logger: LoggerInterface, writer: WriterInterface, environment?: string, runId?: number);
|
|
19
20
|
/**
|
|
20
21
|
* @returns {Promise<void>}
|
|
21
22
|
*/
|
|
@@ -35,13 +35,13 @@ const process = __importStar(require("process"));
|
|
|
35
35
|
*/
|
|
36
36
|
class ReportReporter extends abstract_reporter_1.AbstractReporter {
|
|
37
37
|
/**
|
|
38
|
-
* @param {
|
|
38
|
+
* @param {LoggerInterface} logger
|
|
39
39
|
* @param {WriterInterface} writer
|
|
40
40
|
* @param {string | undefined} environment
|
|
41
41
|
* @param {number | undefined} runId
|
|
42
42
|
*/
|
|
43
|
-
constructor(
|
|
44
|
-
super(
|
|
43
|
+
constructor(logger, writer, environment, runId) {
|
|
44
|
+
super(logger);
|
|
45
45
|
this.writer = writer;
|
|
46
46
|
this.startTime = Date.now();
|
|
47
47
|
this.environment = environment;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { QaseApiInterface, ResultStepStatus, TestStepResultCreateStatusEnum } from 'qaseio';
|
|
2
|
-
import { AbstractReporter
|
|
2
|
+
import { AbstractReporter } from './abstract-reporter';
|
|
3
3
|
import { StepStatusEnum, TestResultType, TestStatusEnum } from '../models';
|
|
4
|
+
import { LoggerInterface } from '../utils/logger';
|
|
4
5
|
export type TestOpsRunType = {
|
|
5
6
|
id?: number | undefined;
|
|
6
7
|
title: string;
|
|
@@ -91,11 +92,12 @@ export declare class TestOpsReporter extends AbstractReporter {
|
|
|
91
92
|
*/
|
|
92
93
|
private isTestRunReady;
|
|
93
94
|
/**
|
|
95
|
+
* @param {LoggerInterface} logger
|
|
94
96
|
* @param {ReporterOptionsType & TestOpsOptionsType} options
|
|
95
97
|
* @param {QaseApiInterface} api
|
|
96
98
|
* @param {number} environment
|
|
97
99
|
*/
|
|
98
|
-
constructor(
|
|
100
|
+
constructor(logger: LoggerInterface, options: TestOpsOptionsType, api: QaseApiInterface, environment?: number);
|
|
99
101
|
/**
|
|
100
102
|
* @returns {Promise<void>}
|
|
101
103
|
*/
|
|
@@ -145,16 +147,19 @@ export declare class TestOpsReporter extends AbstractReporter {
|
|
|
145
147
|
private getRelation;
|
|
146
148
|
/**
|
|
147
149
|
* @param {TestStepType[]} steps
|
|
150
|
+
* @param testTitle
|
|
148
151
|
* @returns Promise<ResultStep[]>
|
|
149
152
|
* @private
|
|
150
153
|
*/
|
|
151
154
|
private transformSteps;
|
|
152
155
|
/**
|
|
153
156
|
* @param {TestStepType[]} steps
|
|
157
|
+
* @param testTitle
|
|
154
158
|
* @returns Promise<TestStepResultCreate[]>
|
|
155
159
|
* @private
|
|
156
160
|
*/
|
|
157
161
|
private transformStepsV1;
|
|
162
|
+
private logEmptyStep;
|
|
158
163
|
/**
|
|
159
164
|
* @param {number} runId
|
|
160
165
|
* @returns {Promise<void>}
|
|
@@ -17,13 +17,14 @@ const defaultChunkSize = 200;
|
|
|
17
17
|
*/
|
|
18
18
|
class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
19
19
|
/**
|
|
20
|
+
* @param {LoggerInterface} logger
|
|
20
21
|
* @param {ReporterOptionsType & TestOpsOptionsType} options
|
|
21
22
|
* @param {QaseApiInterface} api
|
|
22
23
|
* @param {number} environment
|
|
23
24
|
*/
|
|
24
|
-
constructor(options, api, environment) {
|
|
25
|
-
const { project, uploadAttachments, run,
|
|
26
|
-
super(
|
|
25
|
+
constructor(logger, options, api, environment) {
|
|
26
|
+
const { project, uploadAttachments, run, } = options;
|
|
27
|
+
super(logger);
|
|
27
28
|
this.api = api;
|
|
28
29
|
/**
|
|
29
30
|
* @type {number}
|
|
@@ -145,7 +146,7 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
145
146
|
*/
|
|
146
147
|
async transformTestResult(result) {
|
|
147
148
|
const attachments = await this.uploadAttachments(result.attachments);
|
|
148
|
-
const steps = await this.transformSteps(result.steps);
|
|
149
|
+
const steps = await this.transformSteps(result.steps, result.title);
|
|
149
150
|
const model = {
|
|
150
151
|
title: result.title,
|
|
151
152
|
execution: this.getExecution(result.execution),
|
|
@@ -166,7 +167,7 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
166
167
|
*/
|
|
167
168
|
async transformTestResultV1(result) {
|
|
168
169
|
const attachments = await this.uploadAttachments(result.attachments);
|
|
169
|
-
const steps = await this.transformStepsV1(result.steps);
|
|
170
|
+
const steps = await this.transformStepsV1(result.steps, result.title);
|
|
170
171
|
const resultCreate = {
|
|
171
172
|
attachments: attachments,
|
|
172
173
|
comment: result.message,
|
|
@@ -230,25 +231,32 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
230
231
|
}
|
|
231
232
|
/**
|
|
232
233
|
* @param {TestStepType[]} steps
|
|
234
|
+
* @param testTitle
|
|
233
235
|
* @returns Promise<ResultStep[]>
|
|
234
236
|
* @private
|
|
235
237
|
*/
|
|
236
|
-
async transformSteps(steps) {
|
|
238
|
+
async transformSteps(steps, testTitle) {
|
|
237
239
|
const resultsSteps = [];
|
|
238
240
|
for (const step of steps) {
|
|
239
241
|
const attachmentHashes = await this.uploadAttachments(step.attachments);
|
|
240
242
|
const resultStep = {
|
|
241
243
|
data: {
|
|
242
244
|
action: '',
|
|
243
|
-
attachments: attachmentHashes,
|
|
244
245
|
},
|
|
245
246
|
execution: {
|
|
246
247
|
status: TestOpsReporter.stepStatusMap[step.execution.status],
|
|
248
|
+
attachments: attachmentHashes,
|
|
247
249
|
},
|
|
248
250
|
};
|
|
249
251
|
if (step.step_type === models_1.StepType.TEXT) {
|
|
250
252
|
if ('action' in step.data && resultStep.data != undefined) {
|
|
251
|
-
|
|
253
|
+
if (step.data.action === '') {
|
|
254
|
+
this.logEmptyStep(testTitle);
|
|
255
|
+
resultStep.data.action = 'Unnamed step';
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
resultStep.data.action = step.data.action;
|
|
259
|
+
}
|
|
252
260
|
}
|
|
253
261
|
}
|
|
254
262
|
if (step.step_type === models_1.StepType.GHERKIN) {
|
|
@@ -257,7 +265,7 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
257
265
|
}
|
|
258
266
|
}
|
|
259
267
|
if (step.steps.length > 0) {
|
|
260
|
-
resultStep.steps = await this.transformSteps(step.steps);
|
|
268
|
+
resultStep.steps = await this.transformSteps(step.steps, testTitle);
|
|
261
269
|
}
|
|
262
270
|
resultsSteps.push(resultStep);
|
|
263
271
|
}
|
|
@@ -265,10 +273,11 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
265
273
|
}
|
|
266
274
|
/**
|
|
267
275
|
* @param {TestStepType[]} steps
|
|
276
|
+
* @param testTitle
|
|
268
277
|
* @returns Promise<TestStepResultCreate[]>
|
|
269
278
|
* @private
|
|
270
279
|
*/
|
|
271
|
-
async transformStepsV1(steps) {
|
|
280
|
+
async transformStepsV1(steps, testTitle) {
|
|
272
281
|
const resultsSteps = [];
|
|
273
282
|
for (const step of steps) {
|
|
274
283
|
const attachmentHashes = await this.uploadAttachments(step.attachments);
|
|
@@ -278,7 +287,13 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
278
287
|
};
|
|
279
288
|
if (step.step_type === models_1.StepType.TEXT) {
|
|
280
289
|
if ('action' in step.data) {
|
|
281
|
-
|
|
290
|
+
if (step.data.action === '') {
|
|
291
|
+
this.logEmptyStep(testTitle);
|
|
292
|
+
resultStep.action = 'Unnamed step';
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
resultStep.action = step.data.action;
|
|
296
|
+
}
|
|
282
297
|
}
|
|
283
298
|
}
|
|
284
299
|
if (step.step_type === models_1.StepType.GHERKIN) {
|
|
@@ -287,12 +302,15 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
287
302
|
}
|
|
288
303
|
}
|
|
289
304
|
if (step.steps.length > 0) {
|
|
290
|
-
resultStep.steps = await this.transformStepsV1(step.steps);
|
|
305
|
+
resultStep.steps = await this.transformStepsV1(step.steps, testTitle);
|
|
291
306
|
}
|
|
292
307
|
resultsSteps.push(resultStep);
|
|
293
308
|
}
|
|
294
309
|
return resultsSteps;
|
|
295
310
|
}
|
|
311
|
+
logEmptyStep(testTitle) {
|
|
312
|
+
this.logger.log((0, chalk_1.default) `{magenta Test '${testTitle}' has empty action in step. The reporter will mark this step as unnamed step.}`);
|
|
313
|
+
}
|
|
296
314
|
/**
|
|
297
315
|
* @param {number} runId
|
|
298
316
|
* @returns {Promise<void>}
|
package/dist/utils/logger.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface LoggerInterface {
|
|
2
|
+
log(message: string): void;
|
|
3
|
+
logError(message: string, error?: unknown): void;
|
|
4
|
+
logDebug(message: string): void;
|
|
5
|
+
}
|
|
6
|
+
export declare class Logger implements LoggerInterface {
|
|
2
7
|
private readonly debug;
|
|
3
8
|
private readonly filePath;
|
|
4
9
|
constructor(options: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qase-javascript-commons",
|
|
3
|
-
"version": "2.0.0
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Qase JS Reporters",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"test": "jest --passWithNoTests",
|
|
22
22
|
"clean": "rm -rf dist"
|
|
23
23
|
},
|
|
24
|
-
"author": "
|
|
24
|
+
"author": "Qase Team <dharding@dimitriharding.com>",
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"ajv": "^8.12.0",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"lodash.merge": "^4.6.2",
|
|
34
34
|
"lodash.mergewith": "^4.6.2",
|
|
35
35
|
"mime-types": "^2.1.33",
|
|
36
|
-
"qaseio": "^2.1.0
|
|
36
|
+
"qaseio": "^2.1.0",
|
|
37
37
|
"strip-ansi": "^6.0.1",
|
|
38
38
|
"uuid": "^9.0.0"
|
|
39
39
|
},
|