@testomatio/reporter 2.7.2-beta.1 → 2.7.2
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/lib/adapter/vitest.d.ts +9 -0
- package/lib/adapter/vitest.js +75 -29
- package/package.json +1 -1
- package/src/adapter/vitest.js +70 -26
package/lib/adapter/vitest.d.ts
CHANGED
|
@@ -24,12 +24,21 @@ export class VitestReporter {
|
|
|
24
24
|
tests: (TestData & {
|
|
25
25
|
status: string;
|
|
26
26
|
})[];
|
|
27
|
+
_finalized: boolean;
|
|
28
|
+
_finalizing: boolean;
|
|
27
29
|
onInit(): void;
|
|
28
30
|
/**
|
|
29
31
|
* @param {VitestTestFile[] | undefined} files // array with results;
|
|
30
32
|
* @param {unknown[] | undefined} errors // errors does not contain errors from tests; probably its testrunner errors
|
|
31
33
|
*/
|
|
32
34
|
onFinished(files: VitestTestFile[] | undefined, errors: unknown[] | undefined): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Vitest 4+ reporter API callback.
|
|
37
|
+
*
|
|
38
|
+
* @param {Array<unknown> | undefined} testModules
|
|
39
|
+
* @param {unknown[] | undefined} errors
|
|
40
|
+
*/
|
|
41
|
+
onTestRunEnd(testModules: Array<unknown> | undefined, errors: unknown[] | undefined): Promise<void>;
|
|
33
42
|
#private;
|
|
34
43
|
}
|
|
35
44
|
import { Client as TestomatioClient } from '../client.js';
|
package/lib/adapter/vitest.js
CHANGED
|
@@ -26,9 +26,13 @@ class VitestReporter {
|
|
|
26
26
|
* @type {(TestData & {status: string})[]} tests
|
|
27
27
|
*/
|
|
28
28
|
this.tests = [];
|
|
29
|
+
this._finalized = false;
|
|
30
|
+
this._finalizing = false;
|
|
29
31
|
}
|
|
30
32
|
// on run start
|
|
31
33
|
onInit() {
|
|
34
|
+
this._finalized = false;
|
|
35
|
+
this._finalizing = false;
|
|
32
36
|
this.client.createRun();
|
|
33
37
|
}
|
|
34
38
|
/**
|
|
@@ -36,33 +40,57 @@ class VitestReporter {
|
|
|
36
40
|
* @param {unknown[] | undefined} errors // errors does not contain errors from tests; probably its testrunner errors
|
|
37
41
|
*/
|
|
38
42
|
async onFinished(files, errors) {
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
43
|
+
if (this._finalized || this._finalizing)
|
|
44
|
+
return;
|
|
45
|
+
this._finalizing = true;
|
|
46
|
+
try {
|
|
47
|
+
this.tests = [];
|
|
48
|
+
if (!files || !files.length) {
|
|
49
|
+
console.info('No tests executed');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
files.forEach(file => {
|
|
53
|
+
// task could be test or suite
|
|
54
|
+
getTasks(file).forEach(taskOrSuite => {
|
|
55
|
+
if (taskOrSuite.type === 'test') {
|
|
56
|
+
const test = taskOrSuite;
|
|
57
|
+
this.tests.push(this.#getDataFromTest(test));
|
|
58
|
+
}
|
|
59
|
+
else if (taskOrSuite.type === 'suite') {
|
|
60
|
+
const suite = taskOrSuite;
|
|
61
|
+
this.#processTasksOfSuite(suite);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
throw new Error('Unprocessed case. Unknown task type');
|
|
65
|
+
}
|
|
66
|
+
});
|
|
55
67
|
});
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
debug(this.tests.length, 'tests collected');
|
|
69
|
+
// send tests to Testomat.io
|
|
70
|
+
for (const test of this.tests) {
|
|
71
|
+
await this.client.addTestRun(test.status, test);
|
|
72
|
+
}
|
|
73
|
+
console.log('finished');
|
|
74
|
+
if (errors.length)
|
|
75
|
+
console.error('Vitest adapter errors:', errors);
|
|
76
|
+
await this.client.updateRunStatus(getRunStatusFromResults(files));
|
|
77
|
+
this._finalized = true;
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
this._finalizing = false;
|
|
61
81
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Vitest 4+ reporter API callback.
|
|
85
|
+
*
|
|
86
|
+
* @param {Array<unknown> | undefined} testModules
|
|
87
|
+
* @param {unknown[] | undefined} errors
|
|
88
|
+
*/
|
|
89
|
+
async onTestRunEnd(testModules, errors) {
|
|
90
|
+
const files = (testModules || [])
|
|
91
|
+
.map(module => module && ( /** @type {any} */(module).task || module))
|
|
92
|
+
.filter(Boolean);
|
|
93
|
+
await this.onFinished(files, errors);
|
|
66
94
|
}
|
|
67
95
|
/* non-used listeners
|
|
68
96
|
onUserConsoleLog(log) {}
|
|
@@ -81,7 +109,7 @@ class VitestReporter {
|
|
|
81
109
|
* @param {VitestSuite} suite
|
|
82
110
|
*/
|
|
83
111
|
#processTasksOfSuite(suite) {
|
|
84
|
-
suite.
|
|
112
|
+
getTasks(suite).forEach(taskOrSuite => {
|
|
85
113
|
if (taskOrSuite.type === 'test') {
|
|
86
114
|
const test = taskOrSuite;
|
|
87
115
|
this.tests.push(this.#getDataFromTest(test));
|
|
@@ -105,12 +133,12 @@ class VitestReporter {
|
|
|
105
133
|
#getDataFromTest(test) {
|
|
106
134
|
return {
|
|
107
135
|
error: test.result?.errors ? test.result.errors[0] : undefined,
|
|
108
|
-
file: test.file.
|
|
136
|
+
file: test.file?.name || test.file?.filepath || '',
|
|
109
137
|
logs: test.logs ? transformLogsToString(test.logs) : '',
|
|
110
138
|
meta: test.meta,
|
|
111
139
|
// @ts-ignore - STATUS values are string literals but type system sees them as string
|
|
112
140
|
status: getTestStatus(test),
|
|
113
|
-
suite_title: test.suite.name || test.file?.
|
|
141
|
+
suite_title: test.suite?.name || test.file?.name || test.file?.filepath,
|
|
114
142
|
test_id: (0, utils_js_1.getTestomatIdFromTestTitle)(test.name),
|
|
115
143
|
time: test.result?.duration || 0,
|
|
116
144
|
title: test.name,
|
|
@@ -159,9 +187,10 @@ function getTestStatus(test) {
|
|
|
159
187
|
return constants_js_1.STATUS.FAILED;
|
|
160
188
|
if (test.result?.state === 'pass')
|
|
161
189
|
return constants_js_1.STATUS.PASSED;
|
|
162
|
-
if (!test.result && test.mode === 'skip')
|
|
190
|
+
if (test.result?.state === 'skip' || (!test.result && test.mode === 'skip'))
|
|
163
191
|
return constants_js_1.STATUS.SKIPPED;
|
|
164
192
|
console.error(picocolors_1.default.red('Unprocessed case for defining test status. Contact dev team. Test:'), test);
|
|
193
|
+
return constants_js_1.STATUS.SKIPPED;
|
|
165
194
|
}
|
|
166
195
|
/**
|
|
167
196
|
* @param {VitestTestLogs[]} logs
|
|
@@ -179,6 +208,23 @@ function transformLogsToString(logs) {
|
|
|
179
208
|
});
|
|
180
209
|
return logsStr;
|
|
181
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* Supports both old and new Vitest task tree shapes.
|
|
213
|
+
*
|
|
214
|
+
* @param {any} node
|
|
215
|
+
* @returns {any[]}
|
|
216
|
+
*/
|
|
217
|
+
function getTasks(node) {
|
|
218
|
+
if (!node)
|
|
219
|
+
return [];
|
|
220
|
+
if (Array.isArray(node.tasks))
|
|
221
|
+
return node.tasks;
|
|
222
|
+
if (Array.isArray(node.children))
|
|
223
|
+
return node.children;
|
|
224
|
+
if (node.task)
|
|
225
|
+
return [node.task];
|
|
226
|
+
return [];
|
|
227
|
+
}
|
|
182
228
|
module.exports = VitestReporter;
|
|
183
229
|
|
|
184
230
|
module.exports.VitestReporter = VitestReporter;
|
package/package.json
CHANGED
package/src/adapter/vitest.js
CHANGED
|
@@ -23,10 +23,14 @@ class VitestReporter {
|
|
|
23
23
|
* @type {(TestData & {status: string})[]} tests
|
|
24
24
|
*/
|
|
25
25
|
this.tests = [];
|
|
26
|
+
this._finalized = false;
|
|
27
|
+
this._finalizing = false;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
// on run start
|
|
29
31
|
onInit() {
|
|
32
|
+
this._finalized = false;
|
|
33
|
+
this._finalizing = false;
|
|
30
34
|
this.client.createRun();
|
|
31
35
|
}
|
|
32
36
|
|
|
@@ -35,34 +39,59 @@ class VitestReporter {
|
|
|
35
39
|
* @param {unknown[] | undefined} errors // errors does not contain errors from tests; probably its testrunner errors
|
|
36
40
|
*/
|
|
37
41
|
async onFinished(files, errors) {
|
|
38
|
-
if (
|
|
42
|
+
if (this._finalized || this._finalizing) return;
|
|
43
|
+
this._finalizing = true;
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
this.tests = [];
|
|
47
|
+
if (!files || !files.length) {
|
|
48
|
+
console.info('No tests executed');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
39
51
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
files.forEach(file => {
|
|
53
|
+
// task could be test or suite
|
|
54
|
+
getTasks(file).forEach(taskOrSuite => {
|
|
55
|
+
if (taskOrSuite.type === 'test') {
|
|
56
|
+
const test = taskOrSuite;
|
|
57
|
+
this.tests.push(this.#getDataFromTest(test));
|
|
58
|
+
} else if (taskOrSuite.type === 'suite') {
|
|
59
|
+
const suite = taskOrSuite;
|
|
60
|
+
this.#processTasksOfSuite(suite);
|
|
61
|
+
} else {
|
|
62
|
+
throw new Error('Unprocessed case. Unknown task type');
|
|
63
|
+
}
|
|
64
|
+
});
|
|
52
65
|
});
|
|
53
|
-
});
|
|
54
66
|
|
|
55
|
-
|
|
67
|
+
debug(this.tests.length, 'tests collected');
|
|
56
68
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
69
|
+
// send tests to Testomat.io
|
|
70
|
+
for (const test of this.tests) {
|
|
71
|
+
await this.client.addTestRun(test.status, test);
|
|
72
|
+
}
|
|
61
73
|
|
|
62
|
-
|
|
63
|
-
|
|
74
|
+
console.log('finished');
|
|
75
|
+
if (errors.length) console.error('Vitest adapter errors:', errors);
|
|
64
76
|
|
|
65
|
-
|
|
77
|
+
await this.client.updateRunStatus(getRunStatusFromResults(files));
|
|
78
|
+
this._finalized = true;
|
|
79
|
+
} finally {
|
|
80
|
+
this._finalizing = false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Vitest 4+ reporter API callback.
|
|
86
|
+
*
|
|
87
|
+
* @param {Array<unknown> | undefined} testModules
|
|
88
|
+
* @param {unknown[] | undefined} errors
|
|
89
|
+
*/
|
|
90
|
+
async onTestRunEnd(testModules, errors) {
|
|
91
|
+
const files = (testModules || [])
|
|
92
|
+
.map(module => module && (/** @type {any} */ (module).task || module))
|
|
93
|
+
.filter(Boolean);
|
|
94
|
+
await this.onFinished(files, errors);
|
|
66
95
|
}
|
|
67
96
|
|
|
68
97
|
/* non-used listeners
|
|
@@ -83,7 +112,7 @@ class VitestReporter {
|
|
|
83
112
|
* @param {VitestSuite} suite
|
|
84
113
|
*/
|
|
85
114
|
#processTasksOfSuite(suite) {
|
|
86
|
-
suite.
|
|
115
|
+
getTasks(suite).forEach(taskOrSuite => {
|
|
87
116
|
if (taskOrSuite.type === 'test') {
|
|
88
117
|
const test = taskOrSuite;
|
|
89
118
|
this.tests.push(this.#getDataFromTest(test));
|
|
@@ -106,12 +135,12 @@ class VitestReporter {
|
|
|
106
135
|
#getDataFromTest(test) {
|
|
107
136
|
return {
|
|
108
137
|
error: test.result?.errors ? test.result.errors[0] : undefined,
|
|
109
|
-
file: test.file.
|
|
138
|
+
file: test.file?.name || test.file?.filepath || '',
|
|
110
139
|
logs: test.logs ? transformLogsToString(test.logs) : '',
|
|
111
140
|
meta: test.meta,
|
|
112
141
|
// @ts-ignore - STATUS values are string literals but type system sees them as string
|
|
113
142
|
status: getTestStatus(test),
|
|
114
|
-
suite_title: test.suite.name || test.file?.
|
|
143
|
+
suite_title: test.suite?.name || test.file?.name || test.file?.filepath,
|
|
115
144
|
test_id: getTestomatIdFromTestTitle(test.name),
|
|
116
145
|
time: test.result?.duration || 0,
|
|
117
146
|
title: test.name,
|
|
@@ -162,8 +191,9 @@ function getRunStatusFromResults(files) {
|
|
|
162
191
|
function getTestStatus(test) {
|
|
163
192
|
if (test.result?.state === 'fail') return STATUS.FAILED;
|
|
164
193
|
if (test.result?.state === 'pass') return STATUS.PASSED;
|
|
165
|
-
if (!test.result && test.mode === 'skip') return STATUS.SKIPPED;
|
|
194
|
+
if (test.result?.state === 'skip' || (!test.result && test.mode === 'skip')) return STATUS.SKIPPED;
|
|
166
195
|
console.error(pc.red('Unprocessed case for defining test status. Contact dev team. Test:'), test);
|
|
196
|
+
return STATUS.SKIPPED;
|
|
167
197
|
}
|
|
168
198
|
|
|
169
199
|
/**
|
|
@@ -180,5 +210,19 @@ function transformLogsToString(logs) {
|
|
|
180
210
|
return logsStr;
|
|
181
211
|
}
|
|
182
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Supports both old and new Vitest task tree shapes.
|
|
215
|
+
*
|
|
216
|
+
* @param {any} node
|
|
217
|
+
* @returns {any[]}
|
|
218
|
+
*/
|
|
219
|
+
function getTasks(node) {
|
|
220
|
+
if (!node) return [];
|
|
221
|
+
if (Array.isArray(node.tasks)) return node.tasks;
|
|
222
|
+
if (Array.isArray(node.children)) return node.children;
|
|
223
|
+
if (node.task) return [node.task];
|
|
224
|
+
return [];
|
|
225
|
+
}
|
|
226
|
+
|
|
183
227
|
export default VitestReporter;
|
|
184
228
|
export { VitestReporter };
|