qase-javascript-commons 2.0.8 → 2.0.10

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 CHANGED
@@ -37,6 +37,7 @@ All configuration options are listed in the table below:
37
37
  | Mode of reporter | `mode` | `QASE_MODE` | `testops` | No | `testops`, `report`, `off` |
38
38
  | Fallback mode of reporter | `fallback` | `QASE_FALLBACK` | `off` | No | `testops`, `report`, `off` |
39
39
  | Environment | `environment` | `QASE_ENVIRONMENT` | `local` | No | Any string |
40
+ | Root suite | `rootSuite` | `QASE_ROOT_SUITE` | | No | Any string |
40
41
  | Enable debug logs | `debug` | `QASE_DEBUG` | `False` | No | `True`, `False` |
41
42
  | Enable capture logs from `stdout` and `stderr` | `testops.defect` | `QASE_CAPTURE_LOGS` | `False` | No | `True`, `False` |
42
43
  | **Qase Report configuration** | | | | | |
@@ -45,7 +46,8 @@ All configuration options are listed in the table below:
45
46
  | Local report format | `report.connection.format` | `QASE_REPORT_CONNECTION_FORMAT` | `json` | | `json`, `jsonp` |
46
47
  | **Qase TestOps configuration** | | | | | |
47
48
  | Token for [API access](https://developers.qase.io/#authentication) | `testops.api.token` | `QASE_TESTOPS_API_TOKEN` | | Yes | Any string |
48
- | Qase API host | `testops.api.host` | `QASE_TESTOPS_API_HOST` | `qase.io` | No | Any string |
49
+ | Qase API host. For enterprise users, specify full address: `api-example.qase.io` | `testops.api.host` | `QASE_TESTOPS_API_HOST` | `qase.io` | No | Any string |
50
+ | Qase enterprise environment | `testops.api.enterprise` | `QASE_TESTOPS_API_ENTERPRISE` | `False` | No | `True`, `False` |
49
51
  | 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 |
50
52
  | Qase test run ID | `testops.run.id` | `QASE_TESTOPS_RUN_ID` | | No | Any integer |
51
53
  | Qase test run title | `testops.run.title` | `QASE_TESTOPS_RUN_TITLE` | `Automated run <Current date and time>` | No | Any string |
package/changelog.md CHANGED
@@ -1,3 +1,31 @@
1
+ # qase-javascript-commons@2.0.10
2
+
3
+ ## What's new
4
+
5
+ Fixed an issue with sending test results duplicates when we use the `qase-cypress` reporter.
6
+ Now the reporter will send the test results only once.
7
+
8
+ The Cypress calls the `publish` method multiple times for the same test results because of the Cypress architecture.
9
+ It calls the `publish` method for each test file.
10
+
11
+
12
+ # qase-javascript-commons@2.0.9
13
+
14
+ ## What's new
15
+
16
+ Added new configuration option `rootSuite` to specify a root suite.
17
+ This option is available in the config file and the `QASE_ROOT_SUITE` env variable
18
+
19
+ ```diff
20
+ {
21
+ "mode": "testops",
22
+ "fallback": "report",
23
+ "environment": "local",
24
+ + "rootSuite": "Root Suite",
25
+ ...
26
+ }
27
+ ```
28
+
1
29
  # qase-javascript-commons@2.0.8
2
30
 
3
31
  ## What's new
@@ -31,6 +31,10 @@ exports.configValidationSchema = {
31
31
  type: 'boolean',
32
32
  nullable: true,
33
33
  },
34
+ rootSuite: {
35
+ type: 'string',
36
+ nullable: true,
37
+ },
34
38
  testops: {
35
39
  type: 'object',
36
40
  nullable: true,
@@ -43,7 +47,7 @@ exports.configValidationSchema = {
43
47
  type: 'string',
44
48
  nullable: true,
45
49
  },
46
- baseUrl: {
50
+ host: {
47
51
  type: 'string',
48
52
  nullable: true,
49
53
  },
@@ -6,7 +6,8 @@ export declare enum EnvEnum {
6
6
  fallback = "QASE_FALLBACK",
7
7
  debug = "QASE_DEBUG",
8
8
  environment = "QASE_ENVIRONMENT",
9
- captureLogs = "QASE_CAPTURE_LOGS"
9
+ captureLogs = "QASE_CAPTURE_LOGS",
10
+ rootSuite = "QASE_ROOT_SUITE"
10
11
  }
11
12
  /**
12
13
  * @enum {string}
@@ -22,7 +23,7 @@ export declare enum EnvTestOpsEnum {
22
23
  */
23
24
  export declare enum EnvApiEnum {
24
25
  token = "QASE_TESTOPS_API_TOKEN",
25
- baseUrl = "QASE_TESTOPS_API_HOST"
26
+ host = "QASE_TESTOPS_API_HOST"
26
27
  }
27
28
  /**
28
29
  * @enum {string}
@@ -11,6 +11,7 @@ var EnvEnum;
11
11
  EnvEnum["debug"] = "QASE_DEBUG";
12
12
  EnvEnum["environment"] = "QASE_ENVIRONMENT";
13
13
  EnvEnum["captureLogs"] = "QASE_CAPTURE_LOGS";
14
+ EnvEnum["rootSuite"] = "QASE_ROOT_SUITE";
14
15
  })(EnvEnum || (exports.EnvEnum = EnvEnum = {}));
15
16
  /**
16
17
  * @enum {string}
@@ -28,7 +29,7 @@ var EnvTestOpsEnum;
28
29
  var EnvApiEnum;
29
30
  (function (EnvApiEnum) {
30
31
  EnvApiEnum["token"] = "QASE_TESTOPS_API_TOKEN";
31
- EnvApiEnum["baseUrl"] = "QASE_TESTOPS_API_HOST";
32
+ EnvApiEnum["host"] = "QASE_TESTOPS_API_HOST";
32
33
  })(EnvApiEnum || (exports.EnvApiEnum = EnvApiEnum = {}));
33
34
  /**
34
35
  * @enum {string}
@@ -12,12 +12,13 @@ const envToConfig = (env) => ({
12
12
  debug: env[env_enum_1.EnvEnum.debug],
13
13
  environment: env[env_enum_1.EnvEnum.environment],
14
14
  captureLogs: env[env_enum_1.EnvEnum.captureLogs],
15
+ rootSuite: env[env_enum_1.EnvEnum.rootSuite],
15
16
  testops: {
16
17
  project: env[env_enum_1.EnvTestOpsEnum.project],
17
18
  uploadAttachments: env[env_enum_1.EnvTestOpsEnum.uploadAttachments],
18
19
  api: {
19
20
  token: env[env_enum_1.EnvApiEnum.token],
20
- baseUrl: env[env_enum_1.EnvApiEnum.baseUrl],
21
+ host: env[env_enum_1.EnvApiEnum.host],
21
22
  },
22
23
  run: {
23
24
  id: env[env_enum_1.EnvRunEnum.id],
@@ -7,12 +7,13 @@ export type EnvType = {
7
7
  [EnvEnum.debug]?: boolean;
8
8
  [EnvEnum.environment]?: string;
9
9
  [EnvEnum.captureLogs]?: boolean;
10
+ [EnvEnum.rootSuite]?: string;
10
11
  [EnvTestOpsEnum.project]?: string;
11
12
  [EnvTestOpsEnum.uploadAttachments]?: boolean;
12
13
  [EnvTestOpsEnum.defect]?: boolean;
13
14
  [EnvTestOpsEnum.useV2]?: boolean;
14
15
  [EnvApiEnum.token]?: string;
15
- [EnvApiEnum.baseUrl]?: string;
16
+ [EnvApiEnum.host]?: string;
16
17
  [EnvRunEnum.id]?: number;
17
18
  [EnvRunEnum.title]?: string;
18
19
  [EnvRunEnum.description]?: string;
@@ -32,6 +32,10 @@ exports.envValidationSchema = {
32
32
  type: 'boolean',
33
33
  nullable: true,
34
34
  },
35
+ [env_enum_1.EnvEnum.rootSuite]: {
36
+ type: 'string',
37
+ nullable: true,
38
+ },
35
39
  [env_enum_1.EnvTestOpsEnum.project]: {
36
40
  type: 'string',
37
41
  nullable: true,
@@ -52,7 +56,7 @@ exports.envValidationSchema = {
52
56
  type: 'string',
53
57
  nullable: true,
54
58
  },
55
- [env_enum_1.EnvApiEnum.baseUrl]: {
59
+ [env_enum_1.EnvApiEnum.host]: {
56
60
  type: 'string',
57
61
  nullable: true,
58
62
  },
@@ -5,5 +5,5 @@ declare module 'lodash' {
5
5
  mergeWith<T extends unknown[]>(...args: [...T, MergeWithCustomizer]): MergedType<T>;
6
6
  }
7
7
  }
8
- export declare const composeOptions: <T extends unknown[]>(...args: T) => MergedType<[{}, ...T], {}>;
8
+ export declare const composeOptions: <T extends unknown[]>(...args: T) => MergedType<[NonNullable<unknown>, ...T]>;
9
9
  export {};
@@ -24,6 +24,7 @@ export type OptionsType = {
24
24
  captureLogs?: boolean | undefined;
25
25
  debug?: boolean | undefined;
26
26
  environment?: string | undefined;
27
+ rootSuite?: string | undefined;
27
28
  testops?: (RecursivePartial<TestOpsOptionsType> & AdditionalTestOpsOptionsType) | undefined;
28
29
  report?: RecursivePartial<AdditionalReportOptionsType> | undefined;
29
30
  };
package/dist/qase.js CHANGED
@@ -249,7 +249,7 @@ class QaseReporter {
249
249
  * @private
250
250
  */
251
251
  createReporter(mode, options) {
252
- const { frameworkPackage, frameworkName, reporterName, environment, report = {}, testops = {}, } = options;
252
+ const { frameworkPackage, frameworkName, reporterName, environment, rootSuite, report = {}, testops = {}, } = options;
253
253
  switch (mode) {
254
254
  case options_1.ModeEnum.testops: {
255
255
  const { api: { token, headers, ...api } = {}, project, run: { title, description, ...run } = {}, plan = {}, batch = {}, useV2, defect, uploadAttachments, } = testops;
@@ -279,12 +279,12 @@ class QaseReporter {
279
279
  batch,
280
280
  useV2,
281
281
  defect,
282
- }, apiClient, environment);
282
+ }, apiClient, environment, rootSuite);
283
283
  }
284
284
  case options_1.ModeEnum.report: {
285
285
  const localOptions = report.connections?.[writer_1.DriverEnum.local];
286
286
  const writer = new writer_1.FsWriter(localOptions);
287
- return new reporters_1.ReportReporter(this.logger, writer, environment, testops.run?.id);
287
+ return new reporters_1.ReportReporter(this.logger, writer, environment, rootSuite, testops.run?.id);
288
288
  }
289
289
  case options_1.ModeEnum.off:
290
290
  throw new disabled_exception_1.DisabledException();
@@ -9,14 +9,16 @@ export declare class ReportReporter extends AbstractReporter {
9
9
  private writer;
10
10
  private readonly environment;
11
11
  private readonly runId;
12
+ private readonly rootSuite;
12
13
  private startTime;
13
14
  /**
14
15
  * @param {LoggerInterface} logger
15
16
  * @param {WriterInterface} writer
16
17
  * @param {string | undefined} environment
18
+ * @param {string | undefined} rootSuite
17
19
  * @param {number | undefined} runId
18
20
  */
19
- constructor(logger: LoggerInterface, writer: WriterInterface, environment?: string, runId?: number);
21
+ constructor(logger: LoggerInterface, writer: WriterInterface, environment?: string, rootSuite?: string, runId?: number);
20
22
  /**
21
23
  * @returns {Promise<void>}
22
24
  */
@@ -38,14 +38,16 @@ class ReportReporter extends abstract_reporter_1.AbstractReporter {
38
38
  * @param {LoggerInterface} logger
39
39
  * @param {WriterInterface} writer
40
40
  * @param {string | undefined} environment
41
+ * @param {string | undefined} rootSuite
41
42
  * @param {number | undefined} runId
42
43
  */
43
- constructor(logger, writer, environment, runId) {
44
+ constructor(logger, writer, environment, rootSuite, runId) {
44
45
  super(logger);
45
46
  this.writer = writer;
46
47
  this.startTime = Date.now();
47
48
  this.environment = environment;
48
49
  this.runId = runId;
50
+ this.rootSuite = rootSuite;
49
51
  }
50
52
  /**
51
53
  * @returns {Promise<void>}
@@ -117,6 +119,25 @@ class ReportReporter extends abstract_reporter_1.AbstractReporter {
117
119
  }
118
120
  result.steps = this.copyStepAttachments(result.steps);
119
121
  result.run_id = this.runId ?? null;
122
+ if (result.relations != null && this.rootSuite != null) {
123
+ const data = {
124
+ title: this.rootSuite,
125
+ public_id: null,
126
+ };
127
+ result.relations.suite?.data.unshift(data);
128
+ }
129
+ else if (this.rootSuite != null) {
130
+ result.relations = {
131
+ suite: {
132
+ data: [
133
+ {
134
+ title: this.rootSuite,
135
+ public_id: null,
136
+ },
137
+ ],
138
+ },
139
+ };
140
+ }
120
141
  await this.writer.writeTestResult(result);
121
142
  }
122
143
  const path = await this.writer.writeReport(report);
@@ -81,6 +81,11 @@ export declare class TestOpsReporter extends AbstractReporter {
81
81
  * @private
82
82
  */
83
83
  private readonly defect;
84
+ /**
85
+ * @type {string | undefined}
86
+ * @private
87
+ */
88
+ private readonly rootSuite;
84
89
  /**
85
90
  * @type {number}
86
91
  * @private
@@ -95,9 +100,10 @@ export declare class TestOpsReporter extends AbstractReporter {
95
100
  * @param {LoggerInterface} logger
96
101
  * @param {ReporterOptionsType & TestOpsOptionsType} options
97
102
  * @param {QaseApiInterface} api
98
- * @param {number} environment
103
+ * @param {string | undefined} environment
104
+ * @param {string | undefined} rootSuite
99
105
  */
100
- constructor(logger: LoggerInterface, options: TestOpsOptionsType, api: QaseApiInterface, environment?: string);
106
+ constructor(logger: LoggerInterface, options: TestOpsOptionsType, api: QaseApiInterface, environment?: string, rootSuite?: string);
101
107
  /**
102
108
  * @returns {Promise<void>}
103
109
  */
@@ -20,9 +20,10 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
20
20
  * @param {LoggerInterface} logger
21
21
  * @param {ReporterOptionsType & TestOpsOptionsType} options
22
22
  * @param {QaseApiInterface} api
23
- * @param {number} environment
23
+ * @param {string | undefined} environment
24
+ * @param {string | undefined} rootSuite
24
25
  */
25
- constructor(logger, options, api, environment) {
26
+ constructor(logger, options, api, environment, rootSuite) {
26
27
  const { project, uploadAttachments, run, } = options;
27
28
  super(logger);
28
29
  this.api = api;
@@ -45,6 +46,7 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
45
46
  this.batchSize = options.batch?.size ?? defaultChunkSize;
46
47
  this.useV2 = options.useV2 ?? false;
47
48
  this.defect = options.defect ?? false;
49
+ this.rootSuite = rootSuite;
48
50
  }
49
51
  /**
50
52
  * @returns {Promise<void>}
@@ -140,6 +142,8 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
140
142
  if (this.firstIndex < this.results.length) {
141
143
  await this.publishResults(this.results.slice(this.firstIndex));
142
144
  }
145
+ // Clear results because we don't need to send them again then we use Cypress reporter
146
+ this.results.length = 0;
143
147
  if (!this.run.complete) {
144
148
  return;
145
149
  }
@@ -199,9 +203,10 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
199
203
  resultCreate.case_id = id;
200
204
  return resultCreate;
201
205
  }
206
+ const rootSuite = this.rootSuite ? `${this.rootSuite}\t` : '';
202
207
  resultCreate.case = {
203
208
  title: result.title,
204
- suite_title: result.relations?.suite ? result.relations?.suite?.data.map((suite) => suite.title).join('\t') : null,
209
+ suite_title: result.relations?.suite ? `${rootSuite}${result.relations?.suite?.data.map((suite) => suite.title).join('\t')}` : rootSuite,
205
210
  };
206
211
  this.logger.logDebug(`Transformed result: ${JSON.stringify(resultCreate)}`);
207
212
  return resultCreate;
@@ -227,10 +232,28 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
227
232
  * @private
228
233
  */
229
234
  getRelation(relation) {
230
- if (!relation || !relation.suite) {
231
- return {};
235
+ if (!relation?.suite) {
236
+ if (this.rootSuite == undefined) {
237
+ return {};
238
+ }
239
+ return {
240
+ suite: {
241
+ data: [
242
+ {
243
+ public_id: null,
244
+ title: this.rootSuite,
245
+ },
246
+ ],
247
+ },
248
+ };
232
249
  }
233
250
  const suiteData = [];
251
+ if (this.rootSuite != undefined) {
252
+ suiteData.push({
253
+ public_id: null,
254
+ title: this.rootSuite,
255
+ });
256
+ }
234
257
  for (const data of relation.suite.data) {
235
258
  suiteData.push({
236
259
  public_id: null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qase-javascript-commons",
3
- "version": "2.0.8",
3
+ "version": "2.0.10",
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.0",
36
+ "qaseio": "^2.1.3",
37
37
  "strip-ansi": "^6.0.1",
38
38
  "uuid": "^9.0.0"
39
39
  },