qase-javascript-commons 2.0.10 → 2.0.12

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,22 @@
1
+ # qase-javascript-commons@2.0.12
2
+
3
+ ## What's new
4
+
5
+ Support qaseio package version 2.2.0
6
+
7
+
8
+ # qase-javascript-commons@2.0.11
9
+
10
+ ## What's new
11
+
12
+ - Improved logging for better debugging and error reporting.
13
+
14
+ - Show the link to the test run in the console output when the test is failed.
15
+
16
+ ```text
17
+ [INFO] qase: See why this test failed: https://app.qase.io/run/DEMO/dashboard/123?status=%5B2%5D&search=5%20-%206%20=%20-2
18
+ ```
19
+
1
20
  # qase-javascript-commons@2.0.10
2
21
 
3
22
  ## What's new
package/dist/qase.js CHANGED
@@ -161,6 +161,7 @@ class QaseReporter {
161
161
  */
162
162
  async addTestResult(result) {
163
163
  if (!this.disabled) {
164
+ await this.startTestRunOperation;
164
165
  this.logTestItem(result);
165
166
  if (this.useFallback) {
166
167
  await this.addTestResultToFallback(result);
@@ -279,7 +280,7 @@ class QaseReporter {
279
280
  batch,
280
281
  useV2,
281
282
  defect,
282
- }, apiClient, environment, rootSuite);
283
+ }, apiClient, environment, rootSuite, api.host);
283
284
  }
284
285
  case options_1.ModeEnum.report: {
285
286
  const localOptions = report.connections?.[writer_1.DriverEnum.local];
@@ -102,8 +102,9 @@ export declare class TestOpsReporter extends AbstractReporter {
102
102
  * @param {QaseApiInterface} api
103
103
  * @param {string | undefined} environment
104
104
  * @param {string | undefined} rootSuite
105
+ * @param {string | undefined} baseUrl
105
106
  */
106
- constructor(logger: LoggerInterface, options: TestOpsOptionsType, api: QaseApiInterface, environment?: string, rootSuite?: string);
107
+ constructor(logger: LoggerInterface, options: TestOpsOptionsType, api: QaseApiInterface, environment?: string, rootSuite?: string, baseUrl?: string);
107
108
  /**
108
109
  * @returns {Promise<void>}
109
110
  */
@@ -190,4 +191,32 @@ export declare class TestOpsReporter extends AbstractReporter {
190
191
  * @private
191
192
  */
192
193
  private uploadAttachments;
194
+ /**
195
+ * Process error and throw QaseError
196
+ * @param {Error | AxiosError} error
197
+ * @param {string} message
198
+ * @param {object} model
199
+ * @private
200
+ */
201
+ private processError;
202
+ /**
203
+ * @param {string | undefined} url
204
+ * @return string
205
+ * @private
206
+ */
207
+ private getBaseUrl;
208
+ /**
209
+ * @param {number | null} id
210
+ * @param {string} title
211
+ * @return string
212
+ * @private
213
+ */
214
+ private prepareFailedTestLink;
215
+ /**
216
+ * Show link to failed test
217
+ * @param {number | null} id
218
+ * @param {string} title
219
+ * @private
220
+ */
221
+ private showLink;
193
222
  }
@@ -10,6 +10,7 @@ const qaseio_1 = require("qaseio");
10
10
  const abstract_reporter_1 = require("./abstract-reporter");
11
11
  const models_1 = require("../models");
12
12
  const qase_error_1 = require("../utils/qase-error");
13
+ const axios_1 = __importDefault(require("axios"));
13
14
  const defaultChunkSize = 200;
14
15
  /**
15
16
  * @class TestOpsReporter
@@ -22,8 +23,9 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
22
23
  * @param {QaseApiInterface} api
23
24
  * @param {string | undefined} environment
24
25
  * @param {string | undefined} rootSuite
26
+ * @param {string | undefined} baseUrl
25
27
  */
26
- constructor(logger, options, api, environment, rootSuite) {
28
+ constructor(logger, options, api, environment, rootSuite, baseUrl) {
27
29
  const { project, uploadAttachments, run, } = options;
28
30
  super(logger);
29
31
  this.api = api;
@@ -37,8 +39,7 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
37
39
  * @private
38
40
  */
39
41
  this.isTestRunReady = false;
40
- const baseUrl = 'https://app.qase.io';
41
- this.baseUrl = baseUrl.replace(/\/$/, '');
42
+ this.baseUrl = this.getBaseUrl(baseUrl);
42
43
  this.projectCode = project;
43
44
  this.isUploadAttachments = uploadAttachments;
44
45
  this.run = { complete: true, ...run };
@@ -59,6 +60,16 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
59
60
  * @returns {Promise<void>}
60
61
  */
61
62
  async addTestResult(result) {
63
+ if (result.execution.status === models_1.TestStatusEnum.failed) {
64
+ if (Array.isArray(result.testops_id)) {
65
+ for (const id of result.testops_id) {
66
+ this.showLink(id, result.title);
67
+ }
68
+ }
69
+ else {
70
+ this.showLink(result.testops_id, result.title);
71
+ }
72
+ }
62
73
  await super.addTestResult(result);
63
74
  if (!this.isTestRunReady) {
64
75
  return;
@@ -80,18 +91,18 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
80
91
  this.isTestRunReady = true;
81
92
  return;
82
93
  }
83
- this.logger.logDebug('Create test run');
94
+ this.logger.logDebug('Creating test run');
84
95
  let environmentId;
85
96
  if (this.environment != undefined) {
86
97
  try {
87
- const { data } = await this.api.environment.getEnvironments(this.projectCode, 100);
98
+ const { data } = await this.api.environment.getEnvironments(this.projectCode, undefined, this.environment, 100);
88
99
  const env = data.result?.entities?.find((env) => env.slug === this.environment);
89
100
  if (env) {
90
101
  environmentId = env.id;
91
102
  }
92
103
  }
93
104
  catch (error) {
94
- throw new qase_error_1.QaseError('Cannot get environments', { cause: error });
105
+ throw this.processError(error, 'Error on getting environments');
95
106
  }
96
107
  }
97
108
  const { result } = await this.createRun(this.run.title, this.run.description, environmentId);
@@ -115,9 +126,14 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
115
126
  const resultCreateV2 = await this.transformTestResult(result);
116
127
  results.push(resultCreateV2);
117
128
  }
118
- await this.api.result.createResultsV2(this.projectCode, this.run.id, {
119
- results: results,
120
- });
129
+ try {
130
+ await this.api.result.createResultsV2(this.projectCode, this.run.id, {
131
+ results: results,
132
+ });
133
+ }
134
+ catch (error) {
135
+ throw this.processError(error, 'Error on uploading results', results);
136
+ }
121
137
  }
122
138
  else {
123
139
  const results = [];
@@ -125,9 +141,14 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
125
141
  const resultCreate = await this.transformTestResultV1(result);
126
142
  results.push(resultCreate);
127
143
  }
128
- await this.api.results.createResultBulk(this.projectCode, this.run.id, {
129
- results: results,
130
- });
144
+ try {
145
+ await this.api.results.createResultBulk(this.projectCode, this.run.id, {
146
+ results: results,
147
+ });
148
+ }
149
+ catch (error) {
150
+ throw this.processError(error, 'Error on uploading results', results);
151
+ }
131
152
  }
132
153
  this.logger.logDebug(`Results sent to Qase: ${testResults.length}`);
133
154
  }
@@ -152,7 +173,7 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
152
173
  this.logger.log((0, chalk_1.default) `{green Run ${this.run.id} completed}`);
153
174
  }
154
175
  catch (error) {
155
- throw new qase_error_1.QaseError('Error on completing run', { cause: error });
176
+ throw this.processError(error, 'Error on completing run');
156
177
  }
157
178
  const runUrl = `${this.baseUrl}/run/${this.projectCode}/dashboard/${this.run.id}`;
158
179
  this.logger.log((0, chalk_1.default) `{blue Test run link: ${runUrl}}`);
@@ -359,7 +380,7 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
359
380
  this.logger.log(`Get run result on checking run "${String(resp.data.result?.id)}"`);
360
381
  }
361
382
  catch (error) {
362
- throw new qase_error_1.QaseError('Error on checking run', { cause: error });
383
+ throw this.processError(error, 'Error on checking run');
363
384
  }
364
385
  }
365
386
  /**
@@ -385,7 +406,7 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
385
406
  return data;
386
407
  }
387
408
  catch (error) {
388
- throw new qase_error_1.QaseError('Cannot create run', { cause: error });
409
+ throw this.processError(error, 'Error on creating run');
389
410
  }
390
411
  }
391
412
  /**
@@ -438,6 +459,62 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
438
459
  }
439
460
  return acc;
440
461
  }
462
+ /**
463
+ * Process error and throw QaseError
464
+ * @param {Error | AxiosError} error
465
+ * @param {string} message
466
+ * @param {object} model
467
+ * @private
468
+ */
469
+ processError(error, message, model) {
470
+ if (!axios_1.default.isAxiosError(error)) {
471
+ return new qase_error_1.QaseError(message, { cause: error });
472
+ }
473
+ if (error.response?.status === 401) {
474
+ return new qase_error_1.QaseError(message + ': \n Unauthorized. Please check your API token. Maybe it is expired or invalid.');
475
+ }
476
+ if (error.response?.status === 404) {
477
+ return new qase_error_1.QaseError(message + ': Not found.');
478
+ }
479
+ if (error.response?.status === 400) {
480
+ return new qase_error_1.QaseError(message + ': Bad request. Body: \n ' + JSON.stringify(model));
481
+ }
482
+ return new qase_error_1.QaseError(message, { cause: error });
483
+ }
484
+ /**
485
+ * @param {string | undefined} url
486
+ * @return string
487
+ * @private
488
+ */
489
+ getBaseUrl(url) {
490
+ if (!url || url === 'qase.io') {
491
+ return 'https://app.qase.io';
492
+ }
493
+ return `https://${url.replace('api', 'app')}`;
494
+ }
495
+ /**
496
+ * @param {number | null} id
497
+ * @param {string} title
498
+ * @return string
499
+ * @private
500
+ */
501
+ prepareFailedTestLink(id, title) {
502
+ const baseLink = `${this.baseUrl}/run/${this.projectCode}/dashboard/${this.run.id}?source=logs&status=%5B2%5D&search=`;
503
+ if (id) {
504
+ return `${baseLink}${id}`;
505
+ }
506
+ return `${baseLink}${encodeURI(title)}`;
507
+ }
508
+ /**
509
+ * Show link to failed test
510
+ * @param {number | null} id
511
+ * @param {string} title
512
+ * @private
513
+ */
514
+ showLink(id, title) {
515
+ const link = this.prepareFailedTestLink(id, title);
516
+ this.logger.log((0, chalk_1.default) `{blue See why this test failed: ${link}}`);
517
+ }
441
518
  }
442
519
  exports.TestOpsReporter = TestOpsReporter;
443
520
  /**
@@ -1,6 +1,6 @@
1
- export type ErrorOptionsType = {
1
+ export interface ErrorOptionsType {
2
2
  cause?: unknown;
3
- };
3
+ }
4
4
  export interface QaseErrorInterface extends Error {
5
5
  cause?: unknown;
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qase-javascript-commons",
3
- "version": "2.0.10",
3
+ "version": "2.0.12",
4
4
  "description": "Qase JS Reporters",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -33,7 +33,7 @@
33
33
  "lodash.merge": "^4.6.2",
34
34
  "lodash.mergewith": "^4.6.2",
35
35
  "mime-types": "^2.1.33",
36
- "qaseio": "^2.1.3",
36
+ "qaseio": "~2.2.0",
37
37
  "strip-ansi": "^6.0.1",
38
38
  "uuid": "^9.0.0"
39
39
  },