@testomatio/reporter 1.4.5 → 1.5.0-beta-vitest

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.
@@ -129,8 +129,8 @@ function CodeceptReporter(config) {
129
129
  await Promise.all(reportTestPromises);
130
130
 
131
131
  if (upload.isArtifactsEnabled()) {
132
- await uploadAttachments(client, videos, '🎞️ Uploading', 'video');
133
- await uploadAttachments(client, traces, '📁 Uploading', 'trace');
132
+ uploadAttachments(client, videos, '🎞️ Uploading', 'video');
133
+ uploadAttachments(client, traces, '📁 Uploading', 'trace');
134
134
  }
135
135
 
136
136
  const status = failedTests.length === 0 ? STATUS.PASSED : STATUS.FAILED;
@@ -142,6 +142,7 @@ function CodeceptReporter(config) {
142
142
  if (id && failedTests.includes(id)) {
143
143
  failedTests = failedTests.filter(failed => id !== failed);
144
144
  }
145
+ const testId = getTestomatIdFromTestTitle(`${title} ${tags?.join(' ')}`);
145
146
  const testObj = getTestAndMessage(title);
146
147
 
147
148
  const logs = getTestLogs(test);
@@ -151,12 +152,11 @@ function CodeceptReporter(config) {
151
152
 
152
153
  client.addTestRun(STATUS.PASSED, {
153
154
  ...stripExampleFromTitle(title),
154
- rid: id,
155
155
  suite_title: test.parent && test.parent.title,
156
156
  message: testObj.message,
157
157
  time: getDuration(test),
158
158
  steps: global.testomatioDataStore.steps.join('\n') || null,
159
- test_id: getTestomatIdFromTestTitle(`${title} ${tags?.join(' ')}`),
159
+ test_id: testId,
160
160
  logs,
161
161
  manuallyAttachedArtifacts,
162
162
  meta: keyValues,
@@ -179,7 +179,6 @@ function CodeceptReporter(config) {
179
179
  const testId = getTestomatIdFromTestTitle(`${title} ${tags?.join(' ')}`);
180
180
 
181
181
  client.addTestRun(STATUS.FAILED, {
182
- rid: id,
183
182
  ...stripExampleFromTitle(title),
184
183
  suite_title: suite.title,
185
184
  test_id: testId,
@@ -195,6 +194,7 @@ function CodeceptReporter(config) {
195
194
  if (test.err) error = test.err;
196
195
  const { id, tags, title, artifacts } = test;
197
196
  failedTests.push(id || title);
197
+ let testId = getTestomatIdFromTestTitle(`${title} ${tags?.join(' ')}`);
198
198
  const testObj = getTestAndMessage(title);
199
199
 
200
200
  const files = [];
@@ -206,10 +206,10 @@ function CodeceptReporter(config) {
206
206
  const keyValues = services.keyValues.get(test.fullTitle());
207
207
  services.setContext(null);
208
208
 
209
- client.addTestRun(STATUS.FAILED, {
209
+ const reportTestPromise = client
210
+ .addTestRun(STATUS.FAILED, {
210
211
  ...stripExampleFromTitle(title),
211
- rid: id,
212
- test_id: getTestomatIdFromTestTitle(`${title} ${tags?.join(' ')}`),
212
+ test_id: testId,
213
213
  suite_title: test.parent && test.parent.title,
214
214
  error,
215
215
  message: testObj.message,
@@ -219,14 +219,19 @@ function CodeceptReporter(config) {
219
219
  logs,
220
220
  manuallyAttachedArtifacts,
221
221
  meta: keyValues,
222
- });
222
+ })
223
+ .then(pipes => {
224
+ testId = pipes.filter(p => p.pipe.includes('Testomatio'))[0]?.result?.data?.test_id;
223
225
 
224
- debug('artifacts', artifacts);
226
+ debug('artifacts', artifacts);
225
227
 
226
- for (const aid in artifacts) {
227
- if (aid.startsWith('video')) videos.push({ rid: id, title, path: artifacts[aid], type: 'video/webm' });
228
- if (aid.startsWith('trace')) traces.push({ rid: id, title, path: artifacts[aid], type: 'application/zip' });
229
- }
228
+ for (const aid in artifacts) {
229
+ if (aid.startsWith('video')) videos.push({ testId, title, path: artifacts[aid], type: 'video/webm' });
230
+ if (aid.startsWith('trace')) traces.push({ testId, title, path: artifacts[aid], type: 'application/zip' });
231
+ }
232
+ });
233
+
234
+ reportTestPromises.push(reportTestPromise);
230
235
 
231
236
  // output.stop();
232
237
  });
@@ -235,11 +240,11 @@ function CodeceptReporter(config) {
235
240
  const { id, tags, title } = test;
236
241
  if (failedTests.includes(id || title)) return;
237
242
 
243
+ const testId = getTestomatIdFromTestTitle(`${title} ${tags?.join(' ')}`);
238
244
  const testObj = getTestAndMessage(title);
239
245
  client.addTestRun(STATUS.SKIPPED, {
240
- rid: id,
241
246
  ...stripExampleFromTitle(title),
242
- test_id: getTestomatIdFromTestTitle(`${title} ${tags?.join(' ')}`),
247
+ test_id: testId,
243
248
  suite_title: test.parent && test.parent.title,
244
249
  message: testObj.message,
245
250
  time: getDuration(test),
@@ -304,22 +309,21 @@ function CodeceptReporter(config) {
304
309
  }
305
310
 
306
311
  async function uploadAttachments(client, attachments, messagePrefix, attachmentType) {
307
- if (!attachments?.length) return;
308
-
309
- console.log(APP_PREFIX, `Attachments: ${messagePrefix} ${attachments.length} ${attachmentType} ...`);
312
+ if (attachments.length > 0) {
313
+ console.log(APP_PREFIX, `Attachments: ${messagePrefix} ${attachments.length} ${attachmentType}/-s ...`);
310
314
 
311
- const promises = attachments.map(async attachment => {
312
- const { rid, title, path, type } = attachment;
313
- const file = { path, type, title };
314
- return client.addTestRun(undefined, {
315
- ...stripExampleFromTitle(title),
316
- rid,
317
- files: [file],
315
+ const promises = attachments.map(async attachment => {
316
+ const { testId, title, path, type } = attachment;
317
+ const file = { path, type, title };
318
+ return client.addTestRun(undefined, {
319
+ ...stripExampleFromTitle(title),
320
+ test_id: testId,
321
+ files: [file],
322
+ });
318
323
  });
319
- });
320
-
321
- await Promise.all(promises);
322
324
 
325
+ await Promise.all(promises);
326
+ }
323
327
  }
324
328
 
325
329
  function getTestAndMessage(title) {
@@ -2,7 +2,6 @@ const chalk = require('chalk');
2
2
  const crypto = require('crypto');
3
3
  const os = require('os');
4
4
  const path = require('path');
5
- const { v4: uuidv4 } = require('uuid');
6
5
  const fs = require('fs');
7
6
  const { APP_PREFIX, STATUS: Status, TESTOMAT_TMP_STORAGE_DIR } = require('../constants');
8
7
  const TestomatioClient = require('../client');
@@ -40,6 +39,8 @@ class PlaywrightReporter {
40
39
 
41
40
  const { title } = test;
42
41
 
42
+ let testId = getTestomatIdFromTestTitle(`${title} ${test.tags?.join(' ')}`);
43
+
43
44
  const { error, duration } = result;
44
45
 
45
46
  const suite_title = test.parent ? test.parent?.title : path.basename(test?.location?.file);
@@ -57,12 +58,10 @@ class PlaywrightReporter {
57
58
  const manuallyAttachedArtifacts = services.artifacts.get(fullTestTitle);
58
59
  const keyValues = services.keyValues.get(fullTestTitle);
59
60
 
60
- const rid = test.id || test.testId || uuidv4();
61
-
62
- const reportTestPromise = this.client.addTestRun(checkStatus(result.status), {
63
- rid,
61
+ const reportTestPromise = this.client
62
+ .addTestRun(checkStatus(result.status), {
64
63
  error,
65
- test_id: getTestomatIdFromTestTitle(`${title} ${test.tags?.join(' ')}`),
64
+ test_id: testId,
66
65
  suite_title,
67
66
  title,
68
67
  steps: steps.join('\n'),
@@ -71,16 +70,20 @@ class PlaywrightReporter {
71
70
  manuallyAttachedArtifacts,
72
71
  meta: keyValues,
73
72
  file: test.location?.file,
74
- });
73
+ })
74
+ .then(pipes => {
75
+ testId = pipes?.filter(p => p.pipe.includes('Testomatio'))[0]?.result?.data?.test_id;
75
76
 
76
- this.uploads.push({
77
- rid,
78
- title: test.title,
79
- files: result.attachments.filter(a => a.body || a.path),
80
- file: test.location?.file,
81
- });
82
- // remove empty uploads
83
- this.uploads = this.uploads.filter(upload => upload.files.length);
77
+ this.uploads.push({
78
+ testId,
79
+ title,
80
+ suite_title,
81
+ files: result.attachments.filter(a => a.body || a.path),
82
+ file: test.location?.file,
83
+ });
84
+ // remove empty uploads
85
+ this.uploads = this.uploads.filter(upload => upload.files.length);
86
+ });
84
87
 
85
88
  reportTestPromises.push(reportTestPromise);
86
89
  }
@@ -112,7 +115,7 @@ class PlaywrightReporter {
112
115
  const promises = [];
113
116
 
114
117
  for (const upload of this.uploads) {
115
- const { rid, file, title } = upload;
118
+ const { title, testId, suite_title } = upload;
116
119
 
117
120
  const files = upload.files.map(attachment => ({
118
121
  path: this.#getArtifactPath(attachment),
@@ -122,10 +125,11 @@ class PlaywrightReporter {
122
125
 
123
126
  promises.push(
124
127
  this.client.addTestRun(undefined, {
125
- rid,
128
+ test_id: testId,
126
129
  title,
130
+ suite_title,
127
131
  files,
128
- file,
132
+ file: upload.file,
129
133
  }),
130
134
  );
131
135
  }
@@ -0,0 +1,182 @@
1
+ const chalk = require('chalk');
2
+ const { TestomatioClient } = require('../client');
3
+ const { STATUS } = require('../constants');
4
+ const { getTestomatIdFromTestTitle } = require('../utils/utils');
5
+ const debug = require('debug')('@testomatio/reporter:adapter:vitest');
6
+
7
+ /**
8
+ * @typedef {import('../../types').VitestTest} VitestTest
9
+ * @typedef {import('../../types').VitestTestFile} VitestTestFile
10
+ * @typedef {import('../../types').VitestSuite} VitestSuite
11
+ * @typedef {import('../../types').VitestTestLogs} VitestTestLogs
12
+ * @typedef {import('../../vitest.types').ErrorWithDiff} ErrorWithDiff
13
+ * @typedef {typeof import('../constants').STATUS} STATUS
14
+ * @typedef {import('../../types').TestData} TestData
15
+ */
16
+
17
+ class VitestReporter {
18
+ constructor(config = {}) {
19
+ this.client = new TestomatioClient({ apiKey: config?.apiKey });
20
+ /**
21
+ * @type {(TestData & {status: string})[]} tests
22
+ */
23
+ this.tests = [];
24
+ }
25
+
26
+ // on run start
27
+ onInit() {
28
+ this.client.createRun();
29
+ }
30
+
31
+ /**
32
+ * @param {VitestTestFile[] | undefined} files // array with results;
33
+ * @param {unknown[] | undefined} errors // errors does not contain errors from tests; probably its testrunner errors
34
+ */
35
+ async onFinished(files, errors) {
36
+ if (!files || !files.length) console.info('No tests executed');
37
+
38
+ files.forEach(file => {
39
+ // task could be test or suite
40
+ file.tasks.forEach(taskOrSuite => {
41
+ if (taskOrSuite.type === 'test') {
42
+ const test = taskOrSuite;
43
+ this.tests.push(this.#getDataFromTest(test));
44
+ } else if (taskOrSuite.type === 'suite') {
45
+ const suite = taskOrSuite;
46
+ this.#processTasksOfSuite(suite);
47
+ } else {
48
+ throw new Error('Unprocessed case. Unknown task type');
49
+ }
50
+ });
51
+ });
52
+
53
+ debug(this.tests.length, 'tests collected');
54
+
55
+ // send tests to Testomat.io
56
+ for (const test of this.tests) {
57
+ await this.client.addTestRun(test.status, test);
58
+ }
59
+
60
+ console.log('finished');
61
+ if (errors.length) console.error('Vitest adapter errors:', errors);
62
+
63
+ await this.client.updateRunStatus(getRunStatusFromResults(files));
64
+ }
65
+
66
+ /* non-used listeners
67
+ onUserConsoleLog(log) {}
68
+ onPathsCollected(paths) {} // paths array to files with tests
69
+ onCollected(files) {} // files array with tests (but without results)
70
+ onTaskUpdate(packs) {} // some updates come here on afterAll block execution
71
+ onTestRemoved(trigger) {}
72
+ onWatcherStart(files, errors) {}
73
+ onWatcherRerun(files, trigger) {}
74
+ onServerRestart(reason) {}
75
+ onProcessTimeout() {}
76
+ */
77
+
78
+ /**
79
+ * Recursively gets all tasks from suite and pushes them to "tests" array
80
+ *
81
+ * @param {VitestSuite} suite
82
+ */
83
+ #processTasksOfSuite(suite) {
84
+ suite.tasks.forEach(taskOrSuite => {
85
+ if (taskOrSuite.type === 'test') {
86
+ const test = taskOrSuite;
87
+ this.tests.push(this.#getDataFromTest(test));
88
+ } else if (taskOrSuite.type === 'suite') {
89
+ const theSuite = taskOrSuite;
90
+ this.#processTasksOfSuite(theSuite);
91
+ } else {
92
+ throw new Error('Unprocessed case. Unknown task type');
93
+ }
94
+ });
95
+ }
96
+
97
+ /**
98
+ * Processes task and returns test data ready to be sent to Testomat.io
99
+ *
100
+ * @param {VitestTest} test
101
+ *
102
+ * @returns {TestData & {status: string}}
103
+ */
104
+ #getDataFromTest(test) {
105
+ return {
106
+ error: test.result?.errors ? test.result.errors[0] : undefined,
107
+ file: test.file.name,
108
+ logs: test.logs ? transformLogsToString(test.logs) : '',
109
+ meta: test.meta,
110
+ status: getTestStatus(test),
111
+ suite_title: test.suite.name || test.file?.name,
112
+ test_id: getTestomatIdFromTestTitle(test.name),
113
+ time: test.result?.duration || 0,
114
+ title: test.name,
115
+ // testomatio functions (artifacts, logs, steps, meta) are not supported
116
+ };
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Returns run status based on test results
122
+ *
123
+ * @param {VitestTestFile[]} files
124
+ * @returns {'passed' | 'failed' | 'finished'}
125
+ */
126
+ function getRunStatusFromResults(files) {
127
+ /**
128
+ * @type {'passed' | 'failed' | 'finished'}
129
+ */
130
+ let status = 'finished'; // default status (if no failed or passed tests)
131
+
132
+ files.forEach(file => {
133
+ // search for failed tests
134
+ file.tasks.forEach(taskOrSuite => {
135
+ if (taskOrSuite.result?.state === 'fail') {
136
+ status = 'failed'; // set status to failed if any test failed
137
+ }
138
+ });
139
+
140
+ // if there are no failed tests > search for passed tests
141
+ if (status !== 'failed') {
142
+ file.tasks.forEach(taskOrSuite => {
143
+ if (taskOrSuite.result?.state === 'pass') {
144
+ status = 'passed'; // set status to passed if any test passed (and there are no failed tests)
145
+ }
146
+ });
147
+ }
148
+ });
149
+
150
+ return status;
151
+ }
152
+
153
+ /**
154
+ * Returns test status in Testomat.io format
155
+ *
156
+ * @param {VitestTest} test
157
+ * @returns 'passed' | 'failed' | 'skipped'
158
+ */
159
+ function getTestStatus(test) {
160
+ if (test.result?.state === 'fail') return STATUS.FAILED;
161
+ if (test.result?.state === 'pass') return STATUS.PASSED;
162
+ if (!test.result && test.mode === 'skip') return STATUS.SKIPPED;
163
+ console.error(chalk.red('Unprocessed case for defining test status. Contact dev team. Test:'), test);
164
+ }
165
+
166
+ /**
167
+ * @param {VitestTestLogs[]} logs
168
+ * @returns string
169
+ */
170
+ function transformLogsToString(logs) {
171
+ if (!logs) return '';
172
+ let logsStr = '';
173
+ logs.forEach(log => {
174
+ if (log.type === 'stdout') logsStr += `${log.content}\n`;
175
+ if (log.type === 'stderr') logsStr += `${chalk.red(log.content)}\n`;
176
+ });
177
+ return logsStr;
178
+ }
179
+
180
+ module.exports.VitestReporter = VitestReporter;
181
+ module.exports.default = VitestReporter;
182
+ module.exports = VitestReporter;
@@ -44,10 +44,15 @@ program
44
44
 
45
45
  let timeoutTimer;
46
46
  if (opts.timelimit) {
47
- timeoutTimer = setTimeout(() => {
48
- console.log(`⚠️ Reached timeout of ${opts.timelimit}s. Exiting... (Exit code is 0 to not fail the pipeline)`);
49
- process.exit(0);
50
- }, parseInt(opts.timelimit, 10) * 1000);
47
+ timeoutTimer = setTimeout(
48
+ () => {
49
+ console.log(
50
+ `⚠️ Reached timeout of ${opts.timelimit}s. Exiting... (Exit code is 0 to not fail the pipeline)`,
51
+ );
52
+ process.exit(0);
53
+ },
54
+ parseInt(opts.timelimit, 10) * 1000,
55
+ );
51
56
  }
52
57
 
53
58
  try {
package/lib/client.js CHANGED
@@ -123,7 +123,7 @@ class Client {
123
123
  if (isTestShouldBeExculedFromReport(testData)) return [];
124
124
 
125
125
  if (status === STATUS.SKIPPED && process.env.TESTOMATIO_EXCLUDE_SKIPPED) {
126
- debug('Skipping test from report', testData?.title)
126
+ debug('Skipping test from report', testData?.title);
127
127
  return []; // do not log skipped tests
128
128
  }
129
129
 
@@ -133,10 +133,12 @@ class Client {
133
133
  suite_title: 'Unknown suite',
134
134
  };
135
135
 
136
+ /**
137
+ * @type {TestData}
138
+ */
136
139
  const {
137
- rid,
138
140
  error = null,
139
- time = '',
141
+ time = 0,
140
142
  example = null,
141
143
  files = [],
142
144
  filesBuffers = [],
@@ -185,7 +187,6 @@ class Client {
185
187
  this.totalUploaded += artifacts.length;
186
188
 
187
189
  const data = {
188
- rid,
189
190
  files,
190
191
  steps,
191
192
  status,
@@ -198,7 +199,7 @@ class Client {
198
199
  suite_id,
199
200
  test_id,
200
201
  message,
201
- run_time: parseFloat(time),
202
+ run_time: typeof time === 'number' ? time : parseFloat(time),
202
203
  artifacts,
203
204
  meta,
204
205
  };
@@ -224,7 +225,8 @@ class Client {
224
225
  /**
225
226
  *
226
227
  * Updates the status of the current test run and finishes the run.
227
- * @param {RunStatus} status - The status of the current test run. Must be one of "passed", "failed", or "finished"
228
+ * @param {'passed' | 'failed' | 'finished'} status - The status of the current test run.
229
+ * Must be one of "passed", "failed", or "finished"
228
230
  * @param {boolean} [isParallel] - Whether the current test run was executed in parallel with other tests.
229
231
  * @returns {Promise<any>} - A Promise that resolves when finishes the run.
230
232
  */
@@ -286,13 +288,22 @@ class Client {
286
288
  if (!message) message = error.message;
287
289
  if (error.inspect) message = error.inspect() || '';
288
290
 
289
- let stack = `${message}\n`;
291
+ let stack = '';
292
+ if (error.name) stack += `${chalk.red(error.name)}`;
293
+ if (error.operator) stack += ` (${chalk.red(error.operator)})`;
294
+ // add new line if something was added to stack
295
+ if (stack) stack += ': ';
290
296
 
291
- // diffs for mocha, cypress, codeceptjs style
292
- if (error.actual && error.expected) {
297
+ stack += `${message}\n`;
298
+
299
+ if (error.diff) {
300
+ stack += error.diff;
301
+ stack += '\n\n';
302
+ } else if (error.actual && error.expected && error.actual !== error.expected) {
303
+ // diffs for mocha, cypress, codeceptjs style
293
304
  stack += `\n\n${chalk.bold.green('+ expected')} ${chalk.bold.red('- actual')}`;
294
- stack += `\n${chalk.red(`- ${error.actual.toString().split('\n').join('\n- ')}`)}`;
295
305
  stack += `\n${chalk.green(`+ ${error.expected.toString().split('\n').join('\n+ ')}`)}`;
306
+ stack += `\n${chalk.red(`- ${error.actual.toString().split('\n').join('\n- ')}`)}`;
296
307
  stack += '\n\n';
297
308
  }
298
309
 
@@ -365,3 +376,4 @@ function isTestShouldBeExculedFromReport(testData) {
365
376
  }
366
377
 
367
378
  module.exports = Client;
379
+ module.exports.TestomatioClient = Client;
@@ -79,13 +79,13 @@ class GitLabPipe {
79
79
  let summary = `${this.hiddenCommentData}
80
80
 
81
81
  | [![Testomat.io Report](${testomatLogoURL})](https://testomat.io) | ${statusEmoji(
82
- runParams.status,
83
- )} ${runParams.status.toUpperCase()} ${statusEmoji(runParams.status)} |
82
+ runParams.status,
83
+ )} ${runParams.status.toUpperCase()} ${statusEmoji(runParams.status)} |
84
84
  | --- | --- |
85
85
  | Tests | ✔️ **${this.tests.length}** tests run |
86
86
  | Summary | ${statusEmoji('failed')} **${failedCount}** failed; ${statusEmoji(
87
- 'passed',
88
- )} **${passedCount}** passed; **${statusEmoji('skipped')}** ${skippedCount} skipped |
87
+ 'passed',
88
+ )} **${passedCount}** passed; **${statusEmoji('skipped')}** ${skippedCount} skipped |
89
89
  | Duration | 🕐 **${humanizeDuration(
90
90
  parseInt(
91
91
  this.tests.reduce((a, t) => a + (t.run_time || 0), 0),
@@ -339,9 +339,6 @@ class TestomatioPipe {
339
339
  addTest(data) {
340
340
  if (!this.isEnabled) return;
341
341
  if (!this.runId) return;
342
-
343
- // add test ID + run ID
344
- data.rid = `${this.runId}-${data.rid}`;
345
342
  data.api_key = this.apiKey;
346
343
  data.create = this.createNewTests;
347
344
 
@@ -248,7 +248,7 @@ const foundedTestLog = (app, tests) => {
248
248
  const humanize = text => {
249
249
  // if there are no spaces, decamelize
250
250
  if (!text.trim().includes(' ')) text = decamelize(text);
251
-
251
+
252
252
  return text
253
253
  .replace(/_./g, match => ` ${match.charAt(1).toUpperCase()}`)
254
254
  .trim()
package/lib/xmlReader.js CHANGED
@@ -460,7 +460,6 @@ function reduceTestCases(prev, item) {
460
460
  // SpecFlow config
461
461
  let { title, tags } = fetchProperties(item.type === 'ParameterizedMethod' ? item : testCaseItem);
462
462
  let example = null;
463
- const suiteTitle = reduceOptions.preferClassname ? testCaseItem.classname : item.name || testCaseItem.classname;
464
463
 
465
464
  title ||= testCaseItem.name || testCaseItem.methodname || testCaseItem.classname;
466
465
  tags ||= [];
@@ -494,7 +493,7 @@ function reduceTestCases(prev, item) {
494
493
  run_time: parseFloat(testCaseItem.time || testCaseItem.duration) * 1000,
495
494
  status,
496
495
  title,
497
- suite_title: suiteTitle,
496
+ suite_title: reduceOptions.preferClassname ? testCaseItem.classname : item.name || testCaseItem.classname,
498
497
  });
499
498
  });
500
499
  return prev;
@@ -528,4 +527,4 @@ function fetchProperties(item) {
528
527
  .filter(p => p.name === 'Category')
529
528
  .forEach(p => tags.push(p.value));
530
529
  return { title, tags };
531
- }
530
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testomatio/reporter",
3
- "version": "1.4.5",
3
+ "version": "1.5.0-beta-vitest",
4
4
  "description": "Testomatio Reporter Client",
5
5
  "main": "./lib/reporter.js",
6
6
  "typings": "typings/index.d.ts",
@@ -55,6 +55,7 @@
55
55
  "test:adapter:jasmine:example": "./tests/adapter/examples/jasmine/passReporterOpts.sh && jasmine './tests/adapter/examples/jasmine/index.test.js' --reporter=./../../../lib/adapter/jasmine.js",
56
56
  "test:adapter:codecept:example": "codeceptjs run --config='./tests/adapter/examples/codecept/codecept.conf.js'",
57
57
  "test:adapter:cucumber:example": "cd ./tests/adapter/examples/cucumber && npx cucumber-js",
58
+ "test:adapter:vitest:example": "vitest --config='./tests/adapter/examples/vitest/vitest.config.js'",
58
59
  "test:storage": "npx mocha tests-storage/artifact-storage.test.js && npx mocha tests-storage/data-storage.test.js && TESTOMATIO_INTERCEPT_CONSOLE_LOGS=true npx mocha tests-storage/logger.test.js && npx mocha tests-storage/logger-2.test.js && npx mocha tests-storage/reporter-functions.test.js"
59
60
  },
60
61
  "devDependencies": {