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.
Files changed (52) hide show
  1. package/changelog.md +23 -0
  2. package/dist/config/config-validation-schema.js +22 -6
  3. package/dist/env/env-enum.d.ts +14 -7
  4. package/dist/env/env-enum.js +14 -6
  5. package/dist/env/env-to-config.js +6 -3
  6. package/dist/env/env-type.d.ts +7 -4
  7. package/dist/env/env-validation-schema.js +15 -4
  8. package/dist/formatter/index.d.ts +1 -0
  9. package/dist/formatter/index.js +3 -1
  10. package/dist/formatter/jsonp-formatter.d.ts +13 -0
  11. package/dist/formatter/jsonp-formatter.js +28 -0
  12. package/dist/models/attachment.d.ts +8 -0
  13. package/dist/models/attachment.js +2 -0
  14. package/dist/models/execution-sum.d.ts +6 -0
  15. package/dist/models/execution-sum.js +2 -0
  16. package/dist/models/host-data.d.ts +11 -0
  17. package/dist/models/host-data.js +2 -0
  18. package/dist/models/index.d.ts +6 -2
  19. package/dist/models/index.js +4 -4
  20. package/dist/models/report.d.ts +14 -0
  21. package/dist/models/report.js +2 -0
  22. package/dist/models/short-result.d.ts +7 -0
  23. package/dist/models/short-result.js +2 -0
  24. package/dist/models/stats.d.ts +8 -0
  25. package/dist/models/stats.js +2 -0
  26. package/dist/models/step-data.d.ts +4 -0
  27. package/dist/models/step-data.js +2 -0
  28. package/dist/models/step-execution.d.ts +11 -0
  29. package/dist/models/step-execution.js +9 -0
  30. package/dist/models/test-execution.d.ts +19 -0
  31. package/dist/models/test-execution.js +15 -0
  32. package/dist/models/test-result.d.ts +14 -20
  33. package/dist/models/test-result.js +0 -13
  34. package/dist/models/test-step.d.ts +9 -11
  35. package/dist/models/test-step.js +0 -7
  36. package/dist/options/options-type.d.ts +1 -0
  37. package/dist/qase.d.ts +22 -2
  38. package/dist/qase.js +103 -25
  39. package/dist/reporters/abstract-reporter.d.ts +18 -7
  40. package/dist/reporters/abstract-reporter.js +37 -2
  41. package/dist/reporters/report-reporter.d.ts +24 -12
  42. package/dist/reporters/report-reporter.js +152 -13
  43. package/dist/reporters/testops-reporter.d.ts +26 -49
  44. package/dist/reporters/testops-reporter.js +87 -155
  45. package/dist/writer/driver-enum.d.ts +7 -0
  46. package/dist/writer/driver-enum.js +9 -1
  47. package/dist/writer/fs-writer.d.ts +17 -8
  48. package/dist/writer/fs-writer.js +55 -8
  49. package/dist/writer/index.d.ts +1 -1
  50. package/dist/writer/index.js +2 -1
  51. package/dist/writer/writer-interface.d.ts +4 -2
  52. package/package.json +4 -3
@@ -1,18 +1,22 @@
1
- import { QaseApiInterface, ResultExecutionStatusEnum, TestStepResultCreateStatusEnum } from 'qaseio';
1
+ import { QaseApiInterface, ResultStepStatus } from 'qaseio';
2
2
  import { AbstractReporter, LoggerInterface, ReporterOptionsType } from './abstract-reporter';
3
- import { StepStatusEnum, TestResultType, TestStatusEnum } from '../models';
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
- environment?: number | undefined;
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, ResultExecutionStatusEnum>}
28
+ * @type {Record<TestStatusEnum, string>}
25
29
  */
26
- static statusMap: Record<TestStatusEnum, ResultExecutionStatusEnum>;
30
+ static statusMap: Record<TestStatusEnum, string>;
27
31
  /**
28
- * @type {Record<StepStatusEnum, TestStepResultCreateStatusEnum>}
32
+ * @type {Record<StepStatusEnum, ResultStepStatus>}
29
33
  */
30
- static stepStatusMap: Record<StepStatusEnum, TestStepResultCreateStatusEnum>;
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 uploadAttachments;
49
+ private readonly isUploadAttachments;
46
50
  /**
47
51
  * @type {TestOpsRunType}
48
52
  * @private
49
53
  */
50
54
  private run;
51
55
  /**
52
- * @type {TestResultType[]}
56
+ * @type { number | undefined}
53
57
  * @private
54
58
  */
55
- private results;
59
+ private readonly environment;
56
60
  /**
57
- * @type {Record<string, string[]>}
58
- * @private
59
- */
60
- private attachments;
61
- /**
62
- * @type {Record<string, string[]>}
61
+ * @type {TestResultType[]}
63
62
  * @private
64
63
  */
65
- private attachmentsMap;
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 {ResultCreate}
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 {ResultStep[]}
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<any>}
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 prepareAttachments;
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, baseUrl = 'https://app.qase.io', uploadAttachments, run, ...restOptions } = options;
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.uploadAttachments = uploadAttachments;
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.run.environment);
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
- if (this.uploadAttachments && Object.keys(this.attachments).length) {
86
- await this.prepareAttachments();
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 {ResultCreate}
83
+ * @returns Promise<ResultCreateV2>
108
84
  * @private
109
85
  */
110
- transformTestResult(result) {
111
- const resultObject = {
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
- attachments: this.getAttachmentsFor(result.id),
114
- execution: this.getExecution(result),
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(result) {
149
- const execution = {
150
- status: TestOpsReporter.statusMap[result.status],
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 {ResultStep[]}
121
+ * @returns Promise<ResultStep[]>
186
122
  * @private
187
123
  */
188
- transformSteps(steps) {
189
- return steps.map(({ id, title, status, steps, }) => {
190
- const step = {
191
- step_type: 'text',
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: title,
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
- step.steps = this.transformSteps(steps);
137
+ if (step.steps.length > 0) {
138
+ resultStep.steps = await this.transformSteps(step.steps);
202
139
  }
203
- return step;
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<any>}
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 prepareAttachments() {
250
- this.log((0, chalk_1.default) `{yellow Uploading attachments to Qase}`);
251
- const uploads = Object.keys(this.attachments).reduce((acc, id) => {
252
- const attachment = this.attachments[id];
253
- if (attachment) {
254
- acc.push([id, this.doUploadAttachments(attachment)]);
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
- const data = (0, fs_1.createReadStream)(attachment);
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
- return response.data.result?.[0];
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
- }))).filter((attachments) => Boolean(attachments));
209
+ }
210
+ return acc;
279
211
  }
280
212
  }
281
213
  exports.TestOpsReporter = TestOpsReporter;
282
214
  /**
283
- * @type {Record<TestStatusEnum, ResultExecutionStatusEnum>}
215
+ * @type {Record<TestStatusEnum, string>}
284
216
  */
285
217
  TestOpsReporter.statusMap = {
286
- [models_1.TestStatusEnum.passed]: qaseio_1.ResultExecutionStatusEnum.PASSED,
287
- [models_1.TestStatusEnum.failed]: qaseio_1.ResultExecutionStatusEnum.FAILED,
288
- [models_1.TestStatusEnum.skipped]: qaseio_1.ResultExecutionStatusEnum.SKIPPED,
289
- [models_1.TestStatusEnum.disabled]: qaseio_1.ResultExecutionStatusEnum.SKIPPED,
290
- [models_1.TestStatusEnum.blocked]: qaseio_1.ResultExecutionStatusEnum.BLOCKED,
291
- [models_1.TestStatusEnum.invalid]: qaseio_1.ResultExecutionStatusEnum.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, TestStepResultCreateStatusEnum>}
226
+ * @type {Record<StepStatusEnum, ResultStepStatus>}
295
227
  */
296
228
  TestOpsReporter.stepStatusMap = {
297
- [models_1.StepStatusEnum.passed]: qaseio_1.TestStepResultCreateStatusEnum.PASSED,
298
- [models_1.StepStatusEnum.failed]: qaseio_1.TestStepResultCreateStatusEnum.FAILED,
299
- [models_1.StepStatusEnum.blocked]: qaseio_1.TestStepResultCreateStatusEnum.BLOCKED,
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
  };
@@ -4,3 +4,10 @@
4
4
  export declare enum DriverEnum {
5
5
  local = "local"
6
6
  }
7
+ /**
8
+ * @enum {string}
9
+ */
10
+ export declare enum FormatEnum {
11
+ json = "json",
12
+ jsonp = "jsonp"
13
+ }
@@ -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 { FormatterInterface } from '../formatter';
2
+ import { TestResultType, Attachment, Report } from '../models';
3
+ import { FormatEnum } from './driver-enum';
4
4
  export type FsWriterOptionsType = {
5
5
  path?: string | undefined;
6
- ext?: string | undefined;
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, formatter: FormatterInterface);
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
- write(results: TestResultType[]): Promise<string>;
29
+ writeReport(results: Report): Promise<string>;
30
+ /**
31
+ * @returns {Promise<void>}
32
+ * @param {TestResultType} result
33
+ */
34
+ writeTestResult(result: TestResultType): Promise<void>;
26
35
  }
@@ -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, formatter) {
39
- this.formatter = formatter;
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.ext = ext;
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 write(results) {
81
+ async writeReport(results) {
50
82
  try {
51
83
  (0, fs_1.mkdirSync)(this.path, { recursive: true });
52
84
  }
53
- catch (error) { /* ignore */ }
54
- const filePath = path.join(this.path, `results-${Date.now()}.${this.ext}`);
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;
@@ -1,3 +1,3 @@
1
1
  export { type WriterInterface } from './writer-interface';
2
2
  export { FsWriter, type FsWriterOptionsType } from './fs-writer';
3
- export { DriverEnum } from './driver-enum';
3
+ export { DriverEnum, FormatEnum } from './driver-enum';
@@ -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
- write(results: TestResultType[]): Promise<string>;
3
+ writeReport(results: Report): Promise<string>;
4
+ writeTestResult(result: TestResultType): Promise<void>;
5
+ writeAttachment(attachments: Attachment[]): Attachment[];
4
6
  }