@testomatio/reporter 2.0.1-beta.4 → 2.0.1-beta.5-timestamp

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 (148) hide show
  1. package/lib/adapter/codecept.js +335 -293
  2. package/lib/adapter/cucumber/current.js +203 -195
  3. package/lib/adapter/cucumber/legacy.js +155 -130
  4. package/lib/adapter/cucumber.js +16 -5
  5. package/lib/adapter/cypress-plugin/index.js +105 -91
  6. package/lib/adapter/jasmine.js +53 -54
  7. package/lib/adapter/jest.js +99 -97
  8. package/lib/adapter/mocha.js +141 -112
  9. package/lib/adapter/playwright.js +231 -199
  10. package/lib/adapter/vitest.js +149 -150
  11. package/lib/adapter/webdriver.js +121 -144
  12. package/lib/bin/cli.js +211 -229
  13. package/lib/bin/reportXml.js +52 -51
  14. package/lib/bin/startTest.js +95 -83
  15. package/lib/bin/uploadArtifacts.js +61 -56
  16. package/lib/client.js +465 -424
  17. package/lib/config.js +23 -18
  18. package/lib/constants.js +44 -50
  19. package/lib/data-storage.js +188 -216
  20. package/lib/junit-adapter/adapter.js +20 -17
  21. package/lib/junit-adapter/csharp.js +14 -28
  22. package/lib/junit-adapter/index.js +25 -27
  23. package/lib/junit-adapter/java.js +53 -41
  24. package/lib/junit-adapter/javascript.js +27 -30
  25. package/lib/junit-adapter/python.js +37 -38
  26. package/lib/junit-adapter/ruby.js +8 -11
  27. package/lib/output.js +52 -44
  28. package/lib/pipe/bitbucket.js +230 -223
  29. package/lib/pipe/csv.js +126 -113
  30. package/lib/pipe/debug.js +99 -118
  31. package/lib/pipe/github.js +213 -218
  32. package/lib/pipe/gitlab.js +206 -183
  33. package/lib/pipe/html.js +321 -258
  34. package/lib/pipe/index.js +66 -94
  35. package/lib/pipe/testomatio.js +474 -429
  36. package/lib/reporter-functions.js +26 -28
  37. package/lib/reporter.js +29 -34
  38. package/lib/services/artifacts.js +51 -55
  39. package/lib/services/index.js +12 -14
  40. package/lib/services/key-values.js +53 -56
  41. package/lib/services/logger.js +245 -226
  42. package/lib/template/testomatio.hbs +1366 -1026
  43. package/lib/uploader.js +364 -295
  44. package/lib/utils/pipe_utils.js +85 -89
  45. package/lib/utils/utils.js +307 -398
  46. package/lib/xmlReader.js +532 -525
  47. package/package.json +21 -64
  48. package/lib/adapter/codecept.d.ts +0 -2
  49. package/lib/adapter/cucumber/current.d.ts +0 -14
  50. package/lib/adapter/cucumber/legacy.d.ts +0 -0
  51. package/lib/adapter/cucumber.d.ts +0 -2
  52. package/lib/adapter/cypress-plugin/index.d.ts +0 -2
  53. package/lib/adapter/jasmine.d.ts +0 -11
  54. package/lib/adapter/jest.d.ts +0 -13
  55. package/lib/adapter/mocha.d.ts +0 -2
  56. package/lib/adapter/nightwatch.d.ts +0 -4
  57. package/lib/adapter/nightwatch.js +0 -80
  58. package/lib/adapter/playwright.d.ts +0 -14
  59. package/lib/adapter/vitest.d.ts +0 -35
  60. package/lib/adapter/webdriver.d.ts +0 -24
  61. package/lib/bin/cli.d.ts +0 -2
  62. package/lib/bin/reportXml.d.ts +0 -2
  63. package/lib/bin/startTest.d.ts +0 -2
  64. package/lib/bin/uploadArtifacts.d.ts +0 -2
  65. package/lib/client.d.ts +0 -76
  66. package/lib/config.d.ts +0 -1
  67. package/lib/constants.d.ts +0 -25
  68. package/lib/data-storage.d.ts +0 -34
  69. package/lib/junit-adapter/adapter.d.ts +0 -9
  70. package/lib/junit-adapter/csharp.d.ts +0 -5
  71. package/lib/junit-adapter/index.d.ts +0 -3
  72. package/lib/junit-adapter/java.d.ts +0 -5
  73. package/lib/junit-adapter/javascript.d.ts +0 -4
  74. package/lib/junit-adapter/python.d.ts +0 -5
  75. package/lib/junit-adapter/ruby.d.ts +0 -4
  76. package/lib/output.d.ts +0 -11
  77. package/lib/package.json +0 -3
  78. package/lib/pipe/bitbucket.d.ts +0 -25
  79. package/lib/pipe/csv.d.ts +0 -47
  80. package/lib/pipe/debug.d.ts +0 -29
  81. package/lib/pipe/github.d.ts +0 -30
  82. package/lib/pipe/gitlab.d.ts +0 -25
  83. package/lib/pipe/html.d.ts +0 -35
  84. package/lib/pipe/index.d.ts +0 -1
  85. package/lib/pipe/testomatio.d.ts +0 -71
  86. package/lib/replay.d.ts +0 -31
  87. package/lib/replay.js +0 -237
  88. package/lib/reporter-functions.d.ts +0 -34
  89. package/lib/reporter.d.ts +0 -232
  90. package/lib/services/artifacts.d.ts +0 -33
  91. package/lib/services/index.d.ts +0 -9
  92. package/lib/services/key-values.d.ts +0 -27
  93. package/lib/services/logger.d.ts +0 -64
  94. package/lib/uploader.d.ts +0 -60
  95. package/lib/utils/pipe_utils.d.ts +0 -41
  96. package/lib/utils/utils.d.ts +0 -54
  97. package/lib/xmlReader.d.ts +0 -92
  98. package/src/adapter/codecept.js +0 -373
  99. package/src/adapter/cucumber/current.js +0 -228
  100. package/src/adapter/cucumber/legacy.js +0 -158
  101. package/src/adapter/cucumber.js +0 -4
  102. package/src/adapter/cypress-plugin/index.js +0 -110
  103. package/src/adapter/jasmine.js +0 -60
  104. package/src/adapter/jest.js +0 -107
  105. package/src/adapter/mocha.cjs +0 -2
  106. package/src/adapter/mocha.js +0 -156
  107. package/src/adapter/nightwatch.js +0 -88
  108. package/src/adapter/playwright.js +0 -254
  109. package/src/adapter/vitest.js +0 -183
  110. package/src/adapter/webdriver.js +0 -142
  111. package/src/bin/cli.js +0 -348
  112. package/src/bin/reportXml.js +0 -77
  113. package/src/bin/startTest.js +0 -124
  114. package/src/bin/uploadArtifacts.js +0 -91
  115. package/src/client.js +0 -508
  116. package/src/config.js +0 -30
  117. package/src/constants.js +0 -53
  118. package/src/data-storage.js +0 -204
  119. package/src/junit-adapter/adapter.js +0 -23
  120. package/src/junit-adapter/csharp.js +0 -28
  121. package/src/junit-adapter/index.js +0 -28
  122. package/src/junit-adapter/java.js +0 -58
  123. package/src/junit-adapter/javascript.js +0 -31
  124. package/src/junit-adapter/python.js +0 -42
  125. package/src/junit-adapter/ruby.js +0 -10
  126. package/src/output.js +0 -57
  127. package/src/pipe/bitbucket.js +0 -252
  128. package/src/pipe/csv.js +0 -140
  129. package/src/pipe/debug.js +0 -119
  130. package/src/pipe/github.js +0 -232
  131. package/src/pipe/gitlab.js +0 -247
  132. package/src/pipe/html.js +0 -373
  133. package/src/pipe/index.js +0 -71
  134. package/src/pipe/testomatio.js +0 -504
  135. package/src/replay.js +0 -245
  136. package/src/reporter-functions.js +0 -55
  137. package/src/reporter.cjs_decprecated +0 -21
  138. package/src/reporter.js +0 -33
  139. package/src/services/artifacts.js +0 -59
  140. package/src/services/index.js +0 -13
  141. package/src/services/key-values.js +0 -59
  142. package/src/services/logger.js +0 -315
  143. package/src/template/emptyData.svg +0 -23
  144. package/src/template/testomatio.hbs +0 -1081
  145. package/src/uploader.js +0 -376
  146. package/src/utils/pipe_utils.js +0 -119
  147. package/src/utils/utils.js +0 -416
  148. package/src/xmlReader.js +0 -614
package/src/client.js DELETED
@@ -1,508 +0,0 @@
1
- import createDebugMessages from 'debug';
2
- import createCallsiteRecord from 'callsite-record';
3
- import { minimatch } from 'minimatch';
4
- import fs from 'fs';
5
- import pc from 'picocolors';
6
- import { randomUUID } from 'crypto';
7
- import { APP_PREFIX, STATUS } from './constants.js';
8
- import { pipesFactory } from './pipe/index.js';
9
- import { glob } from 'glob';
10
- import path, { sep } from 'path';
11
- import { fileURLToPath } from 'node:url';
12
- import { S3Uploader } from './uploader.js';
13
- import { formatStep, storeRunId, validateSuiteId } from './utils/utils.js';
14
- import { filesize as prettyBytes } from 'filesize';
15
-
16
- const debug = createDebugMessages('@testomatio/reporter:client');
17
-
18
- // removed __dirname usage, because:
19
- // 1. replaced with ESM syntax (import.meta.url), but it throws an error on tsc compilation;
20
- // 2. got error "__dirname already defined" in compiles js code (cjs dir)
21
-
22
- let listOfTestFilesToExcludeFromReport = null;
23
-
24
- /**
25
- * @typedef {import('../types/types.js').TestData} TestData
26
- * @typedef {import('../types/types.js').PipeResult} PipeResult
27
- */
28
-
29
- class Client {
30
- /**
31
- * Create a Testomat client instance
32
- * @returns
33
- */
34
- constructor(params = {}) {
35
- this.paramsForPipesFactory = params;
36
- this.pipeStore = {};
37
- this.runId = randomUUID(); // will be replaced by real run id
38
- this.queue = Promise.resolve();
39
-
40
- // @ts-ignore this line will be removed in compiled code, because __dirname is defined in commonjs
41
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
42
- const pathToPackageJSON = path.join(__dirname, '../package.json');
43
- try {
44
- this.version = JSON.parse(fs.readFileSync(pathToPackageJSON).toString()).version;
45
- console.log(APP_PREFIX, `Testomatio Reporter v${this.version}`);
46
- } catch (e) {
47
- // do nothing
48
- }
49
- this.executionList = Promise.resolve();
50
-
51
- this.uploader = new S3Uploader();
52
- }
53
-
54
- /**
55
- * Asynchronously prepares the execution list for running tests through various pipes.
56
- * Each pipe in the client is checked for enablement,
57
- * and if all pipes are disabled, the function returns a resolved Promise.
58
- * Otherwise, it executes the `prepareRun` method for each enabled pipe and collects the results.
59
- * The results are then filtered to remove any undefined values.
60
- * If no valid results are found, the function returns undefined.
61
- * Otherwise, it returns the first non-empty array from the filtered results.
62
- *
63
- * @param {Object} params - The options for preparing the test execution list.
64
- * @param {string} params.pipe - Name of the executed pipe.
65
- * @param {string} params.pipeOptions - Filter option.
66
- * @returns {Promise<any>} - A Promise that resolves to an
67
- * array containing the prepared execution list,
68
- * or resolves to undefined if no valid results are found or if all pipes are disabled.
69
- */
70
- async prepareRun(params) {
71
- this.pipes = await pipesFactory(params || this.paramsForPipesFactory || {}, this.pipeStore);
72
- const { pipe, pipeOptions } = params;
73
- // all pipes disabled, skipping
74
- if (!this.pipes.some(p => p.isEnabled)) {
75
- return Promise.resolve();
76
- }
77
-
78
- try {
79
- const filterPipe = this.pipes.find(p => p.constructor.name.toLowerCase() === `${pipe.toLowerCase()}pipe`);
80
-
81
- if (!filterPipe?.isEnabled) {
82
- // TODO:for the future for the another pipes
83
- console.warn(
84
- APP_PREFIX,
85
- `At the moment processing is available only for the "testomatio" key. Example: "testomatio:tag-name=xxx"`,
86
- );
87
- return;
88
- }
89
-
90
- const results = await Promise.all(
91
- this.pipes.map(async p => ({ pipe: p.toString(), result: await p.prepareRun(pipeOptions) })),
92
- );
93
-
94
- const result = results.filter(p => p.pipe.includes('Testomatio'))[0]?.result;
95
-
96
- if (!result || result.length === 0) {
97
- return;
98
- }
99
-
100
- debug('Execution tests list', result);
101
-
102
- return result;
103
- } catch (err) {
104
- console.error(APP_PREFIX, err);
105
- }
106
- }
107
-
108
- /**
109
- * Used to create a new Test run
110
- *
111
- * @returns {Promise<any>} - resolves to Run id which should be used to update / add test
112
- */
113
- async createRun(params) {
114
- if (!this.pipes || !this.pipes.length)
115
- this.pipes = await pipesFactory(params || this.paramsForPipesFactory || {}, this.pipeStore);
116
- debug('Creating run...');
117
- // all pipes disabled, skipping
118
- if (!this.pipes?.filter(p => p.isEnabled).length) return Promise.resolve();
119
-
120
- this.queue = this.queue
121
- .then(() => Promise.all(this.pipes.map(p => p.createRun())))
122
- .catch(err => console.log(APP_PREFIX, err))
123
- .then(() => {
124
- const runId = this.pipeStore?.runId;
125
- if (runId) this.runId = runId;
126
- storeRunId(this.runId);
127
- })
128
- .then(() => this.uploader.checkEnabled())
129
- .then(() => undefined); // fixes return type
130
- // debug('Run', this.queue);
131
- return this.queue;
132
- }
133
-
134
- /**
135
- * Updates test status and its data
136
- *
137
- * @param {string|undefined} status
138
- * @param {TestData} [testData]
139
- * @returns {Promise<PipeResult[]>}
140
- */
141
- async addTestRun(status, testData) {
142
- // all pipes disabled, skipping
143
- if (!this.pipes?.filter(p => p.isEnabled).length) return [];
144
-
145
- if (isTestShouldBeExculedFromReport(testData)) return [];
146
-
147
- if (status === STATUS.SKIPPED && process.env.TESTOMATIO_EXCLUDE_SKIPPED) {
148
- debug('Skipping test from report', testData?.title);
149
- return []; // do not log skipped tests
150
- }
151
-
152
- if (!testData)
153
- testData = {
154
- title: 'Unknown test',
155
- suite_title: 'Unknown suite',
156
- };
157
-
158
- /**
159
- * @type {TestData}
160
- */
161
- const {
162
- rid,
163
- error = null,
164
- time = 0,
165
- example = null,
166
- files = [],
167
- filesBuffers = [],
168
- steps,
169
- code = null,
170
- title,
171
- file,
172
- suite_title,
173
- suite_id,
174
- test_id,
175
- manuallyAttachedArtifacts,
176
- } = testData;
177
- let { message = '', meta = {} } = testData;
178
-
179
- // stringify meta values and limit keys and values length to 255
180
- meta = Object.entries(meta)
181
- .filter(([, value]) => value !== null && value !== undefined)
182
- .map(([key, value]) => {
183
- try {
184
- if (typeof value === 'object') {
185
- value = JSON.stringify(value);
186
- } else if (typeof value !== 'string') {
187
- try {
188
- value = value.toString();
189
- } catch (err) {
190
- console.warn(APP_PREFIX, `Can't convert meta value to string`, err);
191
- }
192
- }
193
-
194
- if (value?.length > 255) {
195
- value = value.substring(0, 255);
196
- debug(APP_PREFIX, `Meta info value "${value}" is too long, trimmed to 255 characters`);
197
- }
198
-
199
- if (key?.length > 255) {
200
- const newKey = key.substring(0, 255);
201
- debug(APP_PREFIX, `Meta info key "${key}" is too long, trimmed to 255 characters`);
202
- return [newKey, value];
203
- }
204
-
205
- return [key, value];
206
- } catch (err) {
207
- debug(APP_PREFIX, `Error while processing meta info key ${key}`, err);
208
- return [null, null];
209
- }
210
- })
211
- .reduce((acc, [key, value]) => {
212
- if (key) acc[key] = value;
213
- return acc;
214
- }, {});
215
-
216
- let errorFormatted = '';
217
- if (error) {
218
- errorFormatted += this.formatError(error) || '';
219
- message = error?.message;
220
- }
221
-
222
- // Attach logs
223
- const fullLogs = this.formatLogs({ error: errorFormatted, steps, logs: testData.logs });
224
-
225
- // add artifacts
226
- if (manuallyAttachedArtifacts?.length) files.push(...manuallyAttachedArtifacts);
227
-
228
- const uploadedFiles = [];
229
-
230
- for (let f of files) {
231
- if (!f) continue; // f === null
232
- if (typeof f === 'object') {
233
- if (!f.path) continue;
234
-
235
- f = f.path;
236
- }
237
-
238
- uploadedFiles.push(this.uploader.uploadFileByPath(f, [this.runId, rid, path.basename(f)]));
239
- }
240
-
241
- for (const [idx, buffer] of filesBuffers.entries()) {
242
- const fileName = `${idx + 1}-${title.replace(/\s+/g, '-')}`;
243
- uploadedFiles.push(this.uploader.uploadFileAsBuffer(buffer, [this.runId, rid, fileName]));
244
- }
245
-
246
- const artifacts = (await Promise.all(uploadedFiles)).filter(n => !!n);
247
-
248
- const workspaceDir = process.env.TESTOMATIO_WORKDIR || process.cwd();
249
- const relativeFile = file ? path.relative(workspaceDir, file) : file;
250
- const rootSuiteId = validateSuiteId(process.env.TESTOMATIO_SUITE);
251
-
252
- const data = {
253
- rid,
254
- files,
255
- steps,
256
- status,
257
- stack: fullLogs,
258
- example,
259
- file: relativeFile,
260
- code,
261
- title,
262
- suite_title,
263
- suite_id,
264
- test_id,
265
- message,
266
- run_time: typeof time === 'number' ? time : parseFloat(time),
267
- artifacts,
268
- meta,
269
- ...(rootSuiteId && { root_suite_id: rootSuiteId }),
270
- };
271
-
272
- // debug('Adding test run...', data);
273
-
274
- // @ts-ignore
275
- this.queue = this.queue.then(() =>
276
- Promise.all(
277
- this.pipes.map(async pipe => {
278
- try {
279
- const result = await pipe.addTest(data);
280
- return { pipe: pipe.toString(), result };
281
- } catch (err) {
282
- console.log(APP_PREFIX, pipe.toString(), err);
283
- }
284
- }),
285
- ),
286
- );
287
-
288
- // @ts-ignore
289
- return this.queue;
290
- }
291
-
292
- /**
293
- *
294
- * Updates the status of the current test run and finishes the run.
295
- * @param {'passed' | 'failed' | 'skipped' | 'finished'} status - The status of the current test run.
296
- * Must be one of "passed", "failed", or "finished"
297
- * @param {boolean} [isParallel] - Whether the current test run was executed in parallel with other tests.
298
- * @returns {Promise<any>} - A Promise that resolves when finishes the run.
299
- */
300
- updateRunStatus(status, isParallel = false) {
301
- debug('Updating run status...');
302
- // all pipes disabled, skipping
303
- if (!this.pipes?.filter(p => p.isEnabled).length) return Promise.resolve();
304
-
305
- const runParams = { status, parallel: isParallel };
306
-
307
- this.queue = this.queue
308
- .then(() => Promise.all(this.pipes.map(p => p.finishRun(runParams))))
309
- .then(() => {
310
- if (!this.uploader.isEnabled) return;
311
-
312
- const filesizeStrMaxLength = 7;
313
-
314
- if (this.uploader.successfulUploads.length) {
315
- debug('\n', APP_PREFIX, `🗄️ ${this.uploader.successfulUploads.length} artifacts uploaded to S3 bucket`);
316
- const uploadedArtifacts = this.uploader.successfulUploads.map(file => ({
317
- relativePath: file.path.replace(process.cwd(), ''),
318
- link: file.link,
319
- sizePretty: prettyBytes(file.size, { round: 0 }).toString(),
320
- }));
321
-
322
- uploadedArtifacts.forEach(upload => {
323
- debug(
324
- `🟢Uploaded artifact`,
325
- `${upload.relativePath},`,
326
- 'size:',
327
- `${upload.sizePretty},`,
328
- 'link:',
329
- `${upload.link}`,
330
- );
331
- });
332
- }
333
-
334
- if (this.uploader.failedUploads.length) {
335
- console.log(
336
- APP_PREFIX,
337
- `🗄️ ${this.uploader.failedUploads.length} artifacts 🔴${pc.bold('failed')} to upload`,
338
- );
339
- const failedUploads = this.uploader.failedUploads.map(file => ({
340
- relativePath: file.path.replace(process.cwd(), ''),
341
- sizePretty: prettyBytes(file.size, { round: 0 }).toString(),
342
- }));
343
-
344
- const pathPadding = Math.max(...failedUploads.map(upload => upload.relativePath.length)) + 1;
345
-
346
- failedUploads.forEach(upload => {
347
- console.log(
348
- ` ${pc.gray('|')} 🔴 ${upload.relativePath.padEnd(pathPadding)} ${pc.gray(
349
- `| ${upload.sizePretty.padStart(filesizeStrMaxLength)} |`,
350
- )}`,
351
- );
352
- });
353
- }
354
-
355
- if (this.uploader.skippedUploads.length) {
356
- console.log(
357
- '\n',
358
- APP_PREFIX,
359
- `🗄️ ${pc.bold(this.uploader.skippedUploads.length)} artifacts uploading 🟡${pc.bold('skipped')}`,
360
- );
361
- const skippedUploads = this.uploader.skippedUploads.map(file => ({
362
- relativePath: file.path.replace(process.cwd(), ''),
363
- sizePretty: file.size === null ? 'unknown' : prettyBytes(file.size, { round: 0 }).toString(),
364
- }));
365
- const pathPadding = Math.max(...skippedUploads.map(upload => upload.relativePath.length)) + 1;
366
- skippedUploads.forEach(upload => {
367
- console.log(
368
- ` ${pc.gray('|')} 🟡 ${upload.relativePath.padEnd(pathPadding)} ${pc.gray(
369
- `| ${upload.sizePretty.padStart(filesizeStrMaxLength)} |`,
370
- )}`,
371
- );
372
- });
373
- }
374
-
375
- if (this.uploader.skippedUploads.length || this.uploader.failedUploads.length) {
376
- const command = `TESTOMATIO=<your_api_key> TESTOMATIO_RUN=${
377
- this.runId
378
- } npx @testomatio/reporter upload-artifacts`;
379
- const numberOfNotUploadedArtifacts = this.uploader.skippedUploads.length + this.uploader.failedUploads.length;
380
- console.log(
381
- APP_PREFIX,
382
- `${numberOfNotUploadedArtifacts} artifacts were not uploaded.
383
- Run "${pc.magenta(command)}" with valid S3 credentials to upload skipped & failed artifacts`,
384
- );
385
- }
386
- })
387
- .catch(err => console.log(APP_PREFIX, err));
388
-
389
- return this.queue;
390
- }
391
-
392
- /**
393
- * Returns the formatted stack including the stack trace, steps, and logs.
394
- * @returns {string}
395
- */
396
- formatLogs({ error, steps, logs }) {
397
- error = error?.trim();
398
- logs = logs?.trim();
399
-
400
- if (Array.isArray(steps)) {
401
- steps = steps
402
- .map(step => formatStep(step))
403
- .flat()
404
- .join('\n');
405
- }
406
-
407
- let testLogs = '';
408
- if (steps) testLogs += `${pc.bold(pc.blue('################[ Steps ]################'))}\n${steps}\n\n`;
409
- if (logs) testLogs += `${pc.bold(pc.gray('################[ Logs ]################'))}\n${logs}\n\n`;
410
- if (error) testLogs += `${pc.bold(pc.red('################[ Failure ]################'))}\n${error}`;
411
- return testLogs;
412
- }
413
-
414
- formatError(error, message) {
415
- if (!message) message = error.message;
416
- if (error.inspect) message = error.inspect() || '';
417
-
418
- let stack = '';
419
- if (error.name) stack += `${pc.red(error.name)}`;
420
- if (error.operator) stack += ` (${pc.red(error.operator)})`;
421
- // add new line if something was added to stack
422
- if (stack) stack += ': ';
423
-
424
- stack += `${message}\n`;
425
-
426
- if (error.diff) {
427
- // diff for vitest
428
- stack += error.diff;
429
- stack += '\n\n';
430
- } else if (error.actual && error.expected && error.actual !== error.expected) {
431
- // diffs for mocha, cypress, codeceptjs style
432
- stack += `\n\n${pc.bold(pc.green('+ expected'))} ${pc.bold(pc.red('- actual'))}`;
433
- stack += `\n${pc.green(`+ ${error.expected.toString().split('\n').join('\n+ ')}`)}`;
434
- stack += `\n${pc.red(`- ${error.actual.toString().split('\n').join('\n- ')}`)}`;
435
- stack += '\n\n';
436
- }
437
-
438
- const customFilter = process.env.TESTOMATIO_STACK_IGNORE;
439
-
440
- try {
441
- let hasFrame = false;
442
- const record = createCallsiteRecord({
443
- forError: error,
444
- isCallsiteFrame: frame => {
445
- if (customFilter && minimatch(frame.fileName, customFilter)) return false;
446
- if (hasFrame) return false;
447
- if (isNotInternalFrame(frame)) hasFrame = true;
448
- return hasFrame;
449
- },
450
- });
451
- // @ts-ignore
452
- if (record && !record.filename.startsWith('http')) {
453
- stack += record.renderSync({ stackFilter: isNotInternalFrame });
454
- }
455
- return stack;
456
- } catch (e) {
457
- console.log(e);
458
- }
459
- }
460
- }
461
-
462
- function isNotInternalFrame(frame) {
463
- return (
464
- frame.getFileName() &&
465
- frame.getFileName().includes(sep) &&
466
- !frame.getFileName().includes('node_modules') &&
467
- !frame.getFileName().includes('internal')
468
- );
469
- }
470
-
471
- /**
472
- *
473
- * @param {TestData} testData
474
- * @returns boolean
475
- */
476
- function isTestShouldBeExculedFromReport(testData) {
477
- // const fileName = path.basename(test.location?.file || '');
478
- const globExcludeFilesPattern = process.env.TESTOMATIO_EXCLUDE_FILES_FROM_REPORT_GLOB_PATTERN;
479
- if (!globExcludeFilesPattern) return false;
480
-
481
- if (!testData.file) {
482
- debug('No "file" property found for test ', testData.title);
483
- return false;
484
- }
485
-
486
- const excludeParretnsList = globExcludeFilesPattern.split(';');
487
-
488
- // as scanning files is time consuming operation, just save the result in variable to avoid multiple scans
489
- if (!listOfTestFilesToExcludeFromReport) {
490
- // list of files with relative paths
491
- listOfTestFilesToExcludeFromReport = glob.sync(excludeParretnsList, { ignore: '**/node_modules/**' });
492
- debug('Tests from next files will not be reported:', listOfTestFilesToExcludeFromReport);
493
- }
494
-
495
- const testFileRelativePath = path.relative(process.cwd(), testData.file);
496
-
497
- // no files found matching the exclusion pattern
498
- if (!listOfTestFilesToExcludeFromReport.length) return false;
499
-
500
- if (listOfTestFilesToExcludeFromReport.includes(testFileRelativePath)) {
501
- debug(`Excluding test '${testData.title}' <${testFileRelativePath}> from reporting`);
502
- return true;
503
- }
504
- return false;
505
- }
506
-
507
- export { Client };
508
- export default Client;
package/src/config.js DELETED
@@ -1,30 +0,0 @@
1
- // This file is used to read environment variables from .env file
2
- import createDebugMessages from 'debug';
3
-
4
- const debug = createDebugMessages('@testomatio/reporter:config');
5
-
6
- /* for possibility to use multiple env files (reading different paths)
7
- const envFileVars = dotenv.config({ path: '.env' }).parsed; */
8
-
9
- if (process.env.TESTOMATIO_API_KEY && !process.env.TESTOMATIO) {
10
- process.env.TESTOMATIO = process.env.TESTOMATIO_API_KEY;
11
- }
12
- if (process.env.TESTOMATIO_TOKEN && !process.env.TESTOMATIO) {
13
- process.env.TESTOMATIO = process.env.TESTOMATIO_TOKEN;
14
- }
15
-
16
- if (process.env.TESTOMATIO === 'undefined')
17
- console.error('TESTOMATIO is "undefined". Something went wrong. Contact dev team.');
18
-
19
- // select only TESTOMATIO related variables (only to print them in debug)
20
- const testomatioEnvVars =
21
- Object.keys(process.env)
22
- .filter(key => key.startsWith('TESTOMATIO') || key.startsWith('S3_'))
23
- .reduce((obj, key) => {
24
- obj[key] = process.env[key];
25
- return obj;
26
- }, {}) || {};
27
- debug('TESTOMATIO variables:', testomatioEnvVars);
28
-
29
- // includes variables from .env file and process.env
30
- export const config = process.env;
package/src/constants.js DELETED
@@ -1,53 +0,0 @@
1
- import pc from 'picocolors';
2
- import os from 'os';
3
- import path from 'path';
4
-
5
- const APP_PREFIX = pc.gray('[TESTOMATIO]');
6
- const TESTOMATIO_REQUEST_TIMEOUT = parseInt(process.env.TESTOMATIO_REQUEST_TIMEOUT, 10);
7
- if (TESTOMATIO_REQUEST_TIMEOUT) {
8
- console.log(`${APP_PREFIX} Request timeout is set to ${TESTOMATIO_REQUEST_TIMEOUT / 1000}s`);
9
- }
10
- const AXIOS_TIMEOUT = TESTOMATIO_REQUEST_TIMEOUT || 20 * 1000;
11
-
12
- const TESTOMAT_TMP_STORAGE_DIR = path.join(os.tmpdir(), 'testomatio_tmp');
13
-
14
- const CSV_HEADERS = [
15
- { id: 'suite_title', title: 'Suite_title' },
16
- { id: 'title', title: 'Title' },
17
- { id: 'status', title: 'Status' },
18
- { id: 'message', title: 'Message' },
19
- { id: 'stack', title: 'Stack' },
20
- ];
21
-
22
- const STATUS = {
23
- PASSED: 'passed',
24
- FAILED: 'failed',
25
- SKIPPED: 'skipped',
26
- FINISHED: 'finished',
27
- };
28
- // html pipe var
29
- const HTML_REPORT = {
30
- FOLDER: 'html-report',
31
- REPORT_DEFAULT_NAME: 'testomatio-report.html',
32
- TEMPLATE_NAME: 'testomatio.hbs',
33
- };
34
-
35
- const testomatLogoURL = 'https://avatars.githubusercontent.com/u/59105116?s=36&v=4';
36
-
37
- const REPORTER_REQUEST_RETRIES = {
38
- retryTimeout: 5 * 1000, // sum = 5sec
39
- retriesPerRequest: 2,
40
- maxTotalRetries: Number(process.env.TESTOMATIO_MAX_REQUEST_FAILURES_COUNT) || 10,
41
- withinTimeSeconds: Number(process.env.TESTOMATIO_MAX_REQUEST_RETRIES_WITHIN_TIME_SECONDS) || 60,
42
- };
43
-
44
- export {
45
- APP_PREFIX,
46
- TESTOMAT_TMP_STORAGE_DIR,
47
- CSV_HEADERS,
48
- STATUS,
49
- HTML_REPORT,
50
- AXIOS_TIMEOUT,
51
- testomatLogoURL,
52
- REPORTER_REQUEST_RETRIES,
53
- };