qase-javascript-commons 2.0.0-beta.6 → 2.0.0-beta.7

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 CHANGED
@@ -1,3 +1,30 @@
1
+ # qase-javascript-commons@2.0.0-beta.7
2
+
3
+ ## What's new
4
+
5
+ TestOps reporter supports uploading test result in real-time.
6
+ It can be useful for long-running tests, where you want to see the results as soon as they are available.
7
+ You can use chunk size to control the size of the data sent to the Qase.
8
+
9
+ To enable real-time reporting, set an environment variable before running the tests or use the reporter's configuration:
10
+
11
+ ```bash
12
+ QASE_TESTOPS_CHUNK=10
13
+ ```
14
+
15
+ ```diff
16
+ {
17
+ ...
18
+ "testops": {
19
+ + "chunk": 10
20
+ ...
21
+ },
22
+ ...
23
+ }
24
+ ```
25
+
26
+ where `10` is the size of the chunk in test result's count.
27
+
1
28
  # qase-javascript-commons@2.0.0-beta.6
2
29
 
3
30
  ## What's new
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);
@@ -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
- addTestResult(result) {
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 readonly startTime;
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;
@@ -77,6 +77,16 @@ export declare class TestOpsReporter extends AbstractReporter {
77
77
  * @private
78
78
  */
79
79
  private readonly defect;
80
+ /**
81
+ * @type {number}
82
+ * @private
83
+ */
84
+ private firstIndex;
85
+ /**
86
+ * @type {boolean}
87
+ * @private
88
+ */
89
+ private isTestRunReady;
80
90
  /**
81
91
  * @param {ReporterOptionsType & TestOpsOptionsType} options
82
92
  * @param {QaseApiInterface} api
@@ -84,6 +94,25 @@ export declare class TestOpsReporter extends AbstractReporter {
84
94
  * @param {number} environment
85
95
  */
86
96
  constructor(options: ReporterOptionsType & TestOpsOptionsType, api: QaseApiInterface, logger?: LoggerInterface, environment?: number);
97
+ /**
98
+ * @returns {Promise<void>}
99
+ */
100
+ startTestRun(): Promise<void>;
101
+ /**
102
+ * @param {TestResultType} result
103
+ * @returns {Promise<void>}
104
+ */
105
+ addTestResult(result: TestResultType): Promise<void>;
106
+ /**
107
+ * @returns {Promise<void>}
108
+ */
109
+ private checkOrCreateTestRun;
110
+ /**
111
+ * @returns {Promise<void>}
112
+ * @param testResults
113
+ * @private
114
+ */
115
+ private publishResults;
87
116
  /**
88
117
  * @returns {Promise<void>}
89
118
  */
@@ -26,6 +26,16 @@ 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;
@@ -39,59 +49,90 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
39
49
  /**
40
50
  * @returns {Promise<void>}
41
51
  */
42
- async publish() {
43
- let runId;
44
- if (this.run.id !== undefined) {
45
- await this.checkRun(this.run.id);
46
- runId = this.run.id;
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
- else {
49
- const { result } = await this.createRun(this.run.title, this.run.description, this.environment);
50
- if (!result?.id) {
51
- throw new Error('Cannot create run.');
52
- }
53
- runId = result.id;
64
+ const countOfResults = this.chunk + 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
- if (!this.results.length) {
56
- this.log('No test cases were matched. Ensure that your tests are declared correctly.');
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 this.results) {
94
+ for (const result of testResults) {
62
95
  const resultCreateV2 = await this.transformTestResult(result);
63
96
  results.push(resultCreateV2);
64
97
  }
65
- for (let i = 0; i < results.length; i += this.chunk) {
66
- await this.api.result.createResultsV2(this.projectCode, runId, {
67
- results: results.slice(i, i + this.chunk),
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 this.results) {
104
+ for (const result of testResults) {
74
105
  const resultCreate = await this.transformTestResultV1(result);
75
106
  results.push(resultCreate);
76
107
  }
77
- for (let i = 0; i < results.length; i += this.chunk) {
78
- await this.api.results.createResultBulk(this.projectCode, runId, {
79
- results: results.slice(i, i + this.chunk),
80
- });
81
- }
108
+ await this.api.results.createResultBulk(this.projectCode, this.run.id, {
109
+ results: results,
110
+ });
111
+ }
112
+ }
113
+ /**
114
+ * @returns {Promise<void>}
115
+ */
116
+ async publish() {
117
+ if (this.results.length === 0) {
118
+ this.log((0, chalk_1.default) `{yellow No results to send to Qase}`);
119
+ return;
120
+ }
121
+ if (this.firstIndex < this.results.length) {
122
+ await this.publishResults(this.results.slice(this.firstIndex));
82
123
  }
83
124
  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, runId);
89
- this.log((0, chalk_1.default) `{green Run ${runId} completed}`);
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/${runId}`;
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
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qase-javascript-commons",
3
- "version": "2.0.0-beta.6",
3
+ "version": "2.0.0-beta.7",
4
4
  "description": "Qase JS Reporters",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",