@testomatio/reporter 2.0.0-beta-esm → 2.0.1-beta-esm

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 (115) hide show
  1. package/lib/adapter/codecept.d.ts +2 -0
  2. package/lib/adapter/codecept.js +31 -24
  3. package/lib/adapter/cucumber/current.d.ts +14 -0
  4. package/lib/adapter/cucumber/legacy.d.ts +0 -0
  5. package/lib/adapter/cucumber.d.ts +2 -0
  6. package/lib/adapter/cypress-plugin/index.d.ts +2 -0
  7. package/lib/adapter/cypress-plugin/index.js +11 -9
  8. package/lib/adapter/jasmine.d.ts +11 -0
  9. package/lib/adapter/jest.d.ts +13 -0
  10. package/lib/adapter/mocha.d.ts +2 -0
  11. package/lib/adapter/mocha.js +4 -3
  12. package/lib/adapter/playwright.d.ts +14 -0
  13. package/lib/adapter/playwright.js +58 -33
  14. package/lib/adapter/vitest.d.ts +35 -0
  15. package/lib/adapter/vitest.js +6 -6
  16. package/lib/adapter/webdriver.d.ts +24 -0
  17. package/lib/adapter/webdriver.js +34 -6
  18. package/lib/bin/cli.d.ts +2 -0
  19. package/lib/bin/cli.js +228 -0
  20. package/lib/bin/reportXml.d.ts +2 -0
  21. package/lib/bin/reportXml.js +11 -9
  22. package/lib/bin/startTest.d.ts +2 -0
  23. package/lib/bin/startTest.js +9 -5
  24. package/lib/bin/uploadArtifacts.d.ts +2 -0
  25. package/lib/bin/uploadArtifacts.js +81 -0
  26. package/lib/client.d.ts +76 -0
  27. package/lib/client.js +111 -45
  28. package/lib/config.d.ts +1 -0
  29. package/lib/constants.d.ts +25 -0
  30. package/lib/constants.js +5 -1
  31. package/lib/data-storage.d.ts +34 -0
  32. package/lib/data-storage.js +2 -2
  33. package/lib/junit-adapter/adapter.d.ts +9 -0
  34. package/lib/junit-adapter/csharp.d.ts +4 -0
  35. package/lib/junit-adapter/index.d.ts +3 -0
  36. package/lib/junit-adapter/java.d.ts +5 -0
  37. package/lib/junit-adapter/javascript.d.ts +4 -0
  38. package/lib/junit-adapter/python.d.ts +5 -0
  39. package/lib/junit-adapter/ruby.d.ts +4 -0
  40. package/lib/output.d.ts +11 -0
  41. package/lib/package.json +3 -1
  42. package/lib/pipe/bitbucket.d.ts +23 -0
  43. package/lib/pipe/bitbucket.js +2 -2
  44. package/lib/pipe/csv.d.ts +47 -0
  45. package/lib/pipe/csv.js +2 -2
  46. package/lib/pipe/debug.d.ts +29 -0
  47. package/lib/pipe/debug.js +108 -0
  48. package/lib/pipe/github.d.ts +30 -0
  49. package/lib/pipe/github.js +2 -2
  50. package/lib/pipe/gitlab.d.ts +23 -0
  51. package/lib/pipe/gitlab.js +2 -2
  52. package/lib/pipe/html.d.ts +34 -0
  53. package/lib/pipe/html.js +8 -1
  54. package/lib/pipe/index.d.ts +1 -0
  55. package/lib/pipe/index.js +3 -3
  56. package/lib/pipe/testomatio.d.ts +70 -0
  57. package/lib/pipe/testomatio.js +50 -30
  58. package/lib/reporter-functions.d.ts +34 -0
  59. package/lib/reporter-functions.js +17 -7
  60. package/lib/reporter.d.ts +232 -0
  61. package/lib/reporter.js +19 -33
  62. package/lib/services/artifacts.d.ts +33 -0
  63. package/lib/services/index.d.ts +9 -0
  64. package/lib/services/key-values.d.ts +27 -0
  65. package/lib/services/key-values.js +1 -1
  66. package/lib/services/logger.d.ts +64 -0
  67. package/lib/template/testomatio.hbs +651 -1366
  68. package/lib/uploader.d.ts +60 -0
  69. package/lib/uploader.js +312 -0
  70. package/lib/utils/pipe_utils.d.ts +41 -0
  71. package/lib/utils/pipe_utils.js +3 -5
  72. package/lib/utils/utils.d.ts +45 -0
  73. package/lib/utils/utils.js +69 -2
  74. package/lib/xmlReader.d.ts +92 -0
  75. package/lib/xmlReader.js +22 -12
  76. package/package.json +15 -9
  77. package/src/adapter/codecept.js +30 -24
  78. package/src/adapter/cypress-plugin/index.js +5 -3
  79. package/src/adapter/mocha.cjs +1 -1
  80. package/src/adapter/mocha.js +4 -3
  81. package/src/adapter/playwright.js +59 -31
  82. package/src/adapter/vitest.js +6 -6
  83. package/src/adapter/webdriver.js +41 -10
  84. package/src/bin/cli.js +280 -0
  85. package/src/bin/reportXml.js +15 -8
  86. package/src/bin/startTest.js +7 -3
  87. package/src/bin/uploadArtifacts.js +90 -0
  88. package/src/client.js +137 -56
  89. package/src/constants.js +5 -1
  90. package/src/data-storage.js +2 -2
  91. package/src/pipe/bitbucket.js +2 -2
  92. package/src/pipe/csv.js +3 -3
  93. package/src/pipe/debug.js +104 -0
  94. package/src/pipe/github.js +2 -3
  95. package/src/pipe/gitlab.js +6 -6
  96. package/src/pipe/html.js +11 -3
  97. package/src/pipe/index.js +5 -7
  98. package/src/pipe/testomatio.js +72 -67
  99. package/src/reporter-functions.js +18 -7
  100. package/src/reporter.cjs_decprecated +21 -0
  101. package/src/reporter.js +20 -11
  102. package/src/services/key-values.js +1 -1
  103. package/src/services/logger.js +4 -2
  104. package/src/template/testomatio.hbs +651 -1366
  105. package/src/uploader.js +371 -0
  106. package/src/utils/pipe_utils.js +4 -12
  107. package/src/utils/utils.js +48 -6
  108. package/src/xmlReader.js +26 -15
  109. package/lib/adapter/jasmine/jasmine.js +0 -63
  110. package/lib/adapter/mocha/mocha.js +0 -125
  111. package/lib/fileUploader.js +0 -245
  112. package/lib/utils/chalk.js +0 -10
  113. package/src/fileUploader.js +0 -307
  114. package/src/reporter.cjs +0 -22
  115. package/src/utils/chalk.js +0 -13
@@ -0,0 +1,30 @@
1
+ export default GitHubPipe;
2
+ export type Pipe = import("../../types/types.js").Pipe;
3
+ export type TestData = import("../../types/types.js").TestData;
4
+ /**
5
+ * @typedef {import('../../types/types.js').Pipe} Pipe
6
+ * @typedef {import('../../types/types.js').TestData} TestData
7
+ * @class GitHubPipe
8
+ * @implements {Pipe}
9
+ */
10
+ declare class GitHubPipe implements Pipe {
11
+ constructor(params: any, store?: {});
12
+ isEnabled: boolean;
13
+ store: {};
14
+ tests: any[];
15
+ token: any;
16
+ ref: string;
17
+ repo: string;
18
+ jobKey: string;
19
+ hiddenCommentData: string;
20
+ issue: number;
21
+ start: Date;
22
+ prepareRun(): Promise<void>;
23
+ createRun(): Promise<void>;
24
+ addTest(test: any): void;
25
+ finishRun(runParams: any): Promise<void>;
26
+ octokit: import("@octokit/core").Octokit & {
27
+ paginate: import("@octokit/plugin-paginate-rest").PaginateInterface;
28
+ } & import("@octokit/plugin-rest-endpoint-methods/dist-types/generated/method-types.js").RestEndpointMethods & import("@octokit/plugin-rest-endpoint-methods/dist-types/types.js").Api;
29
+ toString(): string;
30
+ }
@@ -14,8 +14,8 @@ const utils_js_1 = require("../utils/utils.js");
14
14
  const pipe_utils_js_1 = require("../utils/pipe_utils.js");
15
15
  const debug = (0, debug_1.default)('@testomatio/reporter:pipe:github');
16
16
  /**
17
- * @typedef {import('../../types').Pipe} Pipe
18
- * @typedef {import('../../types').TestData} TestData
17
+ * @typedef {import('../../types/types.js').Pipe} Pipe
18
+ * @typedef {import('../../types/types.js').TestData} TestData
19
19
  * @class GitHubPipe
20
20
  * @implements {Pipe}
21
21
  */
@@ -0,0 +1,23 @@
1
+ export default GitLabPipe;
2
+ export type Pipe = import("../../types/types.js").Pipe;
3
+ export type TestData = import("../../types/types.js").TestData;
4
+ /**
5
+ * @class GitLabPipe
6
+ * @typedef {import('../../types/types.js').Pipe} Pipe
7
+ * @typedef {import('../../types/types.js').TestData} TestData
8
+ */
9
+ declare class GitLabPipe {
10
+ constructor(params: any, store?: {});
11
+ isEnabled: boolean;
12
+ ENV: NodeJS.ProcessEnv;
13
+ store: {};
14
+ tests: any[];
15
+ token: any;
16
+ hiddenCommentData: string;
17
+ prepareRun(): Promise<void>;
18
+ createRun(): Promise<void>;
19
+ addTest(test: any): void;
20
+ finishRun(runParams: any): Promise<void>;
21
+ toString(): string;
22
+ updateRun(): void;
23
+ }
@@ -17,8 +17,8 @@ const debug = (0, debug_1.default)('@testomatio/reporter:pipe:gitlab');
17
17
  //! and your pipeline trigger should be merge_request
18
18
  /**
19
19
  * @class GitLabPipe
20
- * @typedef {import('../../types').Pipe} Pipe
21
- * @typedef {import('../../types').TestData} TestData
20
+ * @typedef {import('../../types/types.js').Pipe} Pipe
21
+ * @typedef {import('../../types/types.js').TestData} TestData
22
22
  */
23
23
  class GitLabPipe {
24
24
  constructor(params, store = {}) {
@@ -0,0 +1,34 @@
1
+ export default HtmlPipe;
2
+ declare class HtmlPipe {
3
+ constructor(params: any, store?: {});
4
+ store: {};
5
+ title: any;
6
+ apiKey: any;
7
+ isHtml: string;
8
+ isEnabled: boolean;
9
+ htmlOutputPath: string;
10
+ fullHtmlOutputPath: string;
11
+ filenameMsg: string;
12
+ tests: any[];
13
+ htmlReportDir: string;
14
+ htmlReportName: string;
15
+ templateFolderPath: string;
16
+ templateHtmlPath: string;
17
+ createRun(): Promise<void>;
18
+ updateRun(): void;
19
+ /**
20
+ * Add test data to the result array for saving. As a result of this function, we get a result object to save.
21
+ * @param {import('../../types/types.js').RunData} test - object which includes each test entry.
22
+ */
23
+ addTest(test: import("../../types/types.js").RunData): void;
24
+ finishRun(runParams: any): Promise<void>;
25
+ /**
26
+ * Generates an HTML report based on provided test data and a template.
27
+ * @param {object} opts - Test options used to generate the HTML report:
28
+ * runParams, tests, outputPath, templatePath
29
+ * @returns {void} - This function does not return anything.
30
+ */
31
+ buildReport(opts: object): void;
32
+ toString(): string;
33
+ #private;
34
+ }
package/lib/pipe/html.js CHANGED
@@ -58,7 +58,7 @@ class HtmlPipe {
58
58
  }
59
59
  /**
60
60
  * Add test data to the result array for saving. As a result of this function, we get a result object to save.
61
- * @param {import('../../types').RunData} test - object which includes each test entry.
61
+ * @param {import('../../types/types.js').RunData} test - object which includes each test entry.
62
62
  */
63
63
  addTest(test) {
64
64
  if (!this.isEnabled)
@@ -106,6 +106,13 @@ class HtmlPipe {
106
106
  console.log(picocolors_1.default.blue(msg));
107
107
  }
108
108
  tests.forEach(test => {
109
+ // steps could be an array or a string
110
+ test.steps = Array.isArray(test.steps)
111
+ ? (test.steps = test.steps
112
+ .map(step => (0, utils_js_1.formatStep)(step))
113
+ .flat()
114
+ .join('\n'))
115
+ : test.steps;
109
116
  if (!test.message?.trim()) {
110
117
  test.message = "This test has no 'message' code";
111
118
  }
@@ -0,0 +1 @@
1
+ export function pipesFactory(params: any, opts: any): Promise<any[]>;
package/lib/pipe/index.js CHANGED
@@ -37,6 +37,7 @@ const gitlab_js_1 = __importDefault(require("./gitlab.js"));
37
37
  const csv_js_1 = __importDefault(require("./csv.js"));
38
38
  const html_js_1 = __importDefault(require("./html.js"));
39
39
  const bitbucket_js_1 = require("./bitbucket.js");
40
+ const debug_js_1 = require("./debug.js");
40
41
  async function pipesFactory(params, opts) {
41
42
  const extraPipes = [];
42
43
  // Add extra pipes into package.json file:
@@ -72,12 +73,11 @@ async function pipesFactory(params, opts) {
72
73
  new csv_js_1.default(params, opts),
73
74
  new html_js_1.default(params, opts),
74
75
  new bitbucket_js_1.BitbucketPipe(params, opts),
76
+ new debug_js_1.DebugPipe(params, opts),
75
77
  ...extraPipes,
76
78
  ];
77
79
  const pipesEnabled = pipes.filter(p => p.isEnabled);
78
- console.log(constants_js_1.APP_PREFIX, picocolors_1.default.cyan('Pipes:'), picocolors_1.default.cyan(pipesEnabled
79
- .map(p => p.toString())
80
- .join(', ') || 'No pipes enabled'));
80
+ console.log(constants_js_1.APP_PREFIX, picocolors_1.default.cyan('Pipes:'), picocolors_1.default.cyan(pipesEnabled.map(p => p.toString()).join(', ') || 'No pipes enabled'));
81
81
  if (!pipesEnabled.length) {
82
82
  console.log(constants_js_1.APP_PREFIX, picocolors_1.default.dim('If you want to use Testomatio reporter, pass your token as TESTOMATIO env variable'));
83
83
  }
@@ -0,0 +1,70 @@
1
+ export default TestomatioPipe;
2
+ export type Pipe = import("../../types/types.js").Pipe;
3
+ export type TestData = import("../../types/types.js").TestData;
4
+ /**
5
+ * @typedef {import('../../types/types.js').Pipe} Pipe
6
+ * @typedef {import('../../types/types.js').TestData} TestData
7
+ * @class TestomatioPipe
8
+ * @implements {Pipe}
9
+ */
10
+ declare class TestomatioPipe implements Pipe {
11
+ constructor(params: any, store: any);
12
+ batch: {
13
+ isEnabled: any;
14
+ intervalFunction: any;
15
+ intervalTime: number;
16
+ tests: any[];
17
+ batchIndex: number;
18
+ numberOfTimesCalledWithoutTests: number;
19
+ };
20
+ retriesTimestamps: any[];
21
+ reportingCanceledDueToReqFailures: boolean;
22
+ notReportedTestsCount: number;
23
+ isEnabled: boolean;
24
+ url: any;
25
+ apiKey: any;
26
+ parallel: any;
27
+ store: any;
28
+ title: any;
29
+ sharedRun: boolean;
30
+ sharedRunTimeout: boolean;
31
+ groupTitle: any;
32
+ env: string;
33
+ label: string;
34
+ axios: any;
35
+ proceed: string;
36
+ jiraId: string;
37
+ runId: any;
38
+ createNewTests: any;
39
+ hasUnmatchedTests: boolean;
40
+ requestFailures: number;
41
+ /**
42
+ * Asynchronously prepares and retrieves the Testomat.io test grepList based on the provided options.
43
+ * @param {Object} opts - The options for preparing the test grepList.
44
+ * @returns {Promise<string[]>} - An array containing the retrieved
45
+ * test grepList, or an empty array if no tests are found or the request is disabled.
46
+ * @throws {Error} - Throws an error if there was a problem while making the request.
47
+ */
48
+ prepareRun(opts: any): Promise<string[]>;
49
+ /**
50
+ * Creates a new run on Testomat.io
51
+ * @param {{isBatchEnabled?: boolean}} params
52
+ * @returns Promise<void>
53
+ */
54
+ createRun(params?: {
55
+ isBatchEnabled?: boolean;
56
+ }): Promise<void>;
57
+ runUrl: string;
58
+ runPublicUrl: any;
59
+ /**
60
+ * Adds a test to the batch uploader (or reports a single test if batch uploading is disabled)
61
+ */
62
+ addTest(data: any): void;
63
+ /**
64
+ * @param {import('../../types/types.js').RunData} params
65
+ * @returns
66
+ */
67
+ finishRun(params: import("../../types/types.js").RunData): Promise<void>;
68
+ toString(): string;
69
+ #private;
70
+ }
@@ -19,8 +19,8 @@ if (process.env.TESTOMATIO_RUN) {
19
19
  // process.env.runId = process.env.TESTOMATIO_RUN;
20
20
  }
21
21
  /**
22
- * @typedef {import('../../types').Pipe} Pipe
23
- * @typedef {import('../../types').TestData} TestData
22
+ * @typedef {import('../../types/types.js').Pipe} Pipe
23
+ * @typedef {import('../../types/types.js').TestData} TestData
24
24
  * @class TestomatioPipe
25
25
  * @implements {Pipe}
26
26
  */
@@ -59,11 +59,13 @@ class TestomatioPipe {
59
59
  this.axios = axios_1.default.create({
60
60
  baseURL: `${this.url.trim()}`,
61
61
  timeout: constants_js_1.AXIOS_TIMEOUT,
62
- proxy: proxy ? {
63
- host: proxy.hostname,
64
- port: parseInt(proxy.port, 10),
65
- protocol: proxy.protocol,
66
- } : false,
62
+ proxy: proxy
63
+ ? {
64
+ host: proxy.hostname,
65
+ port: parseInt(proxy.port, 10),
66
+ protocol: proxy.protocol,
67
+ }
68
+ : false,
67
69
  });
68
70
  // Pass the axios instance to the retry function
69
71
  (0, axios_retry_1.default)(this.axios, {
@@ -97,6 +99,7 @@ class TestomatioPipe {
97
99
  this.runId = params.runId || process.env.runId;
98
100
  this.createNewTests = params.createNewTests ?? !!process.env.TESTOMATIO_CREATE;
99
101
  this.hasUnmatchedTests = false;
102
+ this.requestFailures = 0;
100
103
  if (!(0, utils_js_1.isValidUrl)(this.url.trim())) {
101
104
  this.isEnabled = false;
102
105
  console.error(constants_js_1.APP_PREFIX, picocolors_1.default.red(`Error creating report on Testomat.io, report url '${this.url}' is invalid`));
@@ -141,10 +144,9 @@ class TestomatioPipe {
141
144
  */
142
145
  async createRun(params = {}) {
143
146
  this.batch.isEnabled = params.isBatchEnabled ?? this.batch.isEnabled;
144
- debug('Creating run...');
145
147
  if (!this.isEnabled)
146
148
  return;
147
- if (this.batch.isEnabled)
149
+ if (this.batch.isEnabled && this.isEnabled)
148
150
  this.batch.intervalFunction = setInterval(this.#batchUpload, this.batch.intervalTime);
149
151
  let buildUrl = process.env.BUILD_URL || process.env.CI_JOB_URL || process.env.CIRCLE_BUILD_URL;
150
152
  // GitHub Actions Url
@@ -177,12 +179,14 @@ class TestomatioPipe {
177
179
  }).filter(([, value]) => !!value));
178
180
  debug(' >>>>>> Run params', JSON.stringify(runParams, null, 2));
179
181
  if (this.runId) {
182
+ this.store.runId = this.runId;
180
183
  debug(`Run with id ${this.runId} already created, updating...`);
181
184
  const resp = await this.axios.put(`/api/reporter/${this.runId}`, runParams);
182
185
  if (resp.data.artifacts)
183
186
  (0, pipe_utils_js_1.setS3Credentials)(resp.data.artifacts);
184
187
  return;
185
188
  }
189
+ debug('Creating run...');
186
190
  try {
187
191
  const resp = await this.axios.post(`/api/reporter`, runParams, {
188
192
  maxContentLength: Infinity,
@@ -201,37 +205,39 @@ class TestomatioPipe {
201
205
  debug('Run created', this.runId);
202
206
  }
203
207
  catch (err) {
204
- console.error(constants_js_1.APP_PREFIX, 'Error creating Testomat.io report, please check if your API key is valid. Skipping report | ', err?.response?.statusText || err?.status || err.message);
208
+ const errorText = err.response?.data?.message || err.message;
209
+ console.log(errorText || err);
210
+ if (!this.apiKey)
211
+ console.error('Testomat.io API key is not set');
212
+ if (!this.apiKey?.startsWith('tstmt'))
213
+ console.error('Testomat.io API key is invalid');
214
+ console.error(constants_js_1.APP_PREFIX, 'Error creating Testomat.io report (see details above), please check if your API key is valid. Skipping report');
205
215
  printCreateIssue(err);
206
216
  }
207
217
  debug('"createRun" function finished');
208
218
  }
209
219
  /**
210
220
  * Decides whether to skip test reporting in case of too many request failures
211
- * @param {TestData} testData
212
221
  * @returns {boolean}
213
222
  */
214
- #cancelTestReportingInCaseOfTooManyReqFailures(testData) {
215
- if (this.reportingCanceledDueToReqFailures)
216
- return true;
217
- const retriesCountWithinTime = this.retriesTimestamps.filter(timestamp => Date.now() - timestamp < constants_js_1.REPORTER_REQUEST_RETRIES.withinTimeSeconds * 1000).length;
218
- debug(`${retriesCountWithinTime} failed requests within ${constants_js_1.REPORTER_REQUEST_RETRIES.withinTimeSeconds}s`);
219
- if (retriesCountWithinTime > constants_js_1.REPORTER_REQUEST_RETRIES.maxTotalRetries) {
220
- const errorMessage = picocolors_1.default.yellow(`${retriesCountWithinTime} requests were failed within ${constants_js_1.REPORTER_REQUEST_RETRIES.withinTimeSeconds}s,\
221
- reporting for test "${testData.title}" to Testomat is skipped`);
222
- console.warn(`${constants_js_1.APP_PREFIX} ${errorMessage}`);
223
+ #cancelTestReportingInCaseOfTooManyReqFailures() {
224
+ if (!process.env.TESTOMATIO_MAX_REQUEST_FAILURES)
225
+ return;
226
+ const cancelReporting = this.requestFailures >= parseInt(process.env.TESTOMATIO_MAX_REQUEST_FAILURES, 10);
227
+ if (cancelReporting) {
223
228
  this.reportingCanceledDueToReqFailures = true;
224
- this.notReportedTestsCount++;
225
- return true;
229
+ let errorMessage = `⚠️ ${process.env.TESTOMATIO_MAX_REQUEST_FAILURES}`;
230
+ errorMessage += ' requests were failed, reporting to Testomat aborted.';
231
+ console.warn(`${constants_js_1.APP_PREFIX} ${picocolors_1.default.yellow(errorMessage)}`);
226
232
  }
227
- return false;
233
+ return cancelReporting;
228
234
  }
229
235
  #uploadSingleTest = async (data) => {
230
236
  if (!this.isEnabled)
231
237
  return;
232
238
  if (!this.runId)
233
239
  return;
234
- if (this.#cancelTestReportingInCaseOfTooManyReqFailures(data))
240
+ if (this.#cancelTestReportingInCaseOfTooManyReqFailures())
235
241
  return;
236
242
  data.api_key = this.apiKey;
237
243
  data.create = this.createNewTests;
@@ -240,9 +246,9 @@ class TestomatioPipe {
240
246
  }
241
247
  const json = json_cycle_1.default.stringify(data);
242
248
  debug('Adding test', json);
243
- return this.axios
244
- .post(`/api/reporter/${this.runId}/testrun`, json, axiosAddTestrunRequestConfig)
245
- .catch(err => {
249
+ return this.axios.post(`/api/reporter/${this.runId}/testrun`, json, axiosAddTestrunRequestConfig).catch(err => {
250
+ this.requestFailures++;
251
+ this.notReportedTestsCount++;
246
252
  if (err.response) {
247
253
  if (err.response.status >= 400) {
248
254
  const responseData = err.response.data || { message: '' };
@@ -266,6 +272,10 @@ class TestomatioPipe {
266
272
  #batchUpload = async () => {
267
273
  if (!this.batch.isEnabled)
268
274
  return;
275
+ if (!this.batch.tests.length)
276
+ return;
277
+ if (this.#cancelTestReportingInCaseOfTooManyReqFailures())
278
+ return;
269
279
  // prevent infinite loop
270
280
  if (this.batch.numberOfTimesCalledWithoutTests > 10) {
271
281
  debug('📨 Batch upload: no tests to send for 10 times, stopping batch');
@@ -284,6 +294,8 @@ class TestomatioPipe {
284
294
  return this.axios
285
295
  .post(`/api/reporter/${this.runId}/testrun`, { api_key: this.apiKey, tests: testsToSend, batch_index: this.batch.batchIndex }, axiosAddTestrunRequestConfig)
286
296
  .catch(err => {
297
+ this.requestFailures++;
298
+ this.notReportedTestsCount += testsToSend.length;
287
299
  if (err.response) {
288
300
  if (err.response.status >= 400) {
289
301
  const responseData = err.response.data || { message: '' };
@@ -323,15 +335,21 @@ class TestomatioPipe {
323
335
  this.#batchUpload();
324
336
  }
325
337
  /**
326
- * @param {import('../../types').RunData} params
338
+ * @param {import('../../types/types.js').RunData} params
327
339
  * @returns
328
340
  */
329
341
  async finishRun(params) {
330
342
  if (!this.isEnabled)
331
343
  return;
332
- if (this.batch.intervalFunction)
333
- clearInterval(this.batch.intervalFunction);
334
344
  await this.#batchUpload();
345
+ if (this.batch.intervalFunction) {
346
+ clearInterval(this.batch.intervalFunction);
347
+ // this code is required in case test is added after run is finished
348
+ // (e.g. if test has artifacts, add test function will be invoked only after artifacts are uploaded)
349
+ // batch stops working after run is finished; thus, disable it to use single test uploading
350
+ this.batch.intervalFunction = null;
351
+ this.batch.isEnabled = false;
352
+ }
335
353
  debug('Finishing run...');
336
354
  if (this.reportingCanceledDueToReqFailures) {
337
355
  const errorMessage = picocolors_1.default.red(`⚠️ Due to request failures, ${this.notReportedTestsCount} test(s) were not reported to Testomat.io`);
@@ -351,7 +369,9 @@ class TestomatioPipe {
351
369
  if (this.runId && !this.proceed) {
352
370
  await this.axios.put(`/api/reporter/${this.runId}`, {
353
371
  api_key: this.apiKey,
372
+ duration: params.duration,
354
373
  status_event,
374
+ detach: params.detach,
355
375
  tests: params.tests,
356
376
  });
357
377
  if (this.runUrl) {
@@ -0,0 +1,34 @@
1
+ declare namespace _default {
2
+ export { saveArtifact as artifact };
3
+ export { logMessage as log };
4
+ export { addStep as step };
5
+ export { setKeyValue as keyValue };
6
+ }
7
+ export default _default;
8
+ /**
9
+ * Stores path to file as artifact and uploads it to the S3 storage
10
+ * @param {string | {path: string, type: string, name: string}} data - path to file or object with path, type and name
11
+ */
12
+ declare function saveArtifact(data: string | {
13
+ path: string;
14
+ type: string;
15
+ name: string;
16
+ }, context?: any): void;
17
+ /**
18
+ * Attach log message(s) to the test report
19
+ * @param string
20
+ */
21
+ declare function logMessage(...args: any[]): void;
22
+ /**
23
+ * Similar to "log" function but marks message in report as a step
24
+ * @param {string} message
25
+ */
26
+ declare function addStep(message: string): void;
27
+ /**
28
+ * Add key-value pair(s) to the test report
29
+ * @param {{[key: string]: string} | string} keyValue object { key: value } (multiple props allowed) or key (string)
30
+ * @param {string?} value
31
+ */
32
+ declare function setKeyValue(keyValue: {
33
+ [key: string]: string;
34
+ } | string, value?: string | null): void;
@@ -1,37 +1,47 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const index_js_1 = require("./services/index.js");
4
- const playwright_js_1 = require("./adapter/playwright.js");
5
- if (process.env.PLAYWRIGHT_TEST_BASE_URL)
6
- (0, playwright_js_1.initPlaywrightForStorage)();
7
4
  /**
8
5
  * Stores path to file as artifact and uploads it to the S3 storage
9
6
  * @param {string | {path: string, type: string, name: string}} data - path to file or object with path, type and name
10
7
  */
11
8
  function saveArtifact(data, context = null) {
9
+ if (process.env.IS_PLAYWRIGHT)
10
+ throw new Error(`This function is not available in Playwright framework.
11
+ /Playwright supports artifacts out of the box`);
12
12
  if (!data)
13
13
  return;
14
14
  index_js_1.services.artifacts.put(data, context);
15
15
  }
16
16
  /**
17
17
  * Attach log message(s) to the test report
18
- * @param {...any} args
18
+ * @param string
19
19
  */
20
20
  function logMessage(...args) {
21
+ if (process.env.IS_PLAYWRIGHT)
22
+ throw new Error('This function is not available in Playwright framework');
21
23
  index_js_1.services.logger._templateLiteralLog(...args);
22
24
  }
23
25
  /**
24
26
  * Similar to "log" function but marks message in report as a step
25
- * @param {*} message
27
+ * @param {string} message
26
28
  */
27
29
  function addStep(message) {
30
+ if (process.env.IS_PLAYWRIGHT)
31
+ throw new Error('This function is not available in Playwright framework. Use playwright steps');
28
32
  index_js_1.services.logger.step(message);
29
33
  }
30
34
  /**
31
35
  * Add key-value pair(s) to the test report
32
- * @param {*} keyValue
36
+ * @param {{[key: string]: string} | string} keyValue object { key: value } (multiple props allowed) or key (string)
37
+ * @param {string?} value
33
38
  */
34
- function setKeyValue(keyValue) {
39
+ function setKeyValue(keyValue, value = null) {
40
+ if (process.env.IS_PLAYWRIGHT)
41
+ throw new Error('This function is not available in Playwright framework. Use test tag instead.');
42
+ if (typeof keyValue === 'string') {
43
+ keyValue = { [keyValue]: value };
44
+ }
35
45
  index_js_1.services.keyValues.put(keyValue);
36
46
  }
37
47
  module.exports = {