qase-javascript-commons 2.0.0-beta.1 → 2.0.0-beta.2
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/changelog.md +23 -0
- package/dist/config/config-validation-schema.js +22 -6
- package/dist/env/env-enum.d.ts +14 -7
- package/dist/env/env-enum.js +14 -6
- package/dist/env/env-to-config.js +6 -3
- package/dist/env/env-type.d.ts +7 -4
- package/dist/env/env-validation-schema.js +15 -4
- package/dist/formatter/index.d.ts +1 -0
- package/dist/formatter/index.js +3 -1
- package/dist/formatter/jsonp-formatter.d.ts +13 -0
- package/dist/formatter/jsonp-formatter.js +28 -0
- package/dist/models/attachment.d.ts +8 -0
- package/dist/models/attachment.js +2 -0
- package/dist/models/execution-sum.d.ts +6 -0
- package/dist/models/execution-sum.js +2 -0
- package/dist/models/host-data.d.ts +11 -0
- package/dist/models/host-data.js +2 -0
- package/dist/models/index.d.ts +6 -2
- package/dist/models/index.js +4 -4
- package/dist/models/report.d.ts +14 -0
- package/dist/models/report.js +2 -0
- package/dist/models/short-result.d.ts +7 -0
- package/dist/models/short-result.js +2 -0
- package/dist/models/stats.d.ts +8 -0
- package/dist/models/stats.js +2 -0
- package/dist/models/step-data.d.ts +4 -0
- package/dist/models/step-data.js +2 -0
- package/dist/models/step-execution.d.ts +11 -0
- package/dist/models/step-execution.js +9 -0
- package/dist/models/test-execution.d.ts +19 -0
- package/dist/models/test-execution.js +15 -0
- package/dist/models/test-result.d.ts +14 -20
- package/dist/models/test-result.js +0 -13
- package/dist/models/test-step.d.ts +9 -11
- package/dist/models/test-step.js +0 -7
- package/dist/options/options-type.d.ts +1 -0
- package/dist/qase.d.ts +22 -2
- package/dist/qase.js +103 -25
- package/dist/reporters/abstract-reporter.d.ts +18 -7
- package/dist/reporters/abstract-reporter.js +37 -2
- package/dist/reporters/report-reporter.d.ts +24 -12
- package/dist/reporters/report-reporter.js +152 -13
- package/dist/reporters/testops-reporter.d.ts +26 -49
- package/dist/reporters/testops-reporter.js +87 -155
- package/dist/writer/driver-enum.d.ts +7 -0
- package/dist/writer/driver-enum.js +9 -1
- package/dist/writer/fs-writer.d.ts +17 -8
- package/dist/writer/fs-writer.js +55 -8
- package/dist/writer/index.d.ts +1 -1
- package/dist/writer/index.js +2 -1
- package/dist/writer/writer-interface.d.ts +4 -2
- package/package.json +4 -3
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
import { QaseApiInterface,
|
|
1
|
+
import { QaseApiInterface, ResultStepStatus } from 'qaseio';
|
|
2
2
|
import { AbstractReporter, LoggerInterface, ReporterOptionsType } from './abstract-reporter';
|
|
3
|
-
import { StepStatusEnum,
|
|
3
|
+
import { StepStatusEnum, TestStatusEnum } from '../models';
|
|
4
4
|
export type TestOpsRunType = {
|
|
5
5
|
id?: number | undefined;
|
|
6
6
|
title: string;
|
|
7
7
|
description: string;
|
|
8
8
|
complete?: boolean | undefined;
|
|
9
|
-
|
|
9
|
+
};
|
|
10
|
+
export type TestOpsPlanType = {
|
|
11
|
+
id?: number | undefined;
|
|
10
12
|
};
|
|
11
13
|
export type TestOpsOptionsType = {
|
|
12
14
|
project: string;
|
|
13
|
-
baseUrl?: string | undefined;
|
|
14
15
|
uploadAttachments?: boolean | undefined;
|
|
15
16
|
run: TestOpsRunType;
|
|
17
|
+
plan: TestOpsPlanType;
|
|
18
|
+
chunk?: number | undefined;
|
|
19
|
+
defect?: boolean | undefined;
|
|
16
20
|
};
|
|
17
21
|
/**
|
|
18
22
|
* @class TestOpsReporter
|
|
@@ -21,90 +25,69 @@ export type TestOpsOptionsType = {
|
|
|
21
25
|
export declare class TestOpsReporter extends AbstractReporter {
|
|
22
26
|
private api;
|
|
23
27
|
/**
|
|
24
|
-
* @type {Record<TestStatusEnum,
|
|
28
|
+
* @type {Record<TestStatusEnum, string>}
|
|
25
29
|
*/
|
|
26
|
-
static statusMap: Record<TestStatusEnum,
|
|
30
|
+
static statusMap: Record<TestStatusEnum, string>;
|
|
27
31
|
/**
|
|
28
|
-
* @type {Record<StepStatusEnum,
|
|
32
|
+
* @type {Record<StepStatusEnum, ResultStepStatus>}
|
|
29
33
|
*/
|
|
30
|
-
static stepStatusMap: Record<StepStatusEnum,
|
|
34
|
+
static stepStatusMap: Record<StepStatusEnum, ResultStepStatus>;
|
|
31
35
|
/**
|
|
32
36
|
* @type {string}
|
|
33
37
|
* @private
|
|
34
38
|
*/
|
|
35
|
-
private baseUrl;
|
|
39
|
+
private readonly baseUrl;
|
|
36
40
|
/**
|
|
37
41
|
* @type {string}
|
|
38
42
|
* @private
|
|
39
43
|
*/
|
|
40
|
-
private projectCode;
|
|
44
|
+
private readonly projectCode;
|
|
41
45
|
/**
|
|
42
46
|
* @type {boolean | undefined}
|
|
43
47
|
* @private
|
|
44
48
|
*/
|
|
45
|
-
private
|
|
49
|
+
private readonly isUploadAttachments;
|
|
46
50
|
/**
|
|
47
51
|
* @type {TestOpsRunType}
|
|
48
52
|
* @private
|
|
49
53
|
*/
|
|
50
54
|
private run;
|
|
51
55
|
/**
|
|
52
|
-
* @type {
|
|
56
|
+
* @type { number | undefined}
|
|
53
57
|
* @private
|
|
54
58
|
*/
|
|
55
|
-
private
|
|
59
|
+
private readonly environment;
|
|
56
60
|
/**
|
|
57
|
-
* @type {
|
|
58
|
-
* @private
|
|
59
|
-
*/
|
|
60
|
-
private attachments;
|
|
61
|
-
/**
|
|
62
|
-
* @type {Record<string, string[]>}
|
|
61
|
+
* @type {TestResultType[]}
|
|
63
62
|
* @private
|
|
64
63
|
*/
|
|
65
|
-
private
|
|
64
|
+
private readonly chunk;
|
|
66
65
|
/**
|
|
67
66
|
* @param {ReporterOptionsType & TestOpsOptionsType} options
|
|
68
67
|
* @param {QaseApiInterface} api
|
|
69
68
|
* @param {LoggerInterface} logger
|
|
69
|
+
* @param {number} environment
|
|
70
70
|
*/
|
|
71
|
-
constructor(options: ReporterOptionsType & TestOpsOptionsType, api: QaseApiInterface, logger?: LoggerInterface);
|
|
72
|
-
/**
|
|
73
|
-
* @param {TestResultType} result
|
|
74
|
-
*/
|
|
75
|
-
addTestResult(result: TestResultType): void;
|
|
76
|
-
private addAttachments;
|
|
71
|
+
constructor(options: ReporterOptionsType & TestOpsOptionsType, api: QaseApiInterface, logger?: LoggerInterface, environment?: number);
|
|
77
72
|
/**
|
|
78
73
|
* @returns {Promise<void>}
|
|
79
74
|
*/
|
|
80
75
|
publish(): Promise<void>;
|
|
81
76
|
/**
|
|
82
77
|
* @param {TestResultType} result
|
|
83
|
-
* @returns
|
|
78
|
+
* @returns Promise<ResultCreateV2>
|
|
84
79
|
* @private
|
|
85
80
|
*/
|
|
86
81
|
private transformTestResult;
|
|
87
82
|
/**
|
|
88
|
-
* @param {string | string[]} suiteTitle
|
|
89
|
-
* @returns {RelationSuiteItem[]}
|
|
90
|
-
* @private
|
|
91
|
-
*/
|
|
92
|
-
private getSuites;
|
|
93
|
-
/**
|
|
94
|
-
* @param {TestResultType} result
|
|
95
83
|
* @returns {ResultExecution}
|
|
96
84
|
* @private
|
|
85
|
+
* @param {TestExecution} exec
|
|
97
86
|
*/
|
|
98
87
|
private getExecution;
|
|
99
|
-
/**
|
|
100
|
-
* @param {string} id
|
|
101
|
-
* @returns {ResultAttachment[]}
|
|
102
|
-
* @private
|
|
103
|
-
*/
|
|
104
|
-
private getAttachmentsFor;
|
|
105
88
|
/**
|
|
106
89
|
* @param {TestStepType[]} steps
|
|
107
|
-
* @returns
|
|
90
|
+
* @returns Promise<ResultStep[]>
|
|
108
91
|
* @private
|
|
109
92
|
*/
|
|
110
93
|
private transformSteps;
|
|
@@ -118,7 +101,7 @@ export declare class TestOpsReporter extends AbstractReporter {
|
|
|
118
101
|
* @param {string} title
|
|
119
102
|
* @param {string} description
|
|
120
103
|
* @param {number | undefined} environment
|
|
121
|
-
* @returns {Promise<
|
|
104
|
+
* @returns {Promise<IdResponse>}
|
|
122
105
|
* @private
|
|
123
106
|
*/
|
|
124
107
|
private createRun;
|
|
@@ -126,11 +109,5 @@ export declare class TestOpsReporter extends AbstractReporter {
|
|
|
126
109
|
* @returns {Promise<void>}
|
|
127
110
|
* @private
|
|
128
111
|
*/
|
|
129
|
-
private
|
|
130
|
-
/**
|
|
131
|
-
* @param {string[]} attachments
|
|
132
|
-
* @returns {Promise<AttachmentGet[]>}
|
|
133
|
-
* @private
|
|
134
|
-
*/
|
|
135
|
-
private doUploadAttachments;
|
|
112
|
+
private uploadAttachments;
|
|
136
113
|
}
|
|
@@ -6,11 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.TestOpsReporter = void 0;
|
|
7
7
|
const fs_1 = require("fs");
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
-
const strip_ansi_1 = __importDefault(require("strip-ansi"));
|
|
10
9
|
const qaseio_1 = require("qaseio");
|
|
11
10
|
const abstract_reporter_1 = require("./abstract-reporter");
|
|
12
11
|
const models_1 = require("../models");
|
|
13
12
|
const qase_error_1 = require("../utils/qase-error");
|
|
13
|
+
const defaultChunkSize = 200;
|
|
14
14
|
/**
|
|
15
15
|
* @class TestOpsReporter
|
|
16
16
|
* @extends AbstractReporter
|
|
@@ -20,47 +20,19 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
20
20
|
* @param {ReporterOptionsType & TestOpsOptionsType} options
|
|
21
21
|
* @param {QaseApiInterface} api
|
|
22
22
|
* @param {LoggerInterface} logger
|
|
23
|
+
* @param {number} environment
|
|
23
24
|
*/
|
|
24
|
-
constructor(options, api, logger) {
|
|
25
|
-
const { project,
|
|
25
|
+
constructor(options, api, logger, environment) {
|
|
26
|
+
const { project, uploadAttachments, run, ...restOptions } = options;
|
|
26
27
|
super(restOptions, logger);
|
|
27
28
|
this.api = api;
|
|
28
|
-
|
|
29
|
-
* @type {TestResultType[]}
|
|
30
|
-
* @private
|
|
31
|
-
*/
|
|
32
|
-
this.results = [];
|
|
33
|
-
/**
|
|
34
|
-
* @type {Record<string, string[]>}
|
|
35
|
-
* @private
|
|
36
|
-
*/
|
|
37
|
-
this.attachments = {};
|
|
38
|
-
/**
|
|
39
|
-
* @type {Record<string, string[]>}
|
|
40
|
-
* @private
|
|
41
|
-
*/
|
|
42
|
-
this.attachmentsMap = {};
|
|
29
|
+
const baseUrl = 'https://app.qase.io';
|
|
43
30
|
this.baseUrl = baseUrl.replace(/\/$/, '');
|
|
44
31
|
this.projectCode = project;
|
|
45
|
-
this.
|
|
32
|
+
this.isUploadAttachments = uploadAttachments;
|
|
46
33
|
this.run = { complete: true, ...run };
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* @param {TestResultType} result
|
|
50
|
-
*/
|
|
51
|
-
addTestResult(result) {
|
|
52
|
-
this.results.push(result);
|
|
53
|
-
this.addAttachments(result);
|
|
54
|
-
}
|
|
55
|
-
addAttachments(resultOrStep) {
|
|
56
|
-
if (resultOrStep.attachments) {
|
|
57
|
-
this.attachments[resultOrStep.id] = resultOrStep.attachments;
|
|
58
|
-
}
|
|
59
|
-
if (resultOrStep.steps) {
|
|
60
|
-
for (const step of resultOrStep.steps) {
|
|
61
|
-
this.addAttachments(step);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
34
|
+
this.environment = environment;
|
|
35
|
+
this.chunk = options.chunk ?? defaultChunkSize;
|
|
64
36
|
}
|
|
65
37
|
/**
|
|
66
38
|
* @returns {Promise<void>}
|
|
@@ -72,7 +44,7 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
72
44
|
runId = this.run.id;
|
|
73
45
|
}
|
|
74
46
|
else {
|
|
75
|
-
const { result } = await this.createRun(this.run.title, this.run.description, this.
|
|
47
|
+
const { result } = await this.createRun(this.run.title, this.run.description, this.environment);
|
|
76
48
|
if (!result?.id) {
|
|
77
49
|
throw new Error('Cannot create run.');
|
|
78
50
|
}
|
|
@@ -82,12 +54,16 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
82
54
|
this.log('No test cases were matched. Ensure that your tests are declared correctly.');
|
|
83
55
|
return;
|
|
84
56
|
}
|
|
85
|
-
|
|
86
|
-
|
|
57
|
+
const results = [];
|
|
58
|
+
for (const result of this.results) {
|
|
59
|
+
const resultCreateV2 = await this.transformTestResult(result);
|
|
60
|
+
results.push(resultCreateV2);
|
|
61
|
+
}
|
|
62
|
+
for (let i = 0; i < results.length; i += this.chunk) {
|
|
63
|
+
await this.api.result.createResultsV2(this.projectCode, runId, {
|
|
64
|
+
results: results.slice(i, i + this.chunk),
|
|
65
|
+
});
|
|
87
66
|
}
|
|
88
|
-
await this.api.result.createResultsV2(this.projectCode, runId, {
|
|
89
|
-
results: this.results.map((result) => this.transformTestResult(result)),
|
|
90
|
-
});
|
|
91
67
|
this.log((0, chalk_1.default) `{green ${this.results.length} result(s) sent to Qase}`);
|
|
92
68
|
if (!this.run.complete) {
|
|
93
69
|
return;
|
|
@@ -104,104 +80,66 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
104
80
|
}
|
|
105
81
|
/**
|
|
106
82
|
* @param {TestResultType} result
|
|
107
|
-
* @returns
|
|
83
|
+
* @returns Promise<ResultCreateV2>
|
|
108
84
|
* @private
|
|
109
85
|
*/
|
|
110
|
-
transformTestResult(result) {
|
|
111
|
-
const
|
|
86
|
+
async transformTestResult(result) {
|
|
87
|
+
const attachments = await this.uploadAttachments(result.attachments);
|
|
88
|
+
const steps = await this.transformSteps(result.steps);
|
|
89
|
+
return {
|
|
112
90
|
title: result.title,
|
|
113
|
-
|
|
114
|
-
|
|
91
|
+
execution: this.getExecution(result.execution),
|
|
92
|
+
testops_id: Array.isArray(result.testops_id) ? null : result.testops_id,
|
|
93
|
+
attachments: attachments,
|
|
94
|
+
steps: steps,
|
|
95
|
+
params: {},
|
|
96
|
+
relations: {
|
|
97
|
+
// suite: {
|
|
98
|
+
// data: result.suiteTitle ? this.getSuites(result.suiteTitle) : [],
|
|
99
|
+
// },
|
|
100
|
+
},
|
|
101
|
+
message: result.message,
|
|
115
102
|
};
|
|
116
|
-
if (result.suiteTitle) {
|
|
117
|
-
resultObject.relations = {
|
|
118
|
-
suite: {
|
|
119
|
-
data: this.getSuites(result.suiteTitle),
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
if (result.testOpsId[0]) {
|
|
124
|
-
resultObject.testops_id = result.testOpsId[0];
|
|
125
|
-
}
|
|
126
|
-
if (result.error) {
|
|
127
|
-
resultObject.message = (0, strip_ansi_1.default)(result.error.message);
|
|
128
|
-
}
|
|
129
|
-
if (result.steps) {
|
|
130
|
-
resultObject.steps = this.transformSteps(result.steps);
|
|
131
|
-
}
|
|
132
|
-
return resultObject;
|
|
133
103
|
}
|
|
134
104
|
/**
|
|
135
|
-
* @param {string | string[]} suiteTitle
|
|
136
|
-
* @returns {RelationSuiteItem[]}
|
|
137
|
-
* @private
|
|
138
|
-
*/
|
|
139
|
-
getSuites(suiteTitle) {
|
|
140
|
-
const suiteTitles = Array.isArray(suiteTitle) ? suiteTitle : suiteTitle.split('\t');
|
|
141
|
-
return suiteTitles.map((title) => ({ title }));
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* @param {TestResultType} result
|
|
145
105
|
* @returns {ResultExecution}
|
|
146
106
|
* @private
|
|
107
|
+
* @param {TestExecution} exec
|
|
147
108
|
*/
|
|
148
|
-
getExecution(
|
|
149
|
-
|
|
150
|
-
status: TestOpsReporter.statusMap[
|
|
109
|
+
getExecution(exec) {
|
|
110
|
+
return {
|
|
111
|
+
status: TestOpsReporter.statusMap[exec.status],
|
|
112
|
+
start_time: exec.start_time,
|
|
113
|
+
end_time: exec.end_time,
|
|
114
|
+
duration: exec.duration,
|
|
115
|
+
stacktrace: exec.stacktrace,
|
|
116
|
+
thread: exec.thread,
|
|
151
117
|
};
|
|
152
|
-
if (result.startTime) {
|
|
153
|
-
execution.start_time = result.startTime;
|
|
154
|
-
}
|
|
155
|
-
if (result.duration) {
|
|
156
|
-
execution.duration = result.duration;
|
|
157
|
-
}
|
|
158
|
-
if (result.endTime) {
|
|
159
|
-
execution.end_time = result.endTime;
|
|
160
|
-
}
|
|
161
|
-
if (result.error) {
|
|
162
|
-
execution.stacktrace = (0, strip_ansi_1.default)(String(result.error.stack));
|
|
163
|
-
}
|
|
164
|
-
return execution;
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* @param {string} id
|
|
168
|
-
* @returns {ResultAttachment[]}
|
|
169
|
-
* @private
|
|
170
|
-
*/
|
|
171
|
-
getAttachmentsFor(id) {
|
|
172
|
-
const attachments = this.attachmentsMap[id];
|
|
173
|
-
if (!attachments) {
|
|
174
|
-
return [];
|
|
175
|
-
}
|
|
176
|
-
return attachments.reduce((acc, attachment) => {
|
|
177
|
-
if (attachment.hash) {
|
|
178
|
-
acc.push({ id: attachment.hash });
|
|
179
|
-
}
|
|
180
|
-
return acc;
|
|
181
|
-
}, []);
|
|
182
118
|
}
|
|
183
119
|
/**
|
|
184
120
|
* @param {TestStepType[]} steps
|
|
185
|
-
* @returns
|
|
121
|
+
* @returns Promise<ResultStep[]>
|
|
186
122
|
* @private
|
|
187
123
|
*/
|
|
188
|
-
transformSteps(steps) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
124
|
+
async transformSteps(steps) {
|
|
125
|
+
const resultsSteps = [];
|
|
126
|
+
for (const step of steps) {
|
|
127
|
+
const attachmentHashes = await this.uploadAttachments(step.attachments);
|
|
128
|
+
const resultStep = {
|
|
192
129
|
data: {
|
|
193
|
-
action:
|
|
130
|
+
action: step.data.action,
|
|
131
|
+
attachments: attachmentHashes,
|
|
194
132
|
},
|
|
195
133
|
execution: {
|
|
196
|
-
status: TestOpsReporter.stepStatusMap[status],
|
|
134
|
+
status: TestOpsReporter.stepStatusMap[step.execution.status],
|
|
197
135
|
},
|
|
198
|
-
attachments: this.getAttachmentsFor(id),
|
|
199
136
|
};
|
|
200
|
-
if (steps) {
|
|
201
|
-
|
|
137
|
+
if (step.steps.length > 0) {
|
|
138
|
+
resultStep.steps = await this.transformSteps(step.steps);
|
|
202
139
|
}
|
|
203
|
-
|
|
204
|
-
}
|
|
140
|
+
resultsSteps.push(resultStep);
|
|
141
|
+
}
|
|
142
|
+
return resultsSteps;
|
|
205
143
|
}
|
|
206
144
|
/**
|
|
207
145
|
* @param {number} runId
|
|
@@ -221,7 +159,7 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
221
159
|
* @param {string} title
|
|
222
160
|
* @param {string} description
|
|
223
161
|
* @param {number | undefined} environment
|
|
224
|
-
* @returns {Promise<
|
|
162
|
+
* @returns {Promise<IdResponse>}
|
|
225
163
|
* @private
|
|
226
164
|
*/
|
|
227
165
|
async createRun(title, description, environment) {
|
|
@@ -246,55 +184,49 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
|
|
|
246
184
|
* @returns {Promise<void>}
|
|
247
185
|
* @private
|
|
248
186
|
*/
|
|
249
|
-
async
|
|
250
|
-
this.
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
256
|
-
return acc;
|
|
257
|
-
}, []);
|
|
258
|
-
this.attachmentsMap = Object.fromEntries(await Promise.all(uploads.map(async ([id, request]) => {
|
|
259
|
-
return [id, await request];
|
|
260
|
-
})));
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* @param {string[]} attachments
|
|
264
|
-
* @returns {Promise<AttachmentGet[]>}
|
|
265
|
-
* @private
|
|
266
|
-
*/
|
|
267
|
-
async doUploadAttachments(attachments) {
|
|
268
|
-
return (await Promise.all(attachments.map(async (attachment) => {
|
|
187
|
+
async uploadAttachments(attachments) {
|
|
188
|
+
if (!this.isUploadAttachments) {
|
|
189
|
+
return [];
|
|
190
|
+
}
|
|
191
|
+
const acc = [];
|
|
192
|
+
for (const attachment of attachments) {
|
|
269
193
|
try {
|
|
270
|
-
|
|
194
|
+
let data;
|
|
195
|
+
if (attachment.file_path) {
|
|
196
|
+
data = (0, fs_1.createReadStream)(attachment.file_path);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
data = attachment.content;
|
|
200
|
+
}
|
|
271
201
|
const response = await this.api.attachments.uploadAttachment(this.projectCode, [data]);
|
|
272
|
-
|
|
202
|
+
if (response.data.result?.[0]?.hash != undefined) {
|
|
203
|
+
acc.push(response.data.result[0].hash);
|
|
204
|
+
}
|
|
273
205
|
}
|
|
274
206
|
catch (error) {
|
|
275
207
|
this.logError('Cannot upload attachment:', error);
|
|
276
|
-
return undefined;
|
|
277
208
|
}
|
|
278
|
-
}
|
|
209
|
+
}
|
|
210
|
+
return acc;
|
|
279
211
|
}
|
|
280
212
|
}
|
|
281
213
|
exports.TestOpsReporter = TestOpsReporter;
|
|
282
214
|
/**
|
|
283
|
-
* @type {Record<TestStatusEnum,
|
|
215
|
+
* @type {Record<TestStatusEnum, string>}
|
|
284
216
|
*/
|
|
285
217
|
TestOpsReporter.statusMap = {
|
|
286
|
-
[models_1.TestStatusEnum.passed]:
|
|
287
|
-
[models_1.TestStatusEnum.failed]:
|
|
288
|
-
[models_1.TestStatusEnum.skipped]:
|
|
289
|
-
[models_1.TestStatusEnum.disabled]:
|
|
290
|
-
[models_1.TestStatusEnum.blocked]:
|
|
291
|
-
[models_1.TestStatusEnum.invalid]:
|
|
218
|
+
[models_1.TestStatusEnum.passed]: 'passed',
|
|
219
|
+
[models_1.TestStatusEnum.failed]: 'failed',
|
|
220
|
+
[models_1.TestStatusEnum.skipped]: 'skipped',
|
|
221
|
+
[models_1.TestStatusEnum.disabled]: 'disabled',
|
|
222
|
+
[models_1.TestStatusEnum.blocked]: 'blocked',
|
|
223
|
+
[models_1.TestStatusEnum.invalid]: 'invalid',
|
|
292
224
|
};
|
|
293
225
|
/**
|
|
294
|
-
* @type {Record<StepStatusEnum,
|
|
226
|
+
* @type {Record<StepStatusEnum, ResultStepStatus>}
|
|
295
227
|
*/
|
|
296
228
|
TestOpsReporter.stepStatusMap = {
|
|
297
|
-
[models_1.StepStatusEnum.passed]: qaseio_1.
|
|
298
|
-
[models_1.StepStatusEnum.failed]: qaseio_1.
|
|
299
|
-
[models_1.StepStatusEnum.blocked]: qaseio_1.
|
|
229
|
+
[models_1.StepStatusEnum.passed]: qaseio_1.ResultStepStatus.PASSED,
|
|
230
|
+
[models_1.StepStatusEnum.failed]: qaseio_1.ResultStepStatus.FAILED,
|
|
231
|
+
[models_1.StepStatusEnum.blocked]: qaseio_1.ResultStepStatus.BLOCKED,
|
|
300
232
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DriverEnum = void 0;
|
|
3
|
+
exports.FormatEnum = exports.DriverEnum = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* @enum {string}
|
|
6
6
|
*/
|
|
@@ -8,3 +8,11 @@ var DriverEnum;
|
|
|
8
8
|
(function (DriverEnum) {
|
|
9
9
|
DriverEnum["local"] = "local";
|
|
10
10
|
})(DriverEnum || (exports.DriverEnum = DriverEnum = {}));
|
|
11
|
+
/**
|
|
12
|
+
* @enum {string}
|
|
13
|
+
*/
|
|
14
|
+
var FormatEnum;
|
|
15
|
+
(function (FormatEnum) {
|
|
16
|
+
FormatEnum["json"] = "json";
|
|
17
|
+
FormatEnum["jsonp"] = "jsonp";
|
|
18
|
+
})(FormatEnum || (exports.FormatEnum = FormatEnum = {}));
|
|
@@ -1,26 +1,35 @@
|
|
|
1
1
|
import { WriterInterface } from './writer-interface';
|
|
2
|
-
import { TestResultType } from '../models';
|
|
3
|
-
import {
|
|
2
|
+
import { TestResultType, Attachment, Report } from '../models';
|
|
3
|
+
import { FormatEnum } from './driver-enum';
|
|
4
4
|
export type FsWriterOptionsType = {
|
|
5
5
|
path?: string | undefined;
|
|
6
|
-
|
|
6
|
+
format?: `${FormatEnum}` | undefined;
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
9
9
|
* @class FsWriter
|
|
10
10
|
* @implements WriterInterface
|
|
11
11
|
*/
|
|
12
12
|
export declare class FsWriter implements WriterInterface {
|
|
13
|
+
private readonly path;
|
|
14
|
+
private readonly format;
|
|
13
15
|
private formatter;
|
|
14
|
-
private path;
|
|
15
|
-
private ext;
|
|
16
16
|
/**
|
|
17
17
|
* @param {FsWriterOptionsType | undefined} options
|
|
18
|
-
* @param {FormatterInterface} formatter
|
|
19
18
|
*/
|
|
20
|
-
constructor(options: FsWriterOptionsType | undefined
|
|
19
|
+
constructor(options: FsWriterOptionsType | undefined);
|
|
20
|
+
/**
|
|
21
|
+
* @param {Attachment[]} attachments
|
|
22
|
+
* @returns {Attachment[]}
|
|
23
|
+
*/
|
|
24
|
+
writeAttachment(attachments: Attachment[]): Attachment[];
|
|
21
25
|
/**
|
|
22
26
|
* @param {TestResultType[]} results
|
|
23
27
|
* @returns {Promise<string>}
|
|
24
28
|
*/
|
|
25
|
-
|
|
29
|
+
writeReport(results: Report): Promise<string>;
|
|
30
|
+
/**
|
|
31
|
+
* @returns {Promise<void>}
|
|
32
|
+
* @param {TestResultType} result
|
|
33
|
+
*/
|
|
34
|
+
writeTestResult(result: TestResultType): Promise<void>;
|
|
26
35
|
}
|
package/dist/writer/fs-writer.js
CHANGED
|
@@ -26,6 +26,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.FsWriter = void 0;
|
|
27
27
|
const fs_1 = require("fs");
|
|
28
28
|
const path = __importStar(require("path"));
|
|
29
|
+
const formatter_1 = require("../formatter");
|
|
30
|
+
const driver_enum_1 = require("./driver-enum");
|
|
29
31
|
/**
|
|
30
32
|
* @class FsWriter
|
|
31
33
|
* @implements WriterInterface
|
|
@@ -33,27 +35,72 @@ const path = __importStar(require("path"));
|
|
|
33
35
|
class FsWriter {
|
|
34
36
|
/**
|
|
35
37
|
* @param {FsWriterOptionsType | undefined} options
|
|
36
|
-
* @param {FormatterInterface} formatter
|
|
37
38
|
*/
|
|
38
|
-
constructor(options
|
|
39
|
-
|
|
40
|
-
const { path: pathOptions = path.join('build', 'qase-report'), ext = 'json', } = options ?? {};
|
|
39
|
+
constructor(options) {
|
|
40
|
+
const { path: pathOptions = path.join('build', 'qase-report'), format = options?.format ?? driver_enum_1.FormatEnum.json, } = options ?? {};
|
|
41
41
|
this.path = pathOptions;
|
|
42
|
-
this.
|
|
42
|
+
this.format = format;
|
|
43
|
+
if (this.format === driver_enum_1.FormatEnum.json) {
|
|
44
|
+
this.formatter = new formatter_1.JsonFormatter();
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
this.formatter = new formatter_1.JsonpFormatter();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* @param {Attachment[]} attachments
|
|
52
|
+
* @returns {Attachment[]}
|
|
53
|
+
*/
|
|
54
|
+
writeAttachment(attachments) {
|
|
55
|
+
const attachmentsPath = path.join(this.path, 'attachments');
|
|
56
|
+
try {
|
|
57
|
+
(0, fs_1.mkdirSync)(attachmentsPath, { recursive: true });
|
|
58
|
+
}
|
|
59
|
+
catch (error) { /* ignore */
|
|
60
|
+
}
|
|
61
|
+
for (const attachment of attachments) {
|
|
62
|
+
if (attachment.file_path) {
|
|
63
|
+
attachment.file_name = path.basename(attachment.file_path);
|
|
64
|
+
}
|
|
65
|
+
const filePath = path.join(attachmentsPath, `${attachment.id}-${attachment.file_name}`);
|
|
66
|
+
if (attachment.file_path) {
|
|
67
|
+
(0, fs_1.copyFileSync)(attachment.file_path, filePath);
|
|
68
|
+
attachment.file_path = filePath;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
(0, fs_1.writeFileSync)(filePath, attachment.content);
|
|
72
|
+
attachment.file_path = filePath;
|
|
73
|
+
}
|
|
74
|
+
return attachments;
|
|
43
75
|
}
|
|
44
76
|
/**
|
|
45
77
|
* @param {TestResultType[]} results
|
|
46
78
|
* @returns {Promise<string>}
|
|
47
79
|
*/
|
|
48
80
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
49
|
-
async
|
|
81
|
+
async writeReport(results) {
|
|
50
82
|
try {
|
|
51
83
|
(0, fs_1.mkdirSync)(this.path, { recursive: true });
|
|
52
84
|
}
|
|
53
|
-
catch (error) { /* ignore */
|
|
54
|
-
|
|
85
|
+
catch (error) { /* ignore */
|
|
86
|
+
}
|
|
87
|
+
const filePath = path.join(this.path, `report.${this.format}`);
|
|
55
88
|
(0, fs_1.writeFileSync)(filePath, await this.formatter.format(results));
|
|
56
89
|
return filePath;
|
|
57
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* @returns {Promise<void>}
|
|
93
|
+
* @param {TestResultType} result
|
|
94
|
+
*/
|
|
95
|
+
async writeTestResult(result) {
|
|
96
|
+
const resultsPath = path.join(this.path, 'results');
|
|
97
|
+
try {
|
|
98
|
+
(0, fs_1.mkdirSync)(resultsPath, { recursive: true });
|
|
99
|
+
}
|
|
100
|
+
catch (error) { /* ignore */
|
|
101
|
+
}
|
|
102
|
+
const filePath = path.join(resultsPath, `${result.id}.${this.format}`);
|
|
103
|
+
(0, fs_1.writeFileSync)(filePath, await this.formatter.format(result));
|
|
104
|
+
}
|
|
58
105
|
}
|
|
59
106
|
exports.FsWriter = FsWriter;
|
package/dist/writer/index.d.ts
CHANGED
package/dist/writer/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DriverEnum = exports.FsWriter = void 0;
|
|
3
|
+
exports.FormatEnum = exports.DriverEnum = exports.FsWriter = void 0;
|
|
4
4
|
var fs_writer_1 = require("./fs-writer");
|
|
5
5
|
Object.defineProperty(exports, "FsWriter", { enumerable: true, get: function () { return fs_writer_1.FsWriter; } });
|
|
6
6
|
var driver_enum_1 = require("./driver-enum");
|
|
7
7
|
Object.defineProperty(exports, "DriverEnum", { enumerable: true, get: function () { return driver_enum_1.DriverEnum; } });
|
|
8
|
+
Object.defineProperty(exports, "FormatEnum", { enumerable: true, get: function () { return driver_enum_1.FormatEnum; } });
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { TestResultType } from '../models';
|
|
1
|
+
import { TestResultType, Attachment, Report } from '../models';
|
|
2
2
|
export interface WriterInterface {
|
|
3
|
-
|
|
3
|
+
writeReport(results: Report): Promise<string>;
|
|
4
|
+
writeTestResult(result: TestResultType): Promise<void>;
|
|
5
|
+
writeAttachment(attachments: Attachment[]): Attachment[];
|
|
4
6
|
}
|