@testomatio/reporter 1.2.1-beta → 1.2.1-beta.codecept-id
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 +61 -54
- package/lib/adapter/codecept.js +136 -57
- package/lib/adapter/cucumber/current.js +103 -60
- package/lib/adapter/cucumber/legacy.js +27 -12
- package/lib/adapter/cucumber.js +2 -2
- package/lib/adapter/cypress-plugin/index.js +52 -25
- package/lib/adapter/jasmine.js +1 -1
- package/lib/adapter/jest.js +49 -11
- package/lib/adapter/mocha.js +103 -51
- package/lib/adapter/playwright.js +100 -31
- package/lib/adapter/webdriver.js +1 -1
- package/lib/bin/reportXml.js +14 -13
- package/lib/bin/startTest.js +27 -6
- package/lib/client.js +193 -69
- package/lib/config.js +34 -0
- package/lib/constants.js +19 -7
- package/lib/data-storage.js +203 -0
- package/lib/fileUploader.js +128 -53
- package/lib/junit-adapter/adapter.js +0 -2
- package/lib/junit-adapter/csharp.js +3 -4
- package/lib/junit-adapter/index.js +3 -3
- package/lib/junit-adapter/java.js +35 -17
- package/lib/junit-adapter/javascript.js +1 -2
- package/lib/junit-adapter/python.js +12 -14
- package/lib/junit-adapter/ruby.js +1 -2
- package/lib/pipe/csv.js +5 -3
- package/lib/pipe/github.js +27 -39
- package/lib/pipe/gitlab.js +20 -24
- package/lib/pipe/html.js +317 -0
- package/lib/pipe/index.js +3 -1
- package/lib/pipe/testomatio.js +182 -55
- package/lib/reporter-functions.js +46 -0
- package/lib/reporter.js +11 -9
- package/lib/services/artifacts.js +57 -0
- package/lib/services/index.js +13 -0
- package/lib/services/key-values.js +58 -0
- package/lib/services/logger.js +311 -0
- package/lib/template/template-draft.hbs +249 -0
- package/lib/template/testomatio.hbs +388 -0
- package/lib/utils/pipe_utils.js +128 -0
- package/lib/{util.js → utils/utils.js} +145 -12
- package/lib/xmlReader.js +211 -122
- package/package.json +18 -8
- package/lib/_ArtifactStorageOld.js +0 -142
- package/lib/artifactStorage.js +0 -25
- package/lib/dataStorage.js +0 -180
- package/lib/logger.js +0 -278
|
@@ -11,7 +11,10 @@ const debug = require('debug')('@testomatio/reporter:util');
|
|
|
11
11
|
* @returns {String|null} testId
|
|
12
12
|
*/
|
|
13
13
|
const parseTest = testTitle => {
|
|
14
|
-
|
|
14
|
+
if (!testTitle) return null;
|
|
15
|
+
|
|
16
|
+
const captures = testTitle.match(/\@T[\w\d]{8}/);
|
|
17
|
+
|
|
15
18
|
if (captures) {
|
|
16
19
|
return captures[1];
|
|
17
20
|
}
|
|
@@ -25,7 +28,7 @@ const parseTest = testTitle => {
|
|
|
25
28
|
* @returns {String|null} suiteId
|
|
26
29
|
*/
|
|
27
30
|
const parseSuite = suiteTitle => {
|
|
28
|
-
const captures = suiteTitle.match(
|
|
31
|
+
const captures = suiteTitle.match(/\@S[\w\d]{8}/);
|
|
29
32
|
if (captures) {
|
|
30
33
|
return captures[1];
|
|
31
34
|
}
|
|
@@ -52,11 +55,20 @@ const isValidUrl = s => {
|
|
|
52
55
|
}
|
|
53
56
|
};
|
|
54
57
|
|
|
58
|
+
const fileMatchRegex = /file:(\/\/?[^:\s]+?\.(png|avi|webm|jpg|html|txt))/gi;
|
|
59
|
+
|
|
55
60
|
const fetchFilesFromStackTrace = (stack = '') => {
|
|
56
|
-
const files = stack.matchAll(
|
|
57
|
-
|
|
58
|
-
.map(f => f
|
|
59
|
-
|
|
61
|
+
const files = Array.from(stack.matchAll(fileMatchRegex))
|
|
62
|
+
.map(f => f[1].trim())
|
|
63
|
+
.map(f => (f.startsWith('//') ? f.substring(1) : f));
|
|
64
|
+
|
|
65
|
+
debug('Found files in stack trace: ', files);
|
|
66
|
+
|
|
67
|
+
return files.filter(f => {
|
|
68
|
+
const isFile = fs.existsSync(f);
|
|
69
|
+
if (!isFile) debug('File %s could not be found and uploaded as artifact', f);
|
|
70
|
+
return isFile;
|
|
71
|
+
});
|
|
60
72
|
};
|
|
61
73
|
|
|
62
74
|
const fetchSourceCodeFromStackTrace = (stack = '') => {
|
|
@@ -84,11 +96,41 @@ const fetchSourceCodeFromStackTrace = (stack = '') => {
|
|
|
84
96
|
|
|
85
97
|
if (!source) return '';
|
|
86
98
|
|
|
87
|
-
return source
|
|
99
|
+
return source
|
|
100
|
+
.split('\n')
|
|
88
101
|
.map((l, i) => {
|
|
89
102
|
if (i === prepend) return `${line} > ${chalk.bold(l)}`;
|
|
90
|
-
return `${line - prepend + i} | ${l}
|
|
91
|
-
})
|
|
103
|
+
return `${line - prepend + i} | ${l}`;
|
|
104
|
+
})
|
|
105
|
+
.join('\n');
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const TEST_ID_REGEX = /@T([\w\d]{8})/;
|
|
109
|
+
|
|
110
|
+
const fetchIdFromCode = (code, opts = {}) => {
|
|
111
|
+
const comments = code
|
|
112
|
+
.split('\n')
|
|
113
|
+
.map(l => l.trim())
|
|
114
|
+
.filter(l => {
|
|
115
|
+
switch (opts.lang) {
|
|
116
|
+
case 'ruby':
|
|
117
|
+
case 'python':
|
|
118
|
+
return l.startsWith('# ');
|
|
119
|
+
default:
|
|
120
|
+
return l.startsWith('// ');
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
return comments.find(c => c.match(TEST_ID_REGEX))?.match(TEST_ID_REGEX)?.[1];
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const fetchIdFromOutput = output => {
|
|
128
|
+
const lines = output
|
|
129
|
+
.split('\n')
|
|
130
|
+
.map(l => l.trim())
|
|
131
|
+
.filter(l => l.startsWith('tid://'));
|
|
132
|
+
|
|
133
|
+
return lines.find(c => c.match(TEST_ID_REGEX))?.match(TEST_ID_REGEX)?.[1];
|
|
92
134
|
};
|
|
93
135
|
|
|
94
136
|
const fetchSourceCode = (contents, opts = {}) => {
|
|
@@ -103,7 +145,15 @@ const fetchSourceCode = (contents, opts = {}) => {
|
|
|
103
145
|
// remove special chars from title
|
|
104
146
|
if (!lineIndex && opts.title) {
|
|
105
147
|
const title = opts.title.replace(/[([@].*/g, '');
|
|
106
|
-
|
|
148
|
+
|
|
149
|
+
if (opts.lang === 'java') {
|
|
150
|
+
lineIndex = lines.findIndex(l => l.includes(`test${title}`));
|
|
151
|
+
if (lineIndex === -1) lineIndex = lines.findIndex(l => l.includes(`@DisplayName("${title}`));
|
|
152
|
+
if (lineIndex === -1) lineIndex = lines.findIndex(l => l.includes(`public void ${title}`));
|
|
153
|
+
if (lineIndex === -1) lineIndex = lines.findIndex(l => l.includes(`${title}(`));
|
|
154
|
+
} else {
|
|
155
|
+
lineIndex = lines.findIndex(l => l.includes(title));
|
|
156
|
+
}
|
|
107
157
|
}
|
|
108
158
|
|
|
109
159
|
if (opts.prepend) {
|
|
@@ -112,7 +162,7 @@ const fetchSourceCode = (contents, opts = {}) => {
|
|
|
112
162
|
|
|
113
163
|
if (lineIndex) {
|
|
114
164
|
const result = [];
|
|
115
|
-
for (let i = lineIndex; i <
|
|
165
|
+
for (let i = lineIndex; i < lineIndex + limit; i++) {
|
|
116
166
|
if (lines[i] === undefined) continue;
|
|
117
167
|
|
|
118
168
|
if (i > lineIndex + 2 && !opts.prepend) {
|
|
@@ -186,13 +236,92 @@ const fileSystem = {
|
|
|
186
236
|
} else {
|
|
187
237
|
debug(`Trying to delete ${dirPath} but it doesn't exist`);
|
|
188
238
|
}
|
|
189
|
-
}
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const foundedTestLog = (app, tests) => {
|
|
243
|
+
const n = tests.length;
|
|
244
|
+
|
|
245
|
+
return n === 1 ? console.log(app, `✅ We found one test!`) : console.log(app, `✅ We found ${n} tests!`);
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
const humanize = text => {
|
|
249
|
+
text = decamelize(text);
|
|
250
|
+
return text
|
|
251
|
+
.replace(/_./g, match => ` ${match.charAt(1).toUpperCase()}`)
|
|
252
|
+
.trim()
|
|
253
|
+
.replace(/^(.)|\s(.)/g, $1 => $1.toUpperCase())
|
|
254
|
+
.trim()
|
|
255
|
+
.replace(/\sA\s/g, ' a ') // replace a|the
|
|
256
|
+
.replace(/\sThe\s/g, ' the ') // replace a|the
|
|
257
|
+
.replace(/^Test\s/, '')
|
|
258
|
+
.replace(/^Should\s/, '');
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* From https://github.com/sindresorhus/decamelize/blob/main/index.js
|
|
263
|
+
* @param {*} text
|
|
264
|
+
* @returns
|
|
265
|
+
*/
|
|
266
|
+
const decamelize = text => {
|
|
267
|
+
const separator = '_';
|
|
268
|
+
const replacement = `$1${separator}$2`;
|
|
269
|
+
|
|
270
|
+
// Split lowercase sequences followed by uppercase character.
|
|
271
|
+
// `dataForUSACounties` → `data_For_USACounties`
|
|
272
|
+
// `myURLstring → `my_URLstring`
|
|
273
|
+
let decamelized = text.replace(/([\p{Lowercase_Letter}\d])(\p{Uppercase_Letter})/gu, replacement);
|
|
274
|
+
|
|
275
|
+
// Lowercase all single uppercase characters. As we
|
|
276
|
+
// want to preserve uppercase sequences, we cannot
|
|
277
|
+
// simply lowercase the separated string at the end.
|
|
278
|
+
// `data_For_USACounties` → `data_for_USACounties`
|
|
279
|
+
decamelized = decamelized.replace(
|
|
280
|
+
/((?<![\p{Uppercase_Letter}\d])[\p{Uppercase_Letter}\d](?![\p{Uppercase_Letter}\d]))/gu,
|
|
281
|
+
$0 => $0.toLowerCase(),
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
// Remaining uppercase sequences will be separated from lowercase sequences.
|
|
285
|
+
// `data_For_USACounties` → `data_for_USA_counties`
|
|
286
|
+
return decamelized.replace(
|
|
287
|
+
/(\p{Uppercase_Letter}+)(\p{Uppercase_Letter}\p{Lowercase_Letter}+)/gu,
|
|
288
|
+
(_, $1, $2) => $1 + separator + $2.toLowerCase(),
|
|
289
|
+
);
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Used to remove color codes
|
|
294
|
+
* @param {*} input
|
|
295
|
+
* @returns
|
|
296
|
+
*/
|
|
297
|
+
function removeColorCodes(input) {
|
|
298
|
+
// eslint-disable-next-line no-control-regex
|
|
299
|
+
return input.replace(/\x1b\[[0-9;]*m/g, '');
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const testRunnerHelper = {
|
|
303
|
+
// for Jest
|
|
304
|
+
getNameOfCurrentlyRunningTest: () => {
|
|
305
|
+
if (global.testomatioTestTitle) return global.testomatioTestTitle;
|
|
306
|
+
|
|
307
|
+
if (!process.env.JEST_WORKER_ID) return null;
|
|
308
|
+
try {
|
|
309
|
+
// TODO: expect?.getState()?.testPath + ' ' + expect?.getState()?.currentTestName
|
|
310
|
+
// @ts-expect-error "expect" could only be defined inside Jest environement (forbidden to import it outside)
|
|
311
|
+
// eslint-disable-next-line no-undef
|
|
312
|
+
return expect?.getState()?.currentTestName;
|
|
313
|
+
} catch (e) {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
},
|
|
190
317
|
};
|
|
191
318
|
|
|
192
319
|
module.exports = {
|
|
193
320
|
isSameTest,
|
|
194
321
|
fetchSourceCode,
|
|
195
322
|
fetchSourceCodeFromStackTrace,
|
|
323
|
+
fetchIdFromCode,
|
|
324
|
+
fetchIdFromOutput,
|
|
196
325
|
fetchFilesFromStackTrace,
|
|
197
326
|
fileSystem,
|
|
198
327
|
getCurrentDateTime,
|
|
@@ -201,4 +330,8 @@ module.exports = {
|
|
|
201
330
|
ansiRegExp,
|
|
202
331
|
parseTest,
|
|
203
332
|
parseSuite,
|
|
333
|
+
humanize,
|
|
334
|
+
removeColorCodes,
|
|
335
|
+
foundedTestLog,
|
|
336
|
+
testRunnerHelper,
|
|
204
337
|
};
|