qase-javascript-commons 2.0.0-beta.9 → 2.0.0

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
@@ -1,11 +1,25 @@
1
1
  # Qase JavaScript Commons
2
2
 
3
- This package contains common classes and functions for working with Qase TMS API.
3
+ This module is an SDK for developing test reporters for Qase TMS.
4
+ It's using `qaseio` as an API client, and all Qase reporters are, in turn,
5
+ using this package.
6
+ You should use it if you're developing your own test reporter for a special-purpose framework.
7
+
8
+ To report results from tests using a popular framework or test runner,
9
+ don't install this module directly and
10
+ use the corresponding reporter module instead:
11
+
12
+ * [CucumberJS](https://github.com/qase-tms/qase-javascript/tree/main/qase-cucumberjs#readme)
13
+ * [Cypress](https://github.com/qase-tms/qase-javascript/tree/main/qase-cypress#readme)
14
+ * [Jest](https://github.com/qase-tms/qase-javascript/tree/main/qase-jest#readme)
15
+ * [Newman](https://github.com/qase-tms/qase-javascript/tree/main/qase-newman#readme)
16
+ * [Playwright](https://github.com/qase-tms/qase-javascript/tree/main/qase-playwright#readme)
17
+ * [TestCafe](https://github.com/qase-tms/qase-javascript/tree/main/qase-testcafe#readme)
4
18
 
5
19
  ## Installation
6
20
 
7
21
  ```bash
8
- npm install qase-javascript-commons@beta
22
+ npm install qase-javascript-commons
9
23
  ```
10
24
 
11
25
  ## Configuration
package/changelog.md CHANGED
@@ -1,3 +1,79 @@
1
+ # qase-javascript-commons@2.0.0
2
+
3
+ ## What's new
4
+
5
+ This is the first release version of the Qase JavaScript SDK.
6
+ It is numbered `2.0.0` (and not `1.0.0`) to match the release series of
7
+ test reporters for Playwright, Cypress, Jest and other frameworks.
8
+
9
+ ### Annotating test with field data
10
+
11
+ Tests can now be annotated with data for system and custom fields in Qase.
12
+ This feature is already implemented in the Playwright reporter:
13
+
14
+ ```js
15
+ test('Test with annotated fields', () => {
16
+ qase.id(1);
17
+ qase.fields({ 'severity': 'high', 'priority': 'medium' })
18
+ // ...
19
+ });
20
+ ```
21
+
22
+ ### Parametrized tests
23
+
24
+ Qase JavaScript SDK enables annotating tests with parameters, and passing parameter values to Qase.
25
+ Parameterized tests can report to a single test case, but each parameter variation is registered as
26
+ a standalone result, with its own run history.
27
+
28
+ ### Attachments from files and variables
29
+
30
+ Reporters can now upload attachments of various data types to Qase,
31
+ both from files and from variables.
32
+ It enables flexible and meticulous logging, such as collecting full HTTP request data,
33
+ including URL, headers, and payload.
34
+
35
+ ### Uploading results in flexible batches, asynchronously
36
+
37
+ Test reporters can now upload results in batches, while tests are still running.
38
+ It helps bring test results faster and enables acting on them long before the test run is complete.
39
+
40
+ ### Uniform configuration
41
+
42
+ Qase JavaScript SDK brings configuration with config files and environment variables
43
+ to a common standard, used with Qase reporters in all languages and frameworks.
44
+
45
+ For details, see the Configuration section in the README.
46
+
47
+ ### Latest API
48
+
49
+ Qase JavaScript SDK is using the latest Qase API client,
50
+ employing the full power of the stable v1 API version,
51
+ and enabling the use of experimental v2 API, tailored for uploading
52
+ huge amounts of test results.
53
+
54
+ # qase-javascript-commons@2.0.0-beta.12
55
+
56
+ ## What's new
57
+
58
+ Fixed an issue when the result has empty step action. Now the reporter will mark such steps as "Unnamed step" and will
59
+ log a warning message.
60
+
61
+ # qase-javascript-commons@2.0.0-beta.11
62
+
63
+ ## What's new
64
+
65
+ * The `useV2` option in the reporter's configuration will now enable using the experimental v2 API.
66
+ Before this fix, v1 API was used despite the configuration.
67
+
68
+ * Attachments from test steps will now be uploaded to Qase.
69
+ Before this fix, the reporter uploaded only the attachments made outside of any step scope.
70
+
71
+ # qase-javascript-commons@2.0.0-beta.10
72
+
73
+ ## What's new
74
+
75
+ Fixed an issue when the results published before the test run creation.
76
+
1
77
  # qase-javascript-commons@2.0.0-beta.9
2
78
 
3
79
  ## What's new
package/dist/qase.d.ts CHANGED
@@ -1,11 +1,17 @@
1
- import { AbstractReporter } from './reporters';
2
1
  import { OptionsType } from './options';
3
2
  import { TestResultType } from './models';
3
+ export interface ReporterInterface {
4
+ addTestResult(result: TestResultType): Promise<void>;
5
+ publish(): Promise<void>;
6
+ startTestRun(): void;
7
+ isCaptureLogs(): boolean;
8
+ }
4
9
  /**
5
10
  * @class QaseReporter
6
11
  * @implements AbstractReporter
7
12
  */
8
- export declare class QaseReporter extends AbstractReporter {
13
+ export declare class QaseReporter implements ReporterInterface {
14
+ private static instance;
9
15
  /**
10
16
  * @param {string} frameworkPackage
11
17
  * @param {string} frameworkName
@@ -15,15 +21,20 @@ export declare class QaseReporter extends AbstractReporter {
15
21
  */
16
22
  private static createHeaders;
17
23
  /**
18
- * @type {ReporterInterface}
24
+ * @type {InternalReporterInterface}
19
25
  * @private
20
26
  */
21
27
  private readonly upstreamReporter?;
22
28
  /**
23
- * @type {ReporterInterface}
29
+ * @type {InternalReporterInterface}
24
30
  * @private
25
31
  */
26
32
  private readonly fallbackReporter?;
33
+ /**
34
+ * @type {boolean | undefined}
35
+ * @private
36
+ */
37
+ private readonly captureLogs;
27
38
  /**
28
39
  * @type {boolean}
29
40
  * @private
@@ -34,14 +45,21 @@ export declare class QaseReporter extends AbstractReporter {
34
45
  * @private
35
46
  */
36
47
  private useFallback;
48
+ private readonly logger;
49
+ private startTestRunOperation?;
37
50
  /**
38
51
  * @param {OptionsType} options
39
52
  */
40
- constructor(options: OptionsType);
53
+ private constructor();
41
54
  /**
42
- * @returns {Promise<void>}
55
+ * @returns {void}
56
+ */
57
+ startTestRun(): void;
58
+ /**
59
+ * @param {OptionsType} options
60
+ * @returns {QaseReporter}
43
61
  */
44
- startTestRun(): Promise<void>;
62
+ static getInstance(options: OptionsType): QaseReporter;
45
63
  /**
46
64
  * @param {TestResultType} result
47
65
  */
@@ -51,6 +69,10 @@ export declare class QaseReporter extends AbstractReporter {
51
69
  * @private
52
70
  */
53
71
  private addTestResultToFallback;
72
+ /**
73
+ * @returns {boolean}
74
+ */
75
+ isCaptureLogs(): boolean;
54
76
  /**
55
77
  * @returns {Promise<void>}
56
78
  */
@@ -63,7 +85,7 @@ export declare class QaseReporter extends AbstractReporter {
63
85
  * @todo implement mode registry
64
86
  * @param {ModeEnum} mode
65
87
  * @param {OptionsType} options
66
- * @returns {ReporterInterface}
88
+ * @returns {InternalReporterInterface}
67
89
  * @private
68
90
  */
69
91
  private createReporter;
package/dist/qase.js CHANGED
@@ -16,6 +16,7 @@ const writer_1 = require("./writer");
16
16
  const get_package_version_1 = require("./utils/get-package-version");
17
17
  const custom_boundary_1 = require("./utils/custom-boundary");
18
18
  const disabled_exception_1 = require("./utils/disabled-exception");
19
+ const logger_1 = require("./utils/logger");
19
20
  /**
20
21
  * @type {Record<TestStatusEnum, (test: TestResultType) => string>}
21
22
  */
@@ -31,7 +32,7 @@ const resultLogMap = {
31
32
  * @class QaseReporter
32
33
  * @implements AbstractReporter
33
34
  */
34
- class QaseReporter extends reporters_1.AbstractReporter {
35
+ class QaseReporter {
35
36
  /**
36
37
  * @param {string} frameworkPackage
37
38
  * @param {string} frameworkName
@@ -68,9 +69,6 @@ class QaseReporter extends reporters_1.AbstractReporter {
68
69
  * @param {OptionsType} options
69
70
  */
70
71
  constructor(options) {
71
- const env = (0, env_1.envToConfig)((0, env_schema_1.default)({ schema: env_1.envValidationSchema }));
72
- const composedOptions = (0, options_1.composeOptions)(options, env);
73
- super({ debug: composedOptions.debug, captureLogs: composedOptions.captureLogs });
74
72
  /**
75
73
  * @type {boolean}
76
74
  * @private
@@ -81,7 +79,11 @@ class QaseReporter extends reporters_1.AbstractReporter {
81
79
  * @private
82
80
  */
83
81
  this.useFallback = false;
82
+ const env = (0, env_1.envToConfig)((0, env_schema_1.default)({ schema: env_1.envValidationSchema }));
83
+ const composedOptions = (0, options_1.composeOptions)(options, env);
84
+ this.logger = new logger_1.Logger({ debug: composedOptions.debug });
84
85
  this.logger.logDebug(`Config: ${JSON.stringify(composedOptions)}`);
86
+ this.captureLogs = composedOptions.captureLogs;
85
87
  try {
86
88
  this.upstreamReporter = this.createReporter(
87
89
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
@@ -120,13 +122,13 @@ class QaseReporter extends reporters_1.AbstractReporter {
120
122
  }
121
123
  }
122
124
  /**
123
- * @returns {Promise<void>}
125
+ * @returns {void}
124
126
  */
125
- async startTestRun() {
127
+ startTestRun() {
126
128
  if (!this.disabled) {
127
129
  this.logger.logDebug('Starting test run');
128
130
  try {
129
- await this.upstreamReporter?.startTestRun();
131
+ this.startTestRunOperation = this.upstreamReporter?.startTestRun();
130
132
  }
131
133
  catch (error) {
132
134
  this.logger.logError('Unable to start test run in the upstream reporter: ', error);
@@ -135,7 +137,7 @@ class QaseReporter extends reporters_1.AbstractReporter {
135
137
  return;
136
138
  }
137
139
  try {
138
- await this.fallbackReporter?.startTestRun();
140
+ this.startTestRunOperation = this.fallbackReporter?.startTestRun();
139
141
  }
140
142
  catch (error) {
141
143
  this.logger.logError('Unable to start test run in the fallback reporter: ', error);
@@ -144,6 +146,16 @@ class QaseReporter extends reporters_1.AbstractReporter {
144
146
  }
145
147
  }
146
148
  }
149
+ /**
150
+ * @param {OptionsType} options
151
+ * @returns {QaseReporter}
152
+ */
153
+ static getInstance(options) {
154
+ if (!QaseReporter.instance) {
155
+ QaseReporter.instance = new QaseReporter(options);
156
+ }
157
+ return QaseReporter.instance;
158
+ }
147
159
  /**
148
160
  * @param {TestResultType} result
149
161
  */
@@ -184,11 +196,18 @@ class QaseReporter extends reporters_1.AbstractReporter {
184
196
  this.disabled = true;
185
197
  }
186
198
  }
199
+ /**
200
+ * @returns {boolean}
201
+ */
202
+ isCaptureLogs() {
203
+ return this.captureLogs ?? false;
204
+ }
187
205
  /**
188
206
  * @returns {Promise<void>}
189
207
  */
190
208
  async publish() {
191
209
  if (!this.disabled) {
210
+ await this.startTestRunOperation;
192
211
  this.logger.logDebug('Publishing test run results');
193
212
  if (this.useFallback) {
194
213
  await this.publishFallback();
@@ -226,14 +245,14 @@ class QaseReporter extends reporters_1.AbstractReporter {
226
245
  * @todo implement mode registry
227
246
  * @param {ModeEnum} mode
228
247
  * @param {OptionsType} options
229
- * @returns {ReporterInterface}
248
+ * @returns {InternalReporterInterface}
230
249
  * @private
231
250
  */
232
251
  createReporter(mode, options) {
233
- const { frameworkPackage, frameworkName, reporterName, environment, report = {}, testops = {}, ...commonOptions } = options;
252
+ const { frameworkPackage, frameworkName, reporterName, environment, report = {}, testops = {}, } = options;
234
253
  switch (mode) {
235
254
  case options_1.ModeEnum.testops: {
236
- const { api: { token, headers, ...api } = {}, project, run: { title, description, ...run } = {}, plan = {}, batch = {}, uploadAttachments, } = testops;
255
+ const { api: { token, headers, ...api } = {}, project, run: { title, description, ...run } = {}, plan = {}, batch = {}, useV2, uploadAttachments, } = testops;
237
256
  if (!token) {
238
257
  throw new Error(`Either "testops.api.token" parameter or "${env_1.EnvApiEnum.token}" environment variable is required in "testops" mode`);
239
258
  }
@@ -248,7 +267,7 @@ class QaseReporter extends reporters_1.AbstractReporter {
248
267
  },
249
268
  ...api,
250
269
  }, custom_boundary_1.CustomBoundaryFormData);
251
- return new reporters_1.TestOpsReporter({
270
+ return new reporters_1.TestOpsReporter(this.logger, {
252
271
  project,
253
272
  uploadAttachments,
254
273
  run: {
@@ -258,17 +277,13 @@ class QaseReporter extends reporters_1.AbstractReporter {
258
277
  },
259
278
  plan,
260
279
  batch,
261
- debug: commonOptions.debug,
262
- captureLogs: commonOptions.captureLogs,
280
+ useV2,
263
281
  }, apiClient, typeof environment === 'number' ? environment : undefined);
264
282
  }
265
283
  case options_1.ModeEnum.report: {
266
284
  const localOptions = report.connections?.[writer_1.DriverEnum.local];
267
285
  const writer = new writer_1.FsWriter(localOptions);
268
- return new reporters_1.ReportReporter({
269
- debug: commonOptions.debug,
270
- captureLogs: commonOptions.captureLogs,
271
- }, writer, typeof environment === 'number' ? environment.toString() : environment, testops.run?.id);
286
+ return new reporters_1.ReportReporter(this.logger, writer, typeof environment === 'number' ? environment.toString() : environment, testops.run?.id);
272
287
  }
273
288
  case options_1.ModeEnum.off:
274
289
  throw new disabled_exception_1.DisabledException();
@@ -1,32 +1,18 @@
1
1
  import { TestResultType } from '../models';
2
- export interface LoggerInterface {
3
- log(message: string): void;
4
- logError(message: string, error?: unknown): void;
5
- logDebug(message: string): void;
6
- }
7
- export interface ReporterOptionsType {
8
- debug?: boolean | undefined;
9
- captureLogs?: boolean | undefined;
10
- }
11
- export interface ReporterInterface {
2
+ import { LoggerInterface } from '../utils/logger';
3
+ export interface InternalReporterInterface {
12
4
  addTestResult(result: TestResultType): Promise<void>;
13
5
  publish(): Promise<void>;
14
6
  startTestRun(): Promise<void>;
15
7
  getTestResults(): TestResultType[];
16
8
  setTestResults(results: TestResultType[]): void;
17
- isCaptureLogs(): boolean;
18
9
  }
19
10
  /**
20
11
  * @abstract
21
12
  * @class AbstractReporter
22
- * @implements ReporterInterface
13
+ * @implements InternalReporterInterface
23
14
  */
24
- export declare abstract class AbstractReporter implements ReporterInterface {
25
- /**
26
- * @type {boolean | undefined}
27
- * @private
28
- */
29
- private readonly captureLogs;
15
+ export declare abstract class AbstractReporter implements InternalReporterInterface {
30
16
  /**
31
17
  * @type {LoggerInterface}
32
18
  * @private
@@ -46,18 +32,14 @@ export declare abstract class AbstractReporter implements ReporterInterface {
46
32
  */
47
33
  abstract startTestRun(): Promise<void>;
48
34
  /**
49
- * @param {ReporterOptionsType} options
50
35
  * @protected
36
+ * @param {LoggerInterface} logger
51
37
  */
52
- protected constructor(options: ReporterOptionsType | undefined);
38
+ protected constructor(logger: LoggerInterface);
53
39
  /**
54
40
  * @returns {TestResultType[]}
55
41
  */
56
42
  getTestResults(): TestResultType[];
57
- /**
58
- * @returns {boolean}
59
- */
60
- isCaptureLogs(): boolean;
61
43
  /**
62
44
  * @param {TestResultType} result
63
45
  */
@@ -2,26 +2,23 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AbstractReporter = void 0;
4
4
  const uuid_1 = require("uuid");
5
- const logger_1 = require("../utils/logger");
6
5
  /**
7
6
  * @abstract
8
7
  * @class AbstractReporter
9
- * @implements ReporterInterface
8
+ * @implements InternalReporterInterface
10
9
  */
11
10
  class AbstractReporter {
12
11
  /**
13
- * @param {ReporterOptionsType} options
14
12
  * @protected
13
+ * @param {LoggerInterface} logger
15
14
  */
16
- constructor(options) {
15
+ constructor(logger) {
17
16
  /**
18
17
  * @type {TestResultType[]}
19
18
  * @protected
20
19
  */
21
20
  this.results = [];
22
- const { debug, captureLogs } = options ?? {};
23
- this.captureLogs = captureLogs;
24
- this.logger = new logger_1.Logger({ debug });
21
+ this.logger = logger;
25
22
  }
26
23
  /**
27
24
  * @returns {TestResultType[]}
@@ -29,12 +26,6 @@ class AbstractReporter {
29
26
  getTestResults() {
30
27
  return this.results;
31
28
  }
32
- /**
33
- * @returns {boolean}
34
- */
35
- isCaptureLogs() {
36
- return this.captureLogs ?? false;
37
- }
38
29
  /**
39
30
  * @param {TestResultType} result
40
31
  */
@@ -1,3 +1,3 @@
1
- export { AbstractReporter, type ReporterInterface, type ReporterOptionsType, type LoggerInterface, } from './abstract-reporter';
1
+ export { AbstractReporter, type InternalReporterInterface, } from './abstract-reporter';
2
2
  export { ReportReporter } from './report-reporter';
3
3
  export { TestOpsReporter, type TestOpsOptionsType } from './testops-reporter';
@@ -1,5 +1,6 @@
1
- import { AbstractReporter, ReporterOptionsType } from './abstract-reporter';
1
+ import { AbstractReporter } from './abstract-reporter';
2
2
  import { WriterInterface } from '../writer';
3
+ import { LoggerInterface } from '../utils/logger';
3
4
  /**
4
5
  * @class ReportReporter
5
6
  * @extends AbstractReporter
@@ -10,12 +11,12 @@ export declare class ReportReporter extends AbstractReporter {
10
11
  private readonly runId;
11
12
  private startTime;
12
13
  /**
13
- * @param {ReporterOptionsType} options
14
+ * @param {LoggerInterface} logger
14
15
  * @param {WriterInterface} writer
15
16
  * @param {string | undefined} environment
16
17
  * @param {number | undefined} runId
17
18
  */
18
- constructor(options: ReporterOptionsType | undefined, writer: WriterInterface, environment?: string, runId?: number);
19
+ constructor(logger: LoggerInterface, writer: WriterInterface, environment?: string, runId?: number);
19
20
  /**
20
21
  * @returns {Promise<void>}
21
22
  */
@@ -35,13 +35,13 @@ const process = __importStar(require("process"));
35
35
  */
36
36
  class ReportReporter extends abstract_reporter_1.AbstractReporter {
37
37
  /**
38
- * @param {ReporterOptionsType} options
38
+ * @param {LoggerInterface} logger
39
39
  * @param {WriterInterface} writer
40
40
  * @param {string | undefined} environment
41
41
  * @param {number | undefined} runId
42
42
  */
43
- constructor(options, writer, environment, runId) {
44
- super(options);
43
+ constructor(logger, writer, environment, runId) {
44
+ super(logger);
45
45
  this.writer = writer;
46
46
  this.startTime = Date.now();
47
47
  this.environment = environment;
@@ -1,6 +1,7 @@
1
1
  import { QaseApiInterface, ResultStepStatus, TestStepResultCreateStatusEnum } from 'qaseio';
2
- import { AbstractReporter, ReporterOptionsType } from './abstract-reporter';
2
+ import { AbstractReporter } from './abstract-reporter';
3
3
  import { StepStatusEnum, TestResultType, TestStatusEnum } from '../models';
4
+ import { LoggerInterface } from '../utils/logger';
4
5
  export type TestOpsRunType = {
5
6
  id?: number | undefined;
6
7
  title: string;
@@ -91,11 +92,12 @@ export declare class TestOpsReporter extends AbstractReporter {
91
92
  */
92
93
  private isTestRunReady;
93
94
  /**
95
+ * @param {LoggerInterface} logger
94
96
  * @param {ReporterOptionsType & TestOpsOptionsType} options
95
97
  * @param {QaseApiInterface} api
96
98
  * @param {number} environment
97
99
  */
98
- constructor(options: ReporterOptionsType & TestOpsOptionsType, api: QaseApiInterface, environment?: number);
100
+ constructor(logger: LoggerInterface, options: TestOpsOptionsType, api: QaseApiInterface, environment?: number);
99
101
  /**
100
102
  * @returns {Promise<void>}
101
103
  */
@@ -145,16 +147,19 @@ export declare class TestOpsReporter extends AbstractReporter {
145
147
  private getRelation;
146
148
  /**
147
149
  * @param {TestStepType[]} steps
150
+ * @param testTitle
148
151
  * @returns Promise<ResultStep[]>
149
152
  * @private
150
153
  */
151
154
  private transformSteps;
152
155
  /**
153
156
  * @param {TestStepType[]} steps
157
+ * @param testTitle
154
158
  * @returns Promise<TestStepResultCreate[]>
155
159
  * @private
156
160
  */
157
161
  private transformStepsV1;
162
+ private logEmptyStep;
158
163
  /**
159
164
  * @param {number} runId
160
165
  * @returns {Promise<void>}
@@ -17,13 +17,14 @@ const defaultChunkSize = 200;
17
17
  */
18
18
  class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
19
19
  /**
20
+ * @param {LoggerInterface} logger
20
21
  * @param {ReporterOptionsType & TestOpsOptionsType} options
21
22
  * @param {QaseApiInterface} api
22
23
  * @param {number} environment
23
24
  */
24
- constructor(options, api, environment) {
25
- const { project, uploadAttachments, run, ...restOptions } = options;
26
- super(restOptions);
25
+ constructor(logger, options, api, environment) {
26
+ const { project, uploadAttachments, run, } = options;
27
+ super(logger);
27
28
  this.api = api;
28
29
  /**
29
30
  * @type {number}
@@ -145,7 +146,7 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
145
146
  */
146
147
  async transformTestResult(result) {
147
148
  const attachments = await this.uploadAttachments(result.attachments);
148
- const steps = await this.transformSteps(result.steps);
149
+ const steps = await this.transformSteps(result.steps, result.title);
149
150
  const model = {
150
151
  title: result.title,
151
152
  execution: this.getExecution(result.execution),
@@ -166,7 +167,7 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
166
167
  */
167
168
  async transformTestResultV1(result) {
168
169
  const attachments = await this.uploadAttachments(result.attachments);
169
- const steps = await this.transformStepsV1(result.steps);
170
+ const steps = await this.transformStepsV1(result.steps, result.title);
170
171
  const resultCreate = {
171
172
  attachments: attachments,
172
173
  comment: result.message,
@@ -230,25 +231,32 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
230
231
  }
231
232
  /**
232
233
  * @param {TestStepType[]} steps
234
+ * @param testTitle
233
235
  * @returns Promise<ResultStep[]>
234
236
  * @private
235
237
  */
236
- async transformSteps(steps) {
238
+ async transformSteps(steps, testTitle) {
237
239
  const resultsSteps = [];
238
240
  for (const step of steps) {
239
241
  const attachmentHashes = await this.uploadAttachments(step.attachments);
240
242
  const resultStep = {
241
243
  data: {
242
244
  action: '',
243
- attachments: attachmentHashes,
244
245
  },
245
246
  execution: {
246
247
  status: TestOpsReporter.stepStatusMap[step.execution.status],
248
+ attachments: attachmentHashes,
247
249
  },
248
250
  };
249
251
  if (step.step_type === models_1.StepType.TEXT) {
250
252
  if ('action' in step.data && resultStep.data != undefined) {
251
- resultStep.data.action = step.data.action;
253
+ if (step.data.action === '') {
254
+ this.logEmptyStep(testTitle);
255
+ resultStep.data.action = 'Unnamed step';
256
+ }
257
+ else {
258
+ resultStep.data.action = step.data.action;
259
+ }
252
260
  }
253
261
  }
254
262
  if (step.step_type === models_1.StepType.GHERKIN) {
@@ -257,7 +265,7 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
257
265
  }
258
266
  }
259
267
  if (step.steps.length > 0) {
260
- resultStep.steps = await this.transformSteps(step.steps);
268
+ resultStep.steps = await this.transformSteps(step.steps, testTitle);
261
269
  }
262
270
  resultsSteps.push(resultStep);
263
271
  }
@@ -265,10 +273,11 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
265
273
  }
266
274
  /**
267
275
  * @param {TestStepType[]} steps
276
+ * @param testTitle
268
277
  * @returns Promise<TestStepResultCreate[]>
269
278
  * @private
270
279
  */
271
- async transformStepsV1(steps) {
280
+ async transformStepsV1(steps, testTitle) {
272
281
  const resultsSteps = [];
273
282
  for (const step of steps) {
274
283
  const attachmentHashes = await this.uploadAttachments(step.attachments);
@@ -278,7 +287,13 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
278
287
  };
279
288
  if (step.step_type === models_1.StepType.TEXT) {
280
289
  if ('action' in step.data) {
281
- resultStep.action = step.data.action;
290
+ if (step.data.action === '') {
291
+ this.logEmptyStep(testTitle);
292
+ resultStep.action = 'Unnamed step';
293
+ }
294
+ else {
295
+ resultStep.action = step.data.action;
296
+ }
282
297
  }
283
298
  }
284
299
  if (step.step_type === models_1.StepType.GHERKIN) {
@@ -287,12 +302,15 @@ class TestOpsReporter extends abstract_reporter_1.AbstractReporter {
287
302
  }
288
303
  }
289
304
  if (step.steps.length > 0) {
290
- resultStep.steps = await this.transformStepsV1(step.steps);
305
+ resultStep.steps = await this.transformStepsV1(step.steps, testTitle);
291
306
  }
292
307
  resultsSteps.push(resultStep);
293
308
  }
294
309
  return resultsSteps;
295
310
  }
311
+ logEmptyStep(testTitle) {
312
+ this.logger.log((0, chalk_1.default) `{magenta Test '${testTitle}' has empty action in step. The reporter will mark this step as unnamed step.}`);
313
+ }
296
314
  /**
297
315
  * @param {number} runId
298
316
  * @returns {Promise<void>}
@@ -1,4 +1,9 @@
1
- export declare class Logger {
1
+ export interface LoggerInterface {
2
+ log(message: string): void;
3
+ logError(message: string, error?: unknown): void;
4
+ logDebug(message: string): void;
5
+ }
6
+ export declare class Logger implements LoggerInterface {
2
7
  private readonly debug;
3
8
  private readonly filePath;
4
9
  constructor(options: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qase-javascript-commons",
3
- "version": "2.0.0-beta.9",
3
+ "version": "2.0.0",
4
4
  "description": "Qase JS Reporters",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -21,7 +21,7 @@
21
21
  "test": "jest --passWithNoTests",
22
22
  "clean": "rm -rf dist"
23
23
  },
24
- "author": "Dimitri Harding <dharding@dimitriharding.com>",
24
+ "author": "Qase Team <dharding@dimitriharding.com>",
25
25
  "license": "Apache-2.0",
26
26
  "dependencies": {
27
27
  "ajv": "^8.12.0",
@@ -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-beta.1",
36
+ "qaseio": "^2.1.0",
37
37
  "strip-ansi": "^6.0.1",
38
38
  "uuid": "^9.0.0"
39
39
  },