qase-javascript-commons 2.0.0-beta.6 → 2.0.0-beta.8
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 +74 -97
- package/changelog.md +48 -0
- package/dist/config/config-validation-schema.js +8 -2
- package/dist/env/env-enum.d.ts +6 -1
- package/dist/env/env-enum.js +8 -2
- package/dist/env/env-to-config.js +3 -1
- package/dist/env/env-type.d.ts +2 -2
- package/dist/env/env-validation-schema.js +4 -4
- package/dist/qase.d.ts +5 -1
- package/dist/qase.js +32 -8
- package/dist/reporters/abstract-reporter.d.ts +7 -2
- package/dist/reporters/abstract-reporter.js +2 -1
- package/dist/reporters/report-reporter.d.ts +5 -2
- package/dist/reporters/report-reporter.js +7 -1
- package/dist/reporters/testops-reporter.d.ts +35 -3
- package/dist/reporters/testops-reporter.js +71 -30
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,102 +1,79 @@
|
|
|
1
|
-
|
|
1
|
+
# Qase JavaScript Commons
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
$ npm install --save qase-core-reporter
|
|
5
|
-
```
|
|
6
|
-
|
|
7
|
-
## Usage
|
|
8
|
-
|
|
9
|
-
> Create a new Qase JS reporter in minutes by leveraging this core reporter.
|
|
10
|
-
> Use Qase core reporter with test framework custom reporter hooks
|
|
11
|
-
|
|
12
|
-
```js
|
|
13
|
-
import {
|
|
14
|
-
QaseCoreReporter,
|
|
15
|
-
QaseOptions,
|
|
16
|
-
QaseCoreReporterOptions,
|
|
17
|
-
TestResult
|
|
18
|
-
} from "qase-core-reporter";
|
|
3
|
+
This package contains common classes and functions for working with Qase TMS API.
|
|
19
4
|
|
|
20
|
-
|
|
21
|
-
// expected options, provided by reporter user
|
|
22
|
-
apiToken: 'lknkldnfknobek'
|
|
23
|
-
projectCode: 'DH'
|
|
24
|
-
};
|
|
5
|
+
## Installation
|
|
25
6
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
frameworkName: 'vitest',
|
|
29
|
-
reporterName: 'vitest-qase-reporter'
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
// Initialize Core reporter with expected params
|
|
33
|
-
const reporter = new QaseCoreReporter(reporterOptions, qaseCoreReporterOptions);
|
|
34
|
-
|
|
35
|
-
// On start hook
|
|
36
|
-
reporter.start();
|
|
37
|
-
|
|
38
|
-
// On test results
|
|
39
|
-
reporter.addTestResult(test: TestResult, status, attachments);
|
|
40
|
-
|
|
41
|
-
// On end/complete hook
|
|
42
|
-
reporter.end({ spawn: false }); // spawn true will finish reporting in a child process
|
|
7
|
+
```bash
|
|
8
|
+
npm install qase-javascript-commons@beta
|
|
43
9
|
```
|
|
44
10
|
|
|
45
|
-
##
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
|
55
|
-
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
61
|
-
|
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
11
|
+
## Configuration
|
|
12
|
+
|
|
13
|
+
Qase JS Reporters can be configured in multiple ways:
|
|
14
|
+
|
|
15
|
+
- using a config file `qase.config.json`
|
|
16
|
+
- using environment variables
|
|
17
|
+
|
|
18
|
+
All configuration options are listed in the table below:
|
|
19
|
+
|
|
20
|
+
| Description | Config file | Environment variable | Default value | Required | Possible values |
|
|
21
|
+
|----------------------------------------------------------------------------------------------------------------------------|----------------------------|---------------------------------|-----------------------------------------|----------|----------------------------|
|
|
22
|
+
| **Common** | | | | | |
|
|
23
|
+
| Mode of reporter | `mode` | `QASE_MODE` | `testops` | No | `testops`, `report`, `off` |
|
|
24
|
+
| Fallback mode of reporter | `fallback` | `QASE_FALLBACK` | `off` | No | `testops`, `report`, `off` |
|
|
25
|
+
| Environment | `environment` | `QASE_ENVIRONMENT` | `local` | No | Any string |
|
|
26
|
+
| Enable debug logs | `debug` | `QASE_DEBUG` | `False` | No | `True`, `False` |
|
|
27
|
+
| Enable capture logs from `stdout` and `stderr` | `testops.defect` | `QASE_CAPTURE_LOGS` | `False` | No | `True`, `False` |
|
|
28
|
+
| **Qase Report configuration** | | | | | |
|
|
29
|
+
| Driver used for report mode | `report.driver` | `QASE_REPORT_DRIVER` | `local` | No | `local` |
|
|
30
|
+
| Path to save the report | `report.connection.path` | `QASE_REPORT_CONNECTION_PATH` | `./build/qase-report` | | |
|
|
31
|
+
| Local report format | `report.connection.format` | `QASE_REPORT_CONNECTION_FORMAT` | `json` | | `json`, `jsonp` |
|
|
32
|
+
| **Qase TestOps configuration** | | | | | |
|
|
33
|
+
| Token for [API access](https://developers.qase.io/#authentication) | `testops.api.token` | `QASE_TESTOPS_API_TOKEN` | | Yes | Any string |
|
|
34
|
+
| Qase API host | `testops.api.host` | `QASE_TESTOPS_API_HOST` | `qase.io` | No | Any string |
|
|
35
|
+
| Code of your project, which you can take from the URL: `https://app.qase.io/project/DEMOTR` - `DEMOTR` is the project code | `testops.project` | `QASE_TESTOPS_PROJECT` | | Yes | Any string |
|
|
36
|
+
| Qase test run ID | `testops.run.id` | `QASE_TESTOPS_RUN_ID` | | No | Any integer |
|
|
37
|
+
| Qase test run title | `testops.run.title` | `QASE_TESTOPS_RUN_TITLE` | `Automated run <Current date and time>` | No | Any string |
|
|
38
|
+
| Qase test run description | `testops.run.description` | `QASE_TESTOPS_RUN_DESCRIPTION` | `<Framework name> automated run` | No | Any string |
|
|
39
|
+
| Qase test run complete | `testops.run.complete` | `QASE_TESTOPS_RUN_COMPLETE` | `True` | | `True`, `False` |
|
|
40
|
+
| Qase test plan ID | `testops.plan.id` | `QASE_TESTOPS_PLAN_ID` | | No | Any integer |
|
|
41
|
+
| Size of batch for sending test results | `testops.batch.size` | `QASE_TESTOPS_BATCH_SIZE` | `200` | No | Any integer |
|
|
42
|
+
| Enable defects for failed test cases | `testops.defect` | `QASE_TESTOPS_DEFECT` | `False` | No | `True`, `False` |
|
|
43
|
+
|
|
44
|
+
### Example `qase.config.json` config:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"mode": "testops",
|
|
49
|
+
"fallback": "report",
|
|
50
|
+
"debug": false,
|
|
51
|
+
"environment": "local",
|
|
52
|
+
"captureLogs": false,
|
|
53
|
+
"report": {
|
|
54
|
+
"driver": "local",
|
|
55
|
+
"connection": {
|
|
56
|
+
"local": {
|
|
57
|
+
"path": "./build/qase-report",
|
|
58
|
+
"format": "json"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"testops": {
|
|
63
|
+
"api": {
|
|
64
|
+
"token": "<token>",
|
|
65
|
+
"host": "qase.io"
|
|
66
|
+
},
|
|
67
|
+
"run": {
|
|
68
|
+
"title": "Regress run",
|
|
69
|
+
"description": "Regress run description",
|
|
70
|
+
"complete": true
|
|
71
|
+
},
|
|
72
|
+
"defect": false,
|
|
73
|
+
"project": "<project_code>",
|
|
74
|
+
"batch": {
|
|
75
|
+
"size": 100
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
package/changelog.md
CHANGED
|
@@ -1,3 +1,51 @@
|
|
|
1
|
+
# qase-javascript-commons@2.0.0-beta.8
|
|
2
|
+
|
|
3
|
+
## What's new
|
|
4
|
+
|
|
5
|
+
Renamed the `QASE_TESTOPS_CHUNK` environment variable to `QASE_TESTOPS_BATCH_SIZE`.
|
|
6
|
+
Renamed the `chunk` field in the reporter's configuration to `batch.size`.
|
|
7
|
+
|
|
8
|
+
```diff
|
|
9
|
+
{
|
|
10
|
+
...
|
|
11
|
+
"testops": {
|
|
12
|
+
- "chunk": 10
|
|
13
|
+
+ "batch": {
|
|
14
|
+
+ "size": 10
|
|
15
|
+
+ }
|
|
16
|
+
...
|
|
17
|
+
},
|
|
18
|
+
...
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
# qase-javascript-commons@2.0.0-beta.7
|
|
23
|
+
|
|
24
|
+
## What's new
|
|
25
|
+
|
|
26
|
+
TestOps reporter supports uploading test result in real-time.
|
|
27
|
+
It can be useful for long-running tests, where you want to see the results as soon as they are available.
|
|
28
|
+
You can use chunk size to control the size of the data sent to the Qase.
|
|
29
|
+
|
|
30
|
+
To enable real-time reporting, set an environment variable before running the tests or use the reporter's configuration:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
QASE_TESTOPS_CHUNK=10
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```diff
|
|
37
|
+
{
|
|
38
|
+
...
|
|
39
|
+
"testops": {
|
|
40
|
+
+ "chunk": 10
|
|
41
|
+
...
|
|
42
|
+
},
|
|
43
|
+
...
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
where `10` is the size of the chunk in test result's count.
|
|
48
|
+
|
|
1
49
|
# qase-javascript-commons@2.0.0-beta.6
|
|
2
50
|
|
|
3
51
|
## What's new
|
|
@@ -107,9 +107,15 @@ exports.configValidationSchema = {
|
|
|
107
107
|
},
|
|
108
108
|
},
|
|
109
109
|
},
|
|
110
|
-
|
|
111
|
-
type: '
|
|
110
|
+
batch: {
|
|
111
|
+
type: 'object',
|
|
112
112
|
nullable: true,
|
|
113
|
+
properties: {
|
|
114
|
+
size: {
|
|
115
|
+
type: 'number',
|
|
116
|
+
nullable: true,
|
|
117
|
+
},
|
|
118
|
+
},
|
|
113
119
|
},
|
|
114
120
|
defect: {
|
|
115
121
|
type: 'boolean',
|
package/dist/env/env-enum.d.ts
CHANGED
|
@@ -14,7 +14,6 @@ export declare enum EnvEnum {
|
|
|
14
14
|
export declare enum EnvTestOpsEnum {
|
|
15
15
|
project = "QASE_TESTOPS_PROJECT",
|
|
16
16
|
uploadAttachments = "QASE_TESTOPS_UPLOAD_ATTACHMENTS",
|
|
17
|
-
chunk = "QASE_TESTOPS_CHUNK",
|
|
18
17
|
defect = "QASE_TESTOPS_DEFECT",
|
|
19
18
|
useV2 = "QASE_TESTOPS_API_V2"
|
|
20
19
|
}
|
|
@@ -40,6 +39,12 @@ export declare enum EnvRunEnum {
|
|
|
40
39
|
export declare enum EnvPlanEnum {
|
|
41
40
|
id = "QASE_TESTOPS_PLAN_ID"
|
|
42
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* @enum {string}
|
|
44
|
+
*/
|
|
45
|
+
export declare enum EnvBatchEnum {
|
|
46
|
+
size = "QASE_TESTOPS_BATCH_SIZE"
|
|
47
|
+
}
|
|
43
48
|
/**
|
|
44
49
|
* @enum {string}
|
|
45
50
|
*/
|
package/dist/env/env-enum.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EnvLocalEnum = exports.EnvPlanEnum = exports.EnvRunEnum = exports.EnvApiEnum = exports.EnvTestOpsEnum = exports.EnvEnum = void 0;
|
|
3
|
+
exports.EnvLocalEnum = exports.EnvBatchEnum = exports.EnvPlanEnum = exports.EnvRunEnum = exports.EnvApiEnum = exports.EnvTestOpsEnum = exports.EnvEnum = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* @enum {string}
|
|
6
6
|
*/
|
|
@@ -19,7 +19,6 @@ var EnvTestOpsEnum;
|
|
|
19
19
|
(function (EnvTestOpsEnum) {
|
|
20
20
|
EnvTestOpsEnum["project"] = "QASE_TESTOPS_PROJECT";
|
|
21
21
|
EnvTestOpsEnum["uploadAttachments"] = "QASE_TESTOPS_UPLOAD_ATTACHMENTS";
|
|
22
|
-
EnvTestOpsEnum["chunk"] = "QASE_TESTOPS_CHUNK";
|
|
23
22
|
EnvTestOpsEnum["defect"] = "QASE_TESTOPS_DEFECT";
|
|
24
23
|
EnvTestOpsEnum["useV2"] = "QASE_TESTOPS_API_V2";
|
|
25
24
|
})(EnvTestOpsEnum || (exports.EnvTestOpsEnum = EnvTestOpsEnum = {}));
|
|
@@ -48,6 +47,13 @@ var EnvPlanEnum;
|
|
|
48
47
|
(function (EnvPlanEnum) {
|
|
49
48
|
EnvPlanEnum["id"] = "QASE_TESTOPS_PLAN_ID";
|
|
50
49
|
})(EnvPlanEnum || (exports.EnvPlanEnum = EnvPlanEnum = {}));
|
|
50
|
+
/**
|
|
51
|
+
* @enum {string}
|
|
52
|
+
*/
|
|
53
|
+
var EnvBatchEnum;
|
|
54
|
+
(function (EnvBatchEnum) {
|
|
55
|
+
EnvBatchEnum["size"] = "QASE_TESTOPS_BATCH_SIZE";
|
|
56
|
+
})(EnvBatchEnum || (exports.EnvBatchEnum = EnvBatchEnum = {}));
|
|
51
57
|
/**
|
|
52
58
|
* @enum {string}
|
|
53
59
|
*/
|
|
@@ -28,7 +28,9 @@ const envToConfig = (env) => ({
|
|
|
28
28
|
plan: {
|
|
29
29
|
id: env[env_enum_1.EnvPlanEnum.id],
|
|
30
30
|
},
|
|
31
|
-
|
|
31
|
+
batch: {
|
|
32
|
+
size: env[env_enum_1.EnvBatchEnum.size],
|
|
33
|
+
},
|
|
32
34
|
defect: env[env_enum_1.EnvTestOpsEnum.defect],
|
|
33
35
|
useV2: env[env_enum_1.EnvTestOpsEnum.useV2],
|
|
34
36
|
},
|
package/dist/env/env-type.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EnvEnum, EnvTestOpsEnum, EnvApiEnum, EnvRunEnum, EnvLocalEnum, EnvPlanEnum } from './env-enum';
|
|
1
|
+
import { EnvEnum, EnvTestOpsEnum, EnvApiEnum, EnvRunEnum, EnvLocalEnum, EnvPlanEnum, EnvBatchEnum } from './env-enum';
|
|
2
2
|
import { ModeEnum } from '../options';
|
|
3
3
|
import { FormatEnum } from '../writer';
|
|
4
4
|
export type EnvType = {
|
|
@@ -9,7 +9,6 @@ export type EnvType = {
|
|
|
9
9
|
[EnvEnum.captureLogs]?: boolean;
|
|
10
10
|
[EnvTestOpsEnum.project]?: string;
|
|
11
11
|
[EnvTestOpsEnum.uploadAttachments]?: boolean;
|
|
12
|
-
[EnvTestOpsEnum.chunk]?: number;
|
|
13
12
|
[EnvTestOpsEnum.defect]?: boolean;
|
|
14
13
|
[EnvTestOpsEnum.useV2]?: boolean;
|
|
15
14
|
[EnvApiEnum.token]?: string;
|
|
@@ -19,6 +18,7 @@ export type EnvType = {
|
|
|
19
18
|
[EnvRunEnum.description]?: string;
|
|
20
19
|
[EnvRunEnum.complete]?: boolean;
|
|
21
20
|
[EnvPlanEnum.id]?: number;
|
|
21
|
+
[EnvBatchEnum.size]?: number;
|
|
22
22
|
[EnvLocalEnum.path]?: string;
|
|
23
23
|
[EnvLocalEnum.format]?: `${FormatEnum}`;
|
|
24
24
|
};
|
|
@@ -40,10 +40,6 @@ exports.envValidationSchema = {
|
|
|
40
40
|
type: 'boolean',
|
|
41
41
|
nullable: true,
|
|
42
42
|
},
|
|
43
|
-
[env_enum_1.EnvTestOpsEnum.chunk]: {
|
|
44
|
-
type: 'number',
|
|
45
|
-
nullable: true,
|
|
46
|
-
},
|
|
47
43
|
[env_enum_1.EnvTestOpsEnum.defect]: {
|
|
48
44
|
type: 'boolean',
|
|
49
45
|
nullable: true,
|
|
@@ -80,6 +76,10 @@ exports.envValidationSchema = {
|
|
|
80
76
|
type: 'number',
|
|
81
77
|
nullable: true,
|
|
82
78
|
},
|
|
79
|
+
[env_enum_1.EnvBatchEnum.size]: {
|
|
80
|
+
type: 'number',
|
|
81
|
+
nullable: true,
|
|
82
|
+
},
|
|
83
83
|
[env_enum_1.EnvLocalEnum.path]: {
|
|
84
84
|
type: 'string',
|
|
85
85
|
nullable: true,
|
package/dist/qase.d.ts
CHANGED
|
@@ -39,10 +39,14 @@ export declare class QaseReporter extends AbstractReporter {
|
|
|
39
39
|
* @param {LoggerInterface} logger
|
|
40
40
|
*/
|
|
41
41
|
constructor(options: OptionsType, logger?: LoggerInterface);
|
|
42
|
+
/**
|
|
43
|
+
* @returns {Promise<void>}
|
|
44
|
+
*/
|
|
45
|
+
startTestRun(): Promise<void>;
|
|
42
46
|
/**
|
|
43
47
|
* @param {TestResultType} result
|
|
44
48
|
*/
|
|
45
|
-
addTestResult(result: TestResultType): void
|
|
49
|
+
addTestResult(result: TestResultType): Promise<void>;
|
|
46
50
|
/**
|
|
47
51
|
* @param {TestResultType} result
|
|
48
52
|
* @private
|
package/dist/qase.js
CHANGED
|
@@ -119,18 +119,42 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* @returns {Promise<void>}
|
|
124
|
+
*/
|
|
125
|
+
async startTestRun() {
|
|
126
|
+
if (!this.disabled) {
|
|
127
|
+
try {
|
|
128
|
+
await this.upstreamReporter?.startTestRun();
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
this.logError('Unable to start test run in the upstream reporter: ', error);
|
|
132
|
+
if (this.fallbackReporter == undefined) {
|
|
133
|
+
this.disabled = true;
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
await this.fallbackReporter?.startTestRun();
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
this.logError('Unable to start test run in the fallback reporter: ', error);
|
|
141
|
+
this.disabled = true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
122
146
|
/**
|
|
123
147
|
* @param {TestResultType} result
|
|
124
148
|
*/
|
|
125
|
-
addTestResult(result) {
|
|
149
|
+
async addTestResult(result) {
|
|
126
150
|
if (!this.disabled) {
|
|
127
151
|
this.logTestItem(result);
|
|
128
152
|
if (this.useFallback) {
|
|
129
|
-
this.addTestResultToFallback(result);
|
|
153
|
+
await this.addTestResultToFallback(result);
|
|
130
154
|
return;
|
|
131
155
|
}
|
|
132
156
|
try {
|
|
133
|
-
this.upstreamReporter?.addTestResult(result);
|
|
157
|
+
await this.upstreamReporter?.addTestResult(result);
|
|
134
158
|
}
|
|
135
159
|
catch (error) {
|
|
136
160
|
this.logError('Unable to add the result to the upstream reporter:', error);
|
|
@@ -142,7 +166,7 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
142
166
|
this.fallbackReporter.setTestResults(this.upstreamReporter?.getTestResults() ?? []);
|
|
143
167
|
this.useFallback = true;
|
|
144
168
|
}
|
|
145
|
-
this.addTestResultToFallback(result);
|
|
169
|
+
await this.addTestResultToFallback(result);
|
|
146
170
|
}
|
|
147
171
|
}
|
|
148
172
|
}
|
|
@@ -150,9 +174,9 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
150
174
|
* @param {TestResultType} result
|
|
151
175
|
* @private
|
|
152
176
|
*/
|
|
153
|
-
addTestResultToFallback(result) {
|
|
177
|
+
async addTestResultToFallback(result) {
|
|
154
178
|
try {
|
|
155
|
-
this.fallbackReporter?.addTestResult(result);
|
|
179
|
+
await this.fallbackReporter?.addTestResult(result);
|
|
156
180
|
}
|
|
157
181
|
catch (error) {
|
|
158
182
|
this.logError('Unable to add the result to the fallback reporter:', error);
|
|
@@ -208,7 +232,7 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
208
232
|
const { frameworkPackage, frameworkName, reporterName, environment, report = {}, testops = {}, ...commonOptions } = options;
|
|
209
233
|
switch (mode) {
|
|
210
234
|
case options_1.ModeEnum.testops: {
|
|
211
|
-
const { api: { token, headers, ...api } = {}, project, run: { title, description, ...run } = {}, plan = {},
|
|
235
|
+
const { api: { token, headers, ...api } = {}, project, run: { title, description, ...run } = {}, plan = {}, batch = {}, uploadAttachments, } = testops;
|
|
212
236
|
if (!token) {
|
|
213
237
|
throw new Error(`Either "testops.api.token" parameter or "${env_1.EnvApiEnum.token}" environment variable is required in "testops" mode`);
|
|
214
238
|
}
|
|
@@ -232,7 +256,7 @@ class QaseReporter extends reporters_1.AbstractReporter {
|
|
|
232
256
|
...run,
|
|
233
257
|
},
|
|
234
258
|
plan,
|
|
235
|
-
|
|
259
|
+
batch,
|
|
236
260
|
debug: commonOptions.debug,
|
|
237
261
|
captureLogs: commonOptions.captureLogs,
|
|
238
262
|
}, apiClient, logger, typeof environment === 'number' ? environment : undefined);
|
|
@@ -9,8 +9,9 @@ export interface ReporterOptionsType {
|
|
|
9
9
|
captureLogs?: boolean | undefined;
|
|
10
10
|
}
|
|
11
11
|
export interface ReporterInterface {
|
|
12
|
-
addTestResult(result: TestResultType): void
|
|
12
|
+
addTestResult(result: TestResultType): Promise<void>;
|
|
13
13
|
publish(): Promise<void>;
|
|
14
|
+
startTestRun(): Promise<void>;
|
|
14
15
|
getTestResults(): TestResultType[];
|
|
15
16
|
setTestResults(results: TestResultType[]): void;
|
|
16
17
|
isCaptureLogs(): boolean;
|
|
@@ -41,6 +42,10 @@ export declare abstract class AbstractReporter implements ReporterInterface {
|
|
|
41
42
|
* @returns {Promise<void>}
|
|
42
43
|
*/
|
|
43
44
|
abstract publish(): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* @returns {Promise<void>}
|
|
47
|
+
*/
|
|
48
|
+
abstract startTestRun(): Promise<void>;
|
|
44
49
|
/**
|
|
45
50
|
* @param {ReporterOptionsType} options
|
|
46
51
|
* @param {LoggerInterface} logger
|
|
@@ -58,7 +63,7 @@ export declare abstract class AbstractReporter implements ReporterInterface {
|
|
|
58
63
|
/**
|
|
59
64
|
* @param {TestResultType} result
|
|
60
65
|
*/
|
|
61
|
-
addTestResult(result: TestResultType): void
|
|
66
|
+
addTestResult(result: TestResultType): Promise<void>;
|
|
62
67
|
/**
|
|
63
68
|
* @param {TestResultType[]} results
|
|
64
69
|
*/
|
|
@@ -45,7 +45,8 @@ class AbstractReporter {
|
|
|
45
45
|
/**
|
|
46
46
|
* @param {TestResultType} result
|
|
47
47
|
*/
|
|
48
|
-
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
49
|
+
async addTestResult(result) {
|
|
49
50
|
if (result.testops_id === null || !Array.isArray(result.testops_id)) {
|
|
50
51
|
this.results.push(result);
|
|
51
52
|
return;
|
|
@@ -8,7 +8,7 @@ export declare class ReportReporter extends AbstractReporter {
|
|
|
8
8
|
private writer;
|
|
9
9
|
private readonly environment;
|
|
10
10
|
private readonly runId;
|
|
11
|
-
private
|
|
11
|
+
private startTime;
|
|
12
12
|
/**
|
|
13
13
|
* @param {ReporterOptionsType} options
|
|
14
14
|
* @param {WriterInterface} writer
|
|
@@ -17,10 +17,13 @@ export declare class ReportReporter extends AbstractReporter {
|
|
|
17
17
|
* @param {number | undefined} runId
|
|
18
18
|
*/
|
|
19
19
|
constructor(options: ReporterOptionsType | undefined, writer: WriterInterface, logger?: LoggerInterface, environment?: string, runId?: number);
|
|
20
|
+
/**
|
|
21
|
+
* @returns {Promise<void>}
|
|
22
|
+
*/
|
|
23
|
+
startTestRun(): Promise<void>;
|
|
20
24
|
/**
|
|
21
25
|
* @returns {Promise<void>}
|
|
22
26
|
*
|
|
23
|
-
* eslint-disable-next-line @typescript-eslint/require-await
|
|
24
27
|
*/
|
|
25
28
|
publish(): Promise<void>;
|
|
26
29
|
/**
|
|
@@ -48,10 +48,16 @@ class ReportReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
48
48
|
this.environment = environment;
|
|
49
49
|
this.runId = runId;
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* @returns {Promise<void>}
|
|
53
|
+
*/
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
55
|
+
async startTestRun() {
|
|
56
|
+
this.startTime = Date.now();
|
|
57
|
+
}
|
|
51
58
|
/**
|
|
52
59
|
* @returns {Promise<void>}
|
|
53
60
|
*
|
|
54
|
-
* eslint-disable-next-line @typescript-eslint/require-await
|
|
55
61
|
*/
|
|
56
62
|
async publish() {
|
|
57
63
|
const report = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { QaseApiInterface, ResultStepStatus, TestStepResultCreateStatusEnum } from 'qaseio';
|
|
2
2
|
import { AbstractReporter, LoggerInterface, ReporterOptionsType } from './abstract-reporter';
|
|
3
|
-
import { StepStatusEnum, TestStatusEnum } from '../models';
|
|
3
|
+
import { StepStatusEnum, TestResultType, TestStatusEnum } from '../models';
|
|
4
4
|
export type TestOpsRunType = {
|
|
5
5
|
id?: number | undefined;
|
|
6
6
|
title: string;
|
|
@@ -10,12 +10,15 @@ export type TestOpsRunType = {
|
|
|
10
10
|
export type TestOpsPlanType = {
|
|
11
11
|
id?: number | undefined;
|
|
12
12
|
};
|
|
13
|
+
export type TestOpsBatchType = {
|
|
14
|
+
size?: number | undefined;
|
|
15
|
+
};
|
|
13
16
|
export type TestOpsOptionsType = {
|
|
14
17
|
project: string;
|
|
15
18
|
uploadAttachments?: boolean | undefined;
|
|
16
19
|
run: TestOpsRunType;
|
|
17
20
|
plan: TestOpsPlanType;
|
|
18
|
-
|
|
21
|
+
batch?: TestOpsBatchType;
|
|
19
22
|
defect?: boolean | undefined;
|
|
20
23
|
useV2?: boolean | undefined;
|
|
21
24
|
};
|
|
@@ -66,7 +69,7 @@ export declare class TestOpsReporter extends AbstractReporter {
|
|
|
66
69
|
* @type {TestResultType[]}
|
|
67
70
|
* @private
|
|
68
71
|
*/
|
|
69
|
-
private readonly
|
|
72
|
+
private readonly batchSize;
|
|
70
73
|
/**
|
|
71
74
|
* @type {boolean | undefined}
|
|
72
75
|
* @private
|
|
@@ -77,6 +80,16 @@ export declare class TestOpsReporter extends AbstractReporter {
|
|
|
77
80
|
* @private
|
|
78
81
|
*/
|
|
79
82
|
private readonly defect;
|
|
83
|
+
/**
|
|
84
|
+
* @type {number}
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
private firstIndex;
|
|
88
|
+
/**
|
|
89
|
+
* @type {boolean}
|
|
90
|
+
* @private
|
|
91
|
+
*/
|
|
92
|
+
private isTestRunReady;
|
|
80
93
|
/**
|
|
81
94
|
* @param {ReporterOptionsType & TestOpsOptionsType} options
|
|
82
95
|
* @param {QaseApiInterface} api
|
|
@@ -84,6 +97,25 @@ export declare class TestOpsReporter extends AbstractReporter {
|
|
|
84
97
|
* @param {number} environment
|
|
85
98
|
*/
|
|
86
99
|
constructor(options: ReporterOptionsType & TestOpsOptionsType, api: QaseApiInterface, logger?: LoggerInterface, environment?: number);
|
|
100
|
+
/**
|
|
101
|
+
* @returns {Promise<void>}
|
|
102
|
+
*/
|
|
103
|
+
startTestRun(): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* @param {TestResultType} result
|
|
106
|
+
* @returns {Promise<void>}
|
|
107
|
+
*/
|
|
108
|
+
addTestResult(result: TestResultType): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* @returns {Promise<void>}
|
|
111
|
+
*/
|
|
112
|
+
private checkOrCreateTestRun;
|
|
113
|
+
/**
|
|
114
|
+
* @returns {Promise<void>}
|
|
115
|
+
* @param testResults
|
|
116
|
+
* @private
|
|
117
|
+
*/
|
|
118
|
+
private publishResults;
|
|
87
119
|
/**
|
|
88
120
|
* @returns {Promise<void>}
|
|
89
121
|
*/
|
|
@@ -26,72 +26,113 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
26
26
|
const { project, uploadAttachments, run, ...restOptions } = options;
|
|
27
27
|
super(restOptions, logger);
|
|
28
28
|
this.api = api;
|
|
29
|
+
/**
|
|
30
|
+
* @type {number}
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
this.firstIndex = 0;
|
|
34
|
+
/**
|
|
35
|
+
* @type {boolean}
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
this.isTestRunReady = false;
|
|
29
39
|
const baseUrl = 'https://app.qase.io';
|
|
30
40
|
this.baseUrl = baseUrl.replace(/\/$/, '');
|
|
31
41
|
this.projectCode = project;
|
|
32
42
|
this.isUploadAttachments = uploadAttachments;
|
|
33
43
|
this.run = { complete: true, ...run };
|
|
34
44
|
this.environment = environment;
|
|
35
|
-
this.
|
|
45
|
+
this.batchSize = options.batch?.size ?? defaultChunkSize;
|
|
36
46
|
this.useV2 = options.useV2 ?? false;
|
|
37
47
|
this.defect = options.defect ?? false;
|
|
38
48
|
}
|
|
39
49
|
/**
|
|
40
50
|
* @returns {Promise<void>}
|
|
41
51
|
*/
|
|
42
|
-
async
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
async startTestRun() {
|
|
53
|
+
await this.checkOrCreateTestRun();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* @param {TestResultType} result
|
|
57
|
+
* @returns {Promise<void>}
|
|
58
|
+
*/
|
|
59
|
+
async addTestResult(result) {
|
|
60
|
+
await super.addTestResult(result);
|
|
61
|
+
if (!this.isTestRunReady) {
|
|
62
|
+
return;
|
|
47
63
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
runId = result.id;
|
|
64
|
+
const countOfResults = this.batchSize + this.firstIndex;
|
|
65
|
+
if (this.results.length >= countOfResults) {
|
|
66
|
+
await this.publishResults(this.results.slice(this.firstIndex, countOfResults));
|
|
67
|
+
this.firstIndex = countOfResults;
|
|
54
68
|
}
|
|
55
|
-
|
|
56
|
-
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* @returns {Promise<void>}
|
|
72
|
+
*/
|
|
73
|
+
async checkOrCreateTestRun() {
|
|
74
|
+
if (this.run.id !== undefined) {
|
|
75
|
+
await this.checkRun(this.run.id);
|
|
76
|
+
this.isTestRunReady = true;
|
|
57
77
|
return;
|
|
58
78
|
}
|
|
79
|
+
const { result } = await this.createRun(this.run.title, this.run.description, this.environment);
|
|
80
|
+
if (!result?.id) {
|
|
81
|
+
throw new Error('Cannot create run.');
|
|
82
|
+
}
|
|
83
|
+
this.run.id = result.id;
|
|
84
|
+
this.isTestRunReady = true;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* @returns {Promise<void>}
|
|
88
|
+
* @param testResults
|
|
89
|
+
* @private
|
|
90
|
+
*/
|
|
91
|
+
async publishResults(testResults) {
|
|
59
92
|
if (this.useV2) {
|
|
60
93
|
const results = [];
|
|
61
|
-
for (const result of
|
|
94
|
+
for (const result of testResults) {
|
|
62
95
|
const resultCreateV2 = await this.transformTestResult(result);
|
|
63
96
|
results.push(resultCreateV2);
|
|
64
97
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
});
|
|
69
|
-
}
|
|
98
|
+
await this.api.result.createResultsV2(this.projectCode, this.run.id, {
|
|
99
|
+
results: results,
|
|
100
|
+
});
|
|
70
101
|
}
|
|
71
102
|
else {
|
|
72
103
|
const results = [];
|
|
73
|
-
for (const result of
|
|
104
|
+
for (const result of testResults) {
|
|
74
105
|
const resultCreate = await this.transformTestResultV1(result);
|
|
75
106
|
results.push(resultCreate);
|
|
76
107
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
108
|
+
await this.api.results.createResultBulk(this.projectCode, this.run.id, {
|
|
109
|
+
results: results,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
this.log((0, chalk_1.default) `{green ${testResults.length} result(s) sent to Qase}`);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* @returns {Promise<void>}
|
|
116
|
+
*/
|
|
117
|
+
async publish() {
|
|
118
|
+
if (this.results.length === 0) {
|
|
119
|
+
this.log((0, chalk_1.default) `{yellow No results to send to Qase}`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (this.firstIndex < this.results.length) {
|
|
123
|
+
await this.publishResults(this.results.slice(this.firstIndex));
|
|
82
124
|
}
|
|
83
|
-
this.log((0, chalk_1.default) `{green ${this.results.length} result(s) sent to Qase}`);
|
|
84
125
|
if (!this.run.complete) {
|
|
85
126
|
return;
|
|
86
127
|
}
|
|
87
128
|
try {
|
|
88
|
-
await this.api.runs.completeRun(this.projectCode,
|
|
89
|
-
this.log((0, chalk_1.default) `{green Run ${
|
|
129
|
+
await this.api.runs.completeRun(this.projectCode, this.run.id);
|
|
130
|
+
this.log((0, chalk_1.default) `{green Run ${this.run.id} completed}`);
|
|
90
131
|
}
|
|
91
132
|
catch (error) {
|
|
92
133
|
throw new qase_error_1.QaseError('Error on completing run', { cause: error });
|
|
93
134
|
}
|
|
94
|
-
const runUrl = `${this.baseUrl}/run/${this.projectCode}/dashboard/${
|
|
135
|
+
const runUrl = `${this.baseUrl}/run/${this.projectCode}/dashboard/${this.run.id}`;
|
|
95
136
|
this.log((0, chalk_1.default) `{blue Test run link: ${runUrl}}`);
|
|
96
137
|
}
|
|
97
138
|
/**
|