@testomatio/reporter 2.2.1 → 2.2.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/webdriver.js +4 -4
- package/lib/bin/cli.js +9 -6
- package/lib/client.d.ts +1 -2
- package/lib/client.js +2 -3
- package/lib/pipe/testomatio.d.ts +0 -1
- package/lib/pipe/testomatio.js +1 -5
- package/lib/replay.js +1 -1
- package/package.json +1 -1
- package/src/adapter/webdriver.js +5 -4
- package/src/bin/cli.js +9 -6
- package/src/client.js +2 -3
- package/src/pipe/testomatio.js +1 -4
- package/src/replay.js +1 -1
package/lib/adapter/webdriver.js
CHANGED
|
@@ -41,6 +41,7 @@ const client_js_1 = __importDefault(require("../client.js"));
|
|
|
41
41
|
const utils_js_1 = require("../utils/utils.js");
|
|
42
42
|
const index_js_1 = require("../services/index.js");
|
|
43
43
|
const constants_js_1 = require("../constants.js");
|
|
44
|
+
const data_storage_js_1 = require("../data-storage.js");
|
|
44
45
|
class WebdriverReporter extends reporter_1.default {
|
|
45
46
|
constructor(options) {
|
|
46
47
|
super(options);
|
|
@@ -77,9 +78,7 @@ class WebdriverReporter extends reporter_1.default {
|
|
|
77
78
|
onTestEnd(test) {
|
|
78
79
|
test.suite = test.parent;
|
|
79
80
|
const logs = getTestLogs(test.fullTitle);
|
|
80
|
-
//
|
|
81
|
-
// ^ not reproduced anymore (Jul 2025)
|
|
82
|
-
// but still be under investigation
|
|
81
|
+
// still be under investigation
|
|
83
82
|
const artifacts = index_js_1.services.artifacts.get(test.fullTitle);
|
|
84
83
|
const keyValues = index_js_1.services.keyValues.get(test.fullTitle);
|
|
85
84
|
test.logs = logs;
|
|
@@ -102,8 +101,9 @@ class WebdriverReporter extends reporter_1.default {
|
|
|
102
101
|
const screenshotsBuffers = output
|
|
103
102
|
.filter(el => el.endpoint === screenshotEndpoint && el.result && el.result.value)
|
|
104
103
|
.map(el => Buffer.from(el.result.value, 'base64'));
|
|
104
|
+
const rid = (0, data_storage_js_1.stringToMD5Hash)(test.fullTitle);
|
|
105
105
|
await this.client.addTestRun(state, {
|
|
106
|
-
rid
|
|
106
|
+
rid,
|
|
107
107
|
manuallyAttachedArtifacts: test.artifacts,
|
|
108
108
|
error,
|
|
109
109
|
logs: test.logs,
|
package/lib/bin/cli.js
CHANGED
|
@@ -78,7 +78,7 @@ program
|
|
|
78
78
|
console.log(constants_js_1.APP_PREFIX, `No command provided. Use -c option to launch a test runner.`);
|
|
79
79
|
return process.exit(255);
|
|
80
80
|
}
|
|
81
|
-
const client = new client_js_1.default({ apiKey, title
|
|
81
|
+
const client = new client_js_1.default({ apiKey, title });
|
|
82
82
|
if (opts.filter) {
|
|
83
83
|
const [pipe, ...optsArray] = opts.filter.split(':');
|
|
84
84
|
const pipeOptions = optsArray.join(':');
|
|
@@ -95,13 +95,16 @@ program
|
|
|
95
95
|
console.log(constants_js_1.APP_PREFIX, `🚀 Running`, picocolors_1.default.green(command));
|
|
96
96
|
const runTests = async () => {
|
|
97
97
|
const testCmds = command.split(' ');
|
|
98
|
-
const cmd = (0, cross_spawn_1.spawn)(testCmds[0], testCmds.slice(1), {
|
|
98
|
+
const cmd = (0, cross_spawn_1.spawn)(testCmds[0], testCmds.slice(1), {
|
|
99
|
+
stdio: 'inherit',
|
|
100
|
+
env: { ...process.env, TESTOMATIO_PROCEED: 'true', runId: client.runId },
|
|
101
|
+
});
|
|
99
102
|
cmd.on('close', async (code) => {
|
|
100
103
|
const emoji = code === 0 ? '🟢' : '🔴';
|
|
101
104
|
console.log(constants_js_1.APP_PREFIX, emoji, `Runner exited with ${picocolors_1.default.bold(code)}`);
|
|
102
105
|
if (apiKey) {
|
|
103
106
|
const status = code === 0 ? 'passed' : 'failed';
|
|
104
|
-
await client.updateRunStatus(status
|
|
107
|
+
await client.updateRunStatus(status);
|
|
105
108
|
}
|
|
106
109
|
process.exit(code);
|
|
107
110
|
});
|
|
@@ -257,13 +260,13 @@ program
|
|
|
257
260
|
const replayService = new replay_js_1.default({
|
|
258
261
|
apiKey: config_js_1.config.TESTOMATIO,
|
|
259
262
|
dryRun: opts.dryRun,
|
|
260
|
-
onLog:
|
|
261
|
-
onError:
|
|
263
|
+
onLog: message => console.log(constants_js_1.APP_PREFIX, message),
|
|
264
|
+
onError: message => console.error(constants_js_1.APP_PREFIX, '⚠️ ', message),
|
|
262
265
|
onProgress: ({ current, total }) => {
|
|
263
266
|
if (current % 10 === 0 || current === total) {
|
|
264
267
|
console.log(constants_js_1.APP_PREFIX, `📊 Progress: ${current}/${total} tests processed`);
|
|
265
268
|
}
|
|
266
|
-
}
|
|
269
|
+
},
|
|
267
270
|
});
|
|
268
271
|
const result = await replayService.replay(debugFile);
|
|
269
272
|
if (result.dryRun) {
|
package/lib/client.d.ts
CHANGED
|
@@ -58,10 +58,9 @@ export class Client {
|
|
|
58
58
|
* Updates the status of the current test run and finishes the run.
|
|
59
59
|
* @param {'passed' | 'failed' | 'skipped' | 'finished'} status - The status of the current test run.
|
|
60
60
|
* Must be one of "passed", "failed", or "finished"
|
|
61
|
-
* @param {boolean} [isParallel] - Whether the current test run was executed in parallel with other tests.
|
|
62
61
|
* @returns {Promise<any>} - A Promise that resolves when finishes the run.
|
|
63
62
|
*/
|
|
64
|
-
updateRunStatus(status: "passed" | "failed" | "skipped" | "finished"
|
|
63
|
+
updateRunStatus(status: "passed" | "failed" | "skipped" | "finished"): Promise<any>;
|
|
65
64
|
/**
|
|
66
65
|
* Returns the formatted stack including the stack trace, steps, and logs.
|
|
67
66
|
* @returns {string}
|
package/lib/client.js
CHANGED
|
@@ -294,17 +294,16 @@ class Client {
|
|
|
294
294
|
* Updates the status of the current test run and finishes the run.
|
|
295
295
|
* @param {'passed' | 'failed' | 'skipped' | 'finished'} status - The status of the current test run.
|
|
296
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
297
|
* @returns {Promise<any>} - A Promise that resolves when finishes the run.
|
|
299
298
|
*/
|
|
300
|
-
async updateRunStatus(status
|
|
299
|
+
async updateRunStatus(status) {
|
|
301
300
|
this.pipes ||= await (0, index_js_1.pipesFactory)(this.paramsForPipesFactory || {}, this.pipeStore);
|
|
302
301
|
this.runId ||= (0, utils_js_1.readLatestRunId)();
|
|
303
302
|
debug('Updating run status...');
|
|
304
303
|
// all pipes disabled, skipping
|
|
305
304
|
if (!this.pipes?.filter(p => p.isEnabled).length)
|
|
306
305
|
return Promise.resolve();
|
|
307
|
-
const runParams = { status
|
|
306
|
+
const runParams = { status };
|
|
308
307
|
this.queue = this.queue
|
|
309
308
|
.then(() => Promise.all(this.pipes.map(p => p.finishRun(runParams))))
|
|
310
309
|
.then(() => {
|
package/lib/pipe/testomatio.d.ts
CHANGED
package/lib/pipe/testomatio.js
CHANGED
|
@@ -43,7 +43,6 @@ class TestomatioPipe {
|
|
|
43
43
|
debug('Testomatio Pipe: Enabled');
|
|
44
44
|
const proxyUrl = process.env.HTTP_PROXY || process.env.HTTPS_PROXY;
|
|
45
45
|
const proxy = proxyUrl ? new URL(proxyUrl) : null;
|
|
46
|
-
this.parallel = params.parallel;
|
|
47
46
|
this.store = store || {};
|
|
48
47
|
this.title = params.title || process.env.TESTOMATIO_TITLE;
|
|
49
48
|
this.sharedRun = !!process.env.TESTOMATIO_SHARED_RUN;
|
|
@@ -154,7 +153,6 @@ class TestomatioPipe {
|
|
|
154
153
|
const accessEvent = process.env.TESTOMATIO_PUBLISH ? 'publish' : null;
|
|
155
154
|
const runParams = Object.fromEntries(Object.entries({
|
|
156
155
|
ci_build_url: buildUrl,
|
|
157
|
-
parallel: this.parallel,
|
|
158
156
|
api_key: this.apiKey.trim(),
|
|
159
157
|
group_title: this.groupTitle,
|
|
160
158
|
access_event: accessEvent,
|
|
@@ -377,7 +375,7 @@ class TestomatioPipe {
|
|
|
377
375
|
const errorMessage = picocolors_1.default.red(`⚠️ Due to request failures, ${this.notReportedTestsCount} test(s) were not reported to Testomat.io`);
|
|
378
376
|
console.warn(`${constants_js_1.APP_PREFIX} ${errorMessage}`);
|
|
379
377
|
}
|
|
380
|
-
const { status
|
|
378
|
+
const { status } = params;
|
|
381
379
|
let status_event;
|
|
382
380
|
if (status === constants_js_1.STATUS.FINISHED)
|
|
383
381
|
status_event = 'finish';
|
|
@@ -385,8 +383,6 @@ class TestomatioPipe {
|
|
|
385
383
|
status_event = 'pass';
|
|
386
384
|
if (status === constants_js_1.STATUS.FAILED)
|
|
387
385
|
status_event = 'fail';
|
|
388
|
-
if (parallel)
|
|
389
|
-
status_event += '_parallel';
|
|
390
386
|
try {
|
|
391
387
|
if (this.runId && !this.proceed) {
|
|
392
388
|
await this.client.request({
|
package/lib/replay.js
CHANGED
|
@@ -238,7 +238,7 @@ class Replay {
|
|
|
238
238
|
});
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
|
-
await client.updateRunStatus(finishParams.status || constants_js_1.STATUS.FINISHED
|
|
241
|
+
await client.updateRunStatus(finishParams.status || constants_js_1.STATUS.FINISHED);
|
|
242
242
|
const result = {
|
|
243
243
|
success: true,
|
|
244
244
|
testsCount: tests.length,
|
package/package.json
CHANGED
package/src/adapter/webdriver.js
CHANGED
|
@@ -3,6 +3,7 @@ import TestomatClient from '../client.js';
|
|
|
3
3
|
import { getTestomatIdFromTestTitle, fileSystem } from '../utils/utils.js';
|
|
4
4
|
import { services } from '../services/index.js';
|
|
5
5
|
import { TESTOMAT_TMP_STORAGE_DIR } from '../constants.js';
|
|
6
|
+
import { stringToMD5Hash } from '../data-storage.js';
|
|
6
7
|
|
|
7
8
|
class WebdriverReporter extends WDIOReporter {
|
|
8
9
|
constructor(options) {
|
|
@@ -52,9 +53,7 @@ class WebdriverReporter extends WDIOReporter {
|
|
|
52
53
|
onTestEnd(test) {
|
|
53
54
|
test.suite = test.parent;
|
|
54
55
|
const logs = getTestLogs(test.fullTitle);
|
|
55
|
-
//
|
|
56
|
-
// ^ not reproduced anymore (Jul 2025)
|
|
57
|
-
// but still be under investigation
|
|
56
|
+
// still be under investigation
|
|
58
57
|
const artifacts = services.artifacts.get(test.fullTitle);
|
|
59
58
|
const keyValues = services.keyValues.get(test.fullTitle);
|
|
60
59
|
test.logs = logs;
|
|
@@ -83,8 +82,10 @@ class WebdriverReporter extends WDIOReporter {
|
|
|
83
82
|
.filter(el => el.endpoint === screenshotEndpoint && el.result && el.result.value)
|
|
84
83
|
.map(el => Buffer.from(el.result.value, 'base64'));
|
|
85
84
|
|
|
85
|
+
const rid = stringToMD5Hash(test.fullTitle);
|
|
86
|
+
|
|
86
87
|
await this.client.addTestRun(state, {
|
|
87
|
-
rid
|
|
88
|
+
rid,
|
|
88
89
|
manuallyAttachedArtifacts: test.artifacts,
|
|
89
90
|
error,
|
|
90
91
|
logs: test.logs,
|
package/src/bin/cli.js
CHANGED
|
@@ -85,7 +85,7 @@ program
|
|
|
85
85
|
return process.exit(255);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
const client = new TestomatClient({ apiKey, title
|
|
88
|
+
const client = new TestomatClient({ apiKey, title });
|
|
89
89
|
|
|
90
90
|
if (opts.filter) {
|
|
91
91
|
const [pipe, ...optsArray] = opts.filter.split(':');
|
|
@@ -105,14 +105,17 @@ program
|
|
|
105
105
|
|
|
106
106
|
const runTests = async () => {
|
|
107
107
|
const testCmds = command.split(' ');
|
|
108
|
-
const cmd = spawn(testCmds[0], testCmds.slice(1), {
|
|
108
|
+
const cmd = spawn(testCmds[0], testCmds.slice(1), {
|
|
109
|
+
stdio: 'inherit',
|
|
110
|
+
env: { ...process.env, TESTOMATIO_PROCEED: 'true', runId: client.runId },
|
|
111
|
+
});
|
|
109
112
|
|
|
110
113
|
cmd.on('close', async code => {
|
|
111
114
|
const emoji = code === 0 ? '🟢' : '🔴';
|
|
112
115
|
console.log(APP_PREFIX, emoji, `Runner exited with ${pc.bold(code)}`);
|
|
113
116
|
if (apiKey) {
|
|
114
117
|
const status = code === 0 ? 'passed' : 'failed';
|
|
115
|
-
await client.updateRunStatus(status
|
|
118
|
+
await client.updateRunStatus(status);
|
|
116
119
|
}
|
|
117
120
|
process.exit(code);
|
|
118
121
|
});
|
|
@@ -310,13 +313,13 @@ program
|
|
|
310
313
|
const replayService = new Replay({
|
|
311
314
|
apiKey: config.TESTOMATIO,
|
|
312
315
|
dryRun: opts.dryRun,
|
|
313
|
-
onLog:
|
|
314
|
-
onError:
|
|
316
|
+
onLog: message => console.log(APP_PREFIX, message),
|
|
317
|
+
onError: message => console.error(APP_PREFIX, '⚠️ ', message),
|
|
315
318
|
onProgress: ({ current, total }) => {
|
|
316
319
|
if (current % 10 === 0 || current === total) {
|
|
317
320
|
console.log(APP_PREFIX, `📊 Progress: ${current}/${total} tests processed`);
|
|
318
321
|
}
|
|
319
|
-
}
|
|
322
|
+
},
|
|
320
323
|
});
|
|
321
324
|
|
|
322
325
|
const result = await replayService.replay(debugFile);
|
package/src/client.js
CHANGED
|
@@ -312,10 +312,9 @@ class Client {
|
|
|
312
312
|
* Updates the status of the current test run and finishes the run.
|
|
313
313
|
* @param {'passed' | 'failed' | 'skipped' | 'finished'} status - The status of the current test run.
|
|
314
314
|
* Must be one of "passed", "failed", or "finished"
|
|
315
|
-
* @param {boolean} [isParallel] - Whether the current test run was executed in parallel with other tests.
|
|
316
315
|
* @returns {Promise<any>} - A Promise that resolves when finishes the run.
|
|
317
316
|
*/
|
|
318
|
-
async updateRunStatus(status
|
|
317
|
+
async updateRunStatus(status) {
|
|
319
318
|
this.pipes ||= await pipesFactory(this.paramsForPipesFactory || {}, this.pipeStore);
|
|
320
319
|
this.runId ||= readLatestRunId();
|
|
321
320
|
|
|
@@ -323,7 +322,7 @@ class Client {
|
|
|
323
322
|
// all pipes disabled, skipping
|
|
324
323
|
if (!this.pipes?.filter(p => p.isEnabled).length) return Promise.resolve();
|
|
325
324
|
|
|
326
|
-
const runParams = { status
|
|
325
|
+
const runParams = { status };
|
|
327
326
|
|
|
328
327
|
this.queue = this.queue
|
|
329
328
|
.then(() => Promise.all(this.pipes.map(p => p.finishRun(runParams))))
|
package/src/pipe/testomatio.js
CHANGED
|
@@ -43,7 +43,6 @@ class TestomatioPipe {
|
|
|
43
43
|
const proxyUrl = process.env.HTTP_PROXY || process.env.HTTPS_PROXY;
|
|
44
44
|
const proxy = proxyUrl ? new URL(proxyUrl) : null;
|
|
45
45
|
|
|
46
|
-
this.parallel = params.parallel;
|
|
47
46
|
this.store = store || {};
|
|
48
47
|
this.title = params.title || process.env.TESTOMATIO_TITLE;
|
|
49
48
|
this.sharedRun = !!process.env.TESTOMATIO_SHARED_RUN;
|
|
@@ -167,7 +166,6 @@ class TestomatioPipe {
|
|
|
167
166
|
const runParams = Object.fromEntries(
|
|
168
167
|
Object.entries({
|
|
169
168
|
ci_build_url: buildUrl,
|
|
170
|
-
parallel: this.parallel,
|
|
171
169
|
api_key: this.apiKey.trim(),
|
|
172
170
|
group_title: this.groupTitle,
|
|
173
171
|
access_event: accessEvent,
|
|
@@ -419,14 +417,13 @@ class TestomatioPipe {
|
|
|
419
417
|
console.warn(`${APP_PREFIX} ${errorMessage}`);
|
|
420
418
|
}
|
|
421
419
|
|
|
422
|
-
const { status
|
|
420
|
+
const { status } = params;
|
|
423
421
|
|
|
424
422
|
let status_event;
|
|
425
423
|
|
|
426
424
|
if (status === STATUS.FINISHED) status_event = 'finish';
|
|
427
425
|
if (status === STATUS.PASSED) status_event = 'pass';
|
|
428
426
|
if (status === STATUS.FAILED) status_event = 'fail';
|
|
429
|
-
if (parallel) status_event += '_parallel';
|
|
430
427
|
|
|
431
428
|
try {
|
|
432
429
|
if (this.runId && !this.proceed) {
|
package/src/replay.js
CHANGED
|
@@ -246,7 +246,7 @@ export class Replay {
|
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
-
await client.updateRunStatus(finishParams.status || STATUS.FINISHED
|
|
249
|
+
await client.updateRunStatus(finishParams.status || STATUS.FINISHED);
|
|
250
250
|
|
|
251
251
|
const result = {
|
|
252
252
|
success: true,
|