@testomatio/reporter 0.4.4 → 0.5.0-beta.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/.eslintrc.js +18 -22
- package/.github/workflows/node.js.yml +2 -1
- package/.prettierrc.js +12 -0
- package/Changelog.md +24 -15
- package/README.md +122 -93
- package/example/codecept/codecept.conf.js +7 -7
- package/example/codecept/index_test.js +8 -8
- package/example/codecept/sample_test.js +4 -4
- package/example/codecept/steps.d.ts +1 -1
- package/example/codecept/steps_file.js +4 -2
- package/example/core/index.js +6 -6
- package/example/jest/index.test.js +3 -3
- package/example/jest/jest.config.js +1 -1
- package/example/jest/sample.test.js +4 -4
- package/example/mocha/test/index.test.js +5 -5
- package/lib/adapter/codecept.js +73 -70
- package/lib/adapter/cucumber.js +35 -52
- package/lib/adapter/cypress-plugin/index.js +44 -0
- package/lib/adapter/jasmine.js +15 -6
- package/lib/adapter/jest.js +9 -10
- package/lib/adapter/mocha.js +17 -14
- package/lib/adapter/playwright.js +26 -25
- package/lib/adapter/webdriver.js +3 -3
- package/lib/bin/startTest.js +56 -60
- package/lib/client.js +61 -112
- package/lib/constants.js +6 -6
- package/lib/fileUploader.js +44 -16
- package/lib/output.js +6 -8
- package/lib/reporter.js +2 -2
- package/lib/util.js +18 -5
- package/package.json +27 -15
- package/testcafe/index.js +11 -14
- package/tests/adapter/config/index.js +10 -0
- package/tests/adapter/examples/codecept/codecept.conf.js +33 -0
- package/tests/adapter/examples/codecept/index_test.js +11 -0
- package/tests/adapter/examples/codecept/jsconfig.json +5 -0
- package/tests/adapter/examples/codecept/output/Test_for_suite_2_@Tc2171bd2.failed.png +0 -0
- package/tests/adapter/examples/codecept/output/Test_issue_for_suite_1_@Tca70c8c4.failed.png +0 -0
- package/tests/adapter/examples/codecept/sample_test.js +7 -0
- package/tests/adapter/examples/codecept/steps_file.js +10 -0
- package/tests/adapter/examples/jasmine/index.test.js +11 -0
- package/tests/adapter/examples/jasmine/passReporterOpts.sh +8 -0
- package/tests/adapter/examples/jest/index.test.js +11 -0
- package/tests/adapter/examples/jest/jest.config.js +4 -0
- package/tests/adapter/examples/mocha/index.test.js +13 -0
- package/tests/adapter/examples/mocha/mocha.config.js +4 -0
- package/tests/adapter/index.test.js +136 -0
- package/tests/adapter/utils/index.js +40 -0
- package/.prettierrc.json +0 -1
package/lib/adapter/mocha.js
CHANGED
|
@@ -1,27 +1,30 @@
|
|
|
1
|
-
const
|
|
2
|
-
const TestomatClient = require(
|
|
3
|
-
const TRConstants = require(
|
|
4
|
-
const { parseTest } = require(
|
|
1
|
+
const Mocha = require('mocha');
|
|
2
|
+
const TestomatClient = require('../client');
|
|
3
|
+
const TRConstants = require('../constants');
|
|
4
|
+
const { parseTest } = require('../util');
|
|
5
|
+
|
|
6
|
+
const { EVENT_RUN_BEGIN, EVENT_RUN_END, EVENT_TEST_FAIL, EVENT_TEST_PASS } = Mocha.Runner.constants;
|
|
5
7
|
|
|
6
8
|
function MochaReporter(runner, opts) {
|
|
7
|
-
|
|
9
|
+
Mocha.reporters.Base.call(this, runner);
|
|
8
10
|
let passes = 0;
|
|
9
11
|
let failures = 0;
|
|
10
12
|
|
|
11
13
|
const { apiKey } = opts.reporterOptions;
|
|
14
|
+
|
|
12
15
|
if (!apiKey) {
|
|
13
|
-
console.log(
|
|
16
|
+
console.log('TESTOMATIO key is empty, ignoring reports');
|
|
14
17
|
return;
|
|
15
18
|
}
|
|
16
19
|
const client = new TestomatClient({ apiKey });
|
|
17
20
|
|
|
18
|
-
runner.on(
|
|
21
|
+
runner.on(EVENT_RUN_BEGIN, () => {
|
|
19
22
|
client.createRun();
|
|
20
23
|
});
|
|
21
24
|
|
|
22
|
-
runner.on(
|
|
25
|
+
runner.on(EVENT_TEST_PASS, test => {
|
|
23
26
|
passes += 1;
|
|
24
|
-
console.log(
|
|
27
|
+
console.log('pass: %s', test.fullTitle());
|
|
25
28
|
const testId = parseTest(test.title);
|
|
26
29
|
client.addTestRun(testId, TRConstants.PASSED, {
|
|
27
30
|
title: test.title,
|
|
@@ -29,9 +32,9 @@ function MochaReporter(runner, opts) {
|
|
|
29
32
|
});
|
|
30
33
|
});
|
|
31
34
|
|
|
32
|
-
runner.on(
|
|
35
|
+
runner.on(EVENT_TEST_FAIL, (test, err) => {
|
|
33
36
|
failures += 1;
|
|
34
|
-
console.log(
|
|
37
|
+
console.log('fail: %s -- error: %s', test.fullTitle(), err.message);
|
|
35
38
|
const testId = parseTest(test.title);
|
|
36
39
|
client.addTestRun(testId, TRConstants.FAILED, {
|
|
37
40
|
error: err,
|
|
@@ -40,14 +43,14 @@ function MochaReporter(runner, opts) {
|
|
|
40
43
|
});
|
|
41
44
|
});
|
|
42
45
|
|
|
43
|
-
runner.on(
|
|
44
|
-
console.log(
|
|
46
|
+
runner.on(EVENT_RUN_END, () => {
|
|
47
|
+
console.log('end: %d/%d', passes, passes + failures);
|
|
45
48
|
const status = failures === 0 ? TRConstants.PASSED : TRConstants.FAILED;
|
|
46
49
|
client.updateRunStatus(status);
|
|
47
50
|
});
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
// To have this reporter "extend" a built-in reporter uncomment the following line:
|
|
51
|
-
|
|
54
|
+
Mocha.utils.inherits(MochaReporter, Mocha.reporters.Spec);
|
|
52
55
|
|
|
53
56
|
module.exports = MochaReporter;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
const chalk = require(
|
|
1
|
+
const chalk = require('chalk');
|
|
2
2
|
const crypto = require('crypto');
|
|
3
3
|
const os = require('os');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const Status = require('../constants');
|
|
7
|
-
const TestomatioClient = require(
|
|
7
|
+
const TestomatioClient = require('../client');
|
|
8
|
+
const upload = require('../fileUploader');
|
|
8
9
|
const { parseTest } = require('../util');
|
|
9
10
|
|
|
10
11
|
class TestomatioReporter {
|
|
11
|
-
|
|
12
12
|
constructor(config = {}) {
|
|
13
13
|
const { apiKey } = config;
|
|
14
14
|
|
|
@@ -21,7 +21,7 @@ class TestomatioReporter {
|
|
|
21
21
|
this.videos = [];
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
onBegin(
|
|
24
|
+
onBegin(_config, suite) {
|
|
25
25
|
if (!this.client) return;
|
|
26
26
|
this.suite = suite;
|
|
27
27
|
this.client.createRun();
|
|
@@ -37,7 +37,7 @@ class TestomatioReporter {
|
|
|
37
37
|
|
|
38
38
|
const suite_title = test.parent ? test.parent.title : null;
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
const steps = [];
|
|
41
41
|
for (const step of result.steps) {
|
|
42
42
|
appendStep(step, steps);
|
|
43
43
|
}
|
|
@@ -75,18 +75,20 @@ class TestomatioReporter {
|
|
|
75
75
|
async onEnd(result) {
|
|
76
76
|
if (!this.client) return;
|
|
77
77
|
|
|
78
|
-
if (this.videos.length) {
|
|
78
|
+
if (this.videos.length && upload.isEnabled()) {
|
|
79
79
|
console.log(Status.APP_PREFIX, `🎞️ Uploading ${this.videos.length} videos...`);
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
const promises = [];
|
|
82
82
|
for (const video of this.videos) {
|
|
83
83
|
const { testId, title, attachment, suite_title } = video;
|
|
84
|
-
const file =
|
|
85
|
-
promises.push(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
84
|
+
const file = { path: attachment.path, title, type: attachment.contentType };
|
|
85
|
+
promises.push(
|
|
86
|
+
this.client.addTestRun(testId, undefined, {
|
|
87
|
+
title,
|
|
88
|
+
suite_title,
|
|
89
|
+
files: [file],
|
|
90
|
+
}),
|
|
91
|
+
);
|
|
90
92
|
}
|
|
91
93
|
await Promise.all(promises);
|
|
92
94
|
}
|
|
@@ -96,25 +98,24 @@ class TestomatioReporter {
|
|
|
96
98
|
}
|
|
97
99
|
|
|
98
100
|
function checkStatus(status) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return Status.PASSED;
|
|
107
|
-
}
|
|
108
|
-
return Status.FAILED;
|
|
101
|
+
return (
|
|
102
|
+
{
|
|
103
|
+
skipped: Status.SKIPPED,
|
|
104
|
+
timedOut: Status.FAILED,
|
|
105
|
+
passed: Status.PASSED,
|
|
106
|
+
}[status] || Status.FAILED
|
|
107
|
+
);
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
function appendStep(step, steps = [], shift = 0) {
|
|
112
111
|
const prefix = ' '.repeat(shift);
|
|
112
|
+
|
|
113
113
|
if (step.error) {
|
|
114
|
-
steps.push(`${prefix}${chalk.red(step.title)} ${chalk.gray(`${step.duration}ms`)}`)
|
|
114
|
+
steps.push(`${prefix}${chalk.red(step.title)} ${chalk.gray(`${step.duration}ms`)}`);
|
|
115
115
|
} else {
|
|
116
|
-
steps.push(`${prefix}${step.title} ${chalk.gray(`${step.duration}ms`)}`)
|
|
116
|
+
steps.push(`${prefix}${step.title} ${chalk.gray(`${step.duration}ms`)}`);
|
|
117
117
|
}
|
|
118
|
+
|
|
118
119
|
for (const child of step.steps || []) {
|
|
119
120
|
appendStep(child, steps, shift + 2);
|
|
120
121
|
}
|
package/lib/adapter/webdriver.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const WDIOReporter = require(
|
|
2
|
-
const TestomatClient = require(
|
|
3
|
-
const { parseTest } = require(
|
|
1
|
+
const WDIOReporter = require('@wdio/reporter').default;
|
|
2
|
+
const TestomatClient = require('../client');
|
|
3
|
+
const { parseTest } = require('../util');
|
|
4
4
|
|
|
5
5
|
class WebdriverReporter extends WDIOReporter {
|
|
6
6
|
constructor(options) {
|
package/lib/bin/startTest.js
CHANGED
|
@@ -1,86 +1,82 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const { spawn } = require(
|
|
3
|
-
const program = require(
|
|
4
|
-
const chalk = require(
|
|
5
|
-
const TestomatClient = require(
|
|
6
|
-
const { APP_PREFIX, FINISHED } = require(
|
|
2
|
+
const { spawn } = require('child_process');
|
|
3
|
+
const program = require('commander');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const TestomatClient = require('../client');
|
|
6
|
+
const { APP_PREFIX, FINISHED } = require('../constants');
|
|
7
7
|
|
|
8
|
-
const apiKey = process.env[
|
|
8
|
+
const apiKey = process.env['INPUT_TESTOMATIO-KEY'] || process.env.TESTOMATIO;
|
|
9
9
|
const title = process.env.TESTOMATIO_TITLE;
|
|
10
10
|
|
|
11
11
|
program
|
|
12
|
-
.option(
|
|
12
|
+
.option('-c, --command <cmd>', 'Test runner command')
|
|
13
13
|
.option('--launch', 'Start a new run and return its ID')
|
|
14
14
|
.option('--finish', 'Finish Run by its ID')
|
|
15
|
-
.action(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (finish) {
|
|
30
|
-
if (!process.env.TESTOMATIO_RUN) {
|
|
31
|
-
console.log('TESTOMATIO_RUN environment variable must be set.');
|
|
32
|
-
return process.exit(1);
|
|
15
|
+
.action(opts => {
|
|
16
|
+
const { command, launch, finish } = opts;
|
|
17
|
+
|
|
18
|
+
if (launch) {
|
|
19
|
+
console.log('Starting a new Run on Testomat.io...');
|
|
20
|
+
const client = new TestomatClient({ apiKey });
|
|
21
|
+
|
|
22
|
+
client.createRun().then(() => {
|
|
23
|
+
console.log(process.env.runId);
|
|
24
|
+
process.exit(0);
|
|
25
|
+
});
|
|
26
|
+
return;
|
|
33
27
|
}
|
|
34
28
|
|
|
35
|
-
|
|
29
|
+
if (finish) {
|
|
30
|
+
if (!process.env.TESTOMATIO_RUN) {
|
|
31
|
+
console.log('TESTOMATIO_RUN environment variable must be set.');
|
|
32
|
+
return process.exit(1);
|
|
33
|
+
}
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
console.log('Finishing Run on Testomat.io...');
|
|
38
36
|
|
|
39
|
-
|
|
40
|
-
console.log(chalk.yellow(`Run ${process.env.TESTOMATIO_RUN} was finished`));
|
|
41
|
-
process.exit(0);
|
|
42
|
-
});
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
37
|
+
const client = new TestomatClient({ apiKey });
|
|
45
38
|
|
|
46
|
-
|
|
39
|
+
client.updateRunStatus(FINISHED, true).then(() => {
|
|
40
|
+
console.log(chalk.yellow(`Run ${process.env.TESTOMATIO_RUN} was finished`));
|
|
41
|
+
process.exit(0);
|
|
42
|
+
});
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
47
45
|
|
|
48
|
-
|
|
49
|
-
console.log(APP_PREFIX, `🚀 Running`, chalk.green(command));
|
|
46
|
+
let exitCode = 0;
|
|
50
47
|
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
const testCmds = command.split(' ');
|
|
49
|
+
console.log(APP_PREFIX, `🚀 Running`, chalk.green(command));
|
|
53
50
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
APP_PREFIX,
|
|
57
|
-
"⚠️ ",
|
|
58
|
-
`Runner exited with ${chalk.bold(code)}, report is ignored`
|
|
59
|
-
);
|
|
51
|
+
if (!apiKey) {
|
|
52
|
+
const cmd = spawn(testCmds[0], testCmds.slice(1), { stdio: 'inherit' });
|
|
60
53
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
cmd.on('close', code => {
|
|
55
|
+
console.log(APP_PREFIX, '⚠️ ', `Runner exited with ${chalk.bold(code)}, report is ignored`);
|
|
56
|
+
|
|
57
|
+
if (code > exitCode) exitCode = code;
|
|
58
|
+
process.exitCode = exitCode;
|
|
59
|
+
});
|
|
64
60
|
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
67
63
|
|
|
68
|
-
|
|
64
|
+
const client = new TestomatClient({ apiKey, title, parallel: true });
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
client.createRun().then(() => {
|
|
67
|
+
const cmd = spawn(testCmds[0], testCmds.slice(1), { stdio: 'inherit' });
|
|
72
68
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
cmd.on('close', code => {
|
|
70
|
+
const emoji = code === 0 ? '🟢' : '🔴';
|
|
71
|
+
console.log(APP_PREFIX, emoji, `Runner exited with ${chalk.bold(code)}`);
|
|
72
|
+
const status = code === 0 ? 'passed' : 'failed';
|
|
73
|
+
client.updateRunStatus(status, true);
|
|
78
74
|
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
if (code > exitCode) exitCode = code;
|
|
76
|
+
process.exitCode = exitCode;
|
|
77
|
+
});
|
|
81
78
|
});
|
|
82
79
|
});
|
|
83
|
-
});
|
|
84
80
|
|
|
85
81
|
if (process.argv.length <= 2) {
|
|
86
82
|
program.outputHelp();
|
package/lib/client.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
const axios = require(
|
|
2
|
-
const JsonCycle = require(
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const {
|
|
9
|
-
const { PASSED, FAILED, FINISHED, APP_PREFIX } = require(
|
|
10
|
-
|
|
11
|
-
const TESTOMAT_URL = process.env.TESTOMATIO_URL ||
|
|
12
|
-
const { TESTOMATIO_RUNGROUP_TITLE, TESTOMATIO_ENV, TESTOMATIO_RUN } =
|
|
13
|
-
process.env;
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const JsonCycle = require('json-cycle');
|
|
3
|
+
const createCallsiteRecord = require('callsite-record');
|
|
4
|
+
const { sep, join } = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const chalk = require('chalk');
|
|
7
|
+
const upload = require('./fileUploader');
|
|
8
|
+
const { isValidUrl } = require('./util');
|
|
9
|
+
const { PASSED, FAILED, FINISHED, APP_PREFIX } = require('./constants');
|
|
10
|
+
|
|
11
|
+
const TESTOMAT_URL = process.env.TESTOMATIO_URL || 'https://app.testomat.io';
|
|
12
|
+
const { TESTOMATIO_RUNGROUP_TITLE, TESTOMATIO_ENV, TESTOMATIO_RUN } = process.env;
|
|
14
13
|
|
|
15
14
|
if (TESTOMATIO_RUN) {
|
|
16
15
|
process.env.runId = TESTOMATIO_RUN;
|
|
@@ -54,44 +53,28 @@ class TestomatClient {
|
|
|
54
53
|
if (!isValidUrl(TESTOMAT_URL.trim())) {
|
|
55
54
|
console.log(
|
|
56
55
|
APP_PREFIX,
|
|
57
|
-
chalk.red(
|
|
58
|
-
`Error creating report on Testomat.io, report url '${TESTOMAT_URL}' is invalid`
|
|
59
|
-
)
|
|
56
|
+
chalk.red(`Error creating report on Testomat.io, report url '${TESTOMAT_URL}' is invalid`),
|
|
60
57
|
);
|
|
61
58
|
return;
|
|
62
59
|
}
|
|
63
60
|
|
|
64
61
|
if (runId) {
|
|
65
62
|
this.runId = runId;
|
|
66
|
-
this.queue = this.queue.then(() =>
|
|
67
|
-
axios.put(`${TESTOMAT_URL.trim()}/api/reporter/${runId}`, runParams)
|
|
68
|
-
);
|
|
63
|
+
this.queue = this.queue.then(() => axios.put(`${TESTOMAT_URL.trim()}/api/reporter/${runId}`, runParams));
|
|
69
64
|
return Promise.resolve(runId);
|
|
70
65
|
}
|
|
71
66
|
|
|
72
67
|
this.queue = this.queue
|
|
73
|
-
.then(() =>
|
|
74
|
-
this.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
.split("/")
|
|
80
|
-
.splice(3)
|
|
81
|
-
.join("/")}`;
|
|
82
|
-
console.log(
|
|
83
|
-
APP_PREFIX,
|
|
84
|
-
"📊 Report created. Report ID:",
|
|
85
|
-
this.runId,
|
|
86
|
-
chalk.gray(`v${this.version}`)
|
|
87
|
-
);
|
|
88
|
-
process.env.runId = this.runId;
|
|
89
|
-
})
|
|
90
|
-
)
|
|
68
|
+
.then(() => this.axios.post(`${TESTOMAT_URL.trim()}/api/reporter`, runParams).then(resp => {
|
|
69
|
+
this.runId = resp.data.uid;
|
|
70
|
+
this.runUrl = `${TESTOMAT_URL}/${resp.data.url.split('/').splice(3).join('/')}`;
|
|
71
|
+
console.log(APP_PREFIX, '📊 Report created. Report ID:', this.runId, chalk.gray(`v${this.version}`));
|
|
72
|
+
process.env.runId = this.runId;
|
|
73
|
+
}))
|
|
91
74
|
.catch(() => {
|
|
92
75
|
console.log(
|
|
93
76
|
APP_PREFIX,
|
|
94
|
-
|
|
77
|
+
'Error creating report Testomat.io, please check if your API key is valid. Skipping report',
|
|
95
78
|
);
|
|
96
79
|
});
|
|
97
80
|
|
|
@@ -104,10 +87,9 @@ class TestomatClient {
|
|
|
104
87
|
* @returns {Promise}
|
|
105
88
|
*/
|
|
106
89
|
async addTestRun(testId, status, testData = {}) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
time = "",
|
|
90
|
+
const {
|
|
91
|
+
error = '',
|
|
92
|
+
time = '',
|
|
111
93
|
example = null,
|
|
112
94
|
files = [],
|
|
113
95
|
steps,
|
|
@@ -116,15 +98,17 @@ class TestomatClient {
|
|
|
116
98
|
suite_id,
|
|
117
99
|
test_id,
|
|
118
100
|
} = testData;
|
|
101
|
+
let { message = '' } = testData;
|
|
119
102
|
|
|
120
103
|
const uploadedFiles = [];
|
|
121
104
|
|
|
122
105
|
if (testId) testData.test_id = testId;
|
|
123
106
|
|
|
124
|
-
let stack =
|
|
107
|
+
let stack = '';
|
|
125
108
|
|
|
126
109
|
if (error) {
|
|
127
110
|
stack = this.formatError(error);
|
|
111
|
+
message = error.message;
|
|
128
112
|
}
|
|
129
113
|
if (steps) {
|
|
130
114
|
stack = this.formatSteps(stack, steps);
|
|
@@ -137,7 +121,7 @@ class TestomatClient {
|
|
|
137
121
|
}
|
|
138
122
|
|
|
139
123
|
for (const file of files) {
|
|
140
|
-
uploadedFiles.push(uploadFile(file, this.runId));
|
|
124
|
+
uploadedFiles.push(upload.uploadFile(file, this.runId));
|
|
141
125
|
}
|
|
142
126
|
}
|
|
143
127
|
|
|
@@ -147,7 +131,7 @@ class TestomatClient {
|
|
|
147
131
|
|
|
148
132
|
global.testomatioArtifacts = [];
|
|
149
133
|
|
|
150
|
-
this.totalUploaded += uploadedFiles.filter(
|
|
134
|
+
this.totalUploaded += uploadedFiles.filter(n => n).length;
|
|
151
135
|
|
|
152
136
|
const json = JsonCycle.stringify({
|
|
153
137
|
api_key: this.apiKey,
|
|
@@ -164,42 +148,29 @@ class TestomatClient {
|
|
|
164
148
|
run_time: time,
|
|
165
149
|
artifacts: await Promise.all(uploadedFiles),
|
|
166
150
|
});
|
|
167
|
-
return this.axios.post(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
{
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
"Content-Type": "application/json",
|
|
176
|
-
},
|
|
177
|
-
}
|
|
178
|
-
);
|
|
151
|
+
return this.axios.post(`${TESTOMAT_URL}/api/reporter/${this.runId}/testrun`, json, {
|
|
152
|
+
maxContentLength: Infinity,
|
|
153
|
+
maxBodyLength: Infinity,
|
|
154
|
+
headers: {
|
|
155
|
+
// Overwrite Axios's automatically set Content-Type
|
|
156
|
+
'Content-Type': 'application/json',
|
|
157
|
+
},
|
|
158
|
+
});
|
|
179
159
|
})
|
|
180
|
-
.catch(
|
|
160
|
+
.catch(err => {
|
|
181
161
|
if (err.response) {
|
|
182
162
|
if (err.response.status >= 400) {
|
|
183
|
-
const data = err.response.data || { message:
|
|
163
|
+
const data = err.response.data || { message: '' };
|
|
184
164
|
console.log(
|
|
185
165
|
APP_PREFIX,
|
|
186
166
|
chalk.blue(title),
|
|
187
|
-
`Report couldn't be processed: (${err.response.status}) ${data.message}
|
|
167
|
+
`Report couldn't be processed: (${err.response.status}) ${data.message}`,
|
|
188
168
|
);
|
|
189
169
|
return;
|
|
190
170
|
}
|
|
191
|
-
console.log(
|
|
192
|
-
APP_PREFIX,
|
|
193
|
-
chalk.blue(title),
|
|
194
|
-
`Report couldn't be processed: ${err.response.data.message}`
|
|
195
|
-
);
|
|
171
|
+
console.log(APP_PREFIX, chalk.blue(title), `Report couldn't be processed: ${err.response.data.message}`);
|
|
196
172
|
} else {
|
|
197
|
-
console.log(
|
|
198
|
-
APP_PREFIX,
|
|
199
|
-
chalk.blue(title),
|
|
200
|
-
"Report couldn't be processed",
|
|
201
|
-
err
|
|
202
|
-
);
|
|
173
|
+
console.log(APP_PREFIX, chalk.blue(title), "Report couldn't be processed", err);
|
|
203
174
|
}
|
|
204
175
|
});
|
|
205
176
|
|
|
@@ -216,43 +187,37 @@ class TestomatClient {
|
|
|
216
187
|
.then(async () => {
|
|
217
188
|
if (this.runId) {
|
|
218
189
|
let statusEvent;
|
|
219
|
-
if (status === FINISHED) statusEvent =
|
|
220
|
-
if (status === PASSED) statusEvent =
|
|
221
|
-
if (status === FAILED) statusEvent =
|
|
222
|
-
if (isParallel) statusEvent +=
|
|
190
|
+
if (status === FINISHED) statusEvent = 'finish';
|
|
191
|
+
if (status === PASSED) statusEvent = 'pass';
|
|
192
|
+
if (status === FAILED) statusEvent = 'fail';
|
|
193
|
+
if (isParallel) statusEvent += '_parallel';
|
|
223
194
|
await this.axios.put(`${TESTOMAT_URL}/api/reporter/${this.runId}`, {
|
|
224
195
|
api_key: this.apiKey,
|
|
225
196
|
status_event: statusEvent,
|
|
226
197
|
status,
|
|
227
198
|
});
|
|
228
199
|
if (this.runUrl) {
|
|
229
|
-
console.log(
|
|
230
|
-
APP_PREFIX,
|
|
231
|
-
"📊 Report Saved. Report URL:",
|
|
232
|
-
chalk.magenta(this.runUrl)
|
|
233
|
-
);
|
|
200
|
+
console.log(APP_PREFIX, '📊 Report Saved. Report URL:', chalk.magenta(this.runUrl));
|
|
234
201
|
}
|
|
235
202
|
|
|
236
|
-
if (this.totalUploaded > 0) {
|
|
203
|
+
if (upload.isEnabled() && this.totalUploaded > 0) {
|
|
237
204
|
console.log(
|
|
238
205
|
APP_PREFIX,
|
|
239
206
|
`🗄️ Total ${this.totalUploaded} artifacts ${
|
|
240
|
-
isPrivate ?
|
|
241
|
-
} uploaded to S3 bucket
|
|
207
|
+
upload.isPrivate ? 'privately' : chalk.bold('publicly')
|
|
208
|
+
} uploaded to S3 bucket `,
|
|
242
209
|
);
|
|
243
210
|
}
|
|
244
211
|
}
|
|
245
212
|
})
|
|
246
|
-
.catch(
|
|
247
|
-
console.log(APP_PREFIX,
|
|
213
|
+
.catch(err => {
|
|
214
|
+
console.log(APP_PREFIX, 'Error updating status, skipping...', err);
|
|
248
215
|
});
|
|
249
216
|
return this.queue;
|
|
250
217
|
}
|
|
251
218
|
|
|
252
219
|
formatSteps(stack, steps) {
|
|
253
|
-
return stack
|
|
254
|
-
? `${steps}\n\n${chalk.bold.red("################[ Failure ]################")}\n${stack}`
|
|
255
|
-
: steps;
|
|
220
|
+
return stack ? `${steps}\n\n${chalk.bold.red('################[ Failure ]################')}\n${stack}` : steps;
|
|
256
221
|
}
|
|
257
222
|
|
|
258
223
|
formatError(error, message) {
|
|
@@ -263,28 +228,21 @@ class TestomatClient {
|
|
|
263
228
|
|
|
264
229
|
// diffs for mocha, cypress, codeceptjs style
|
|
265
230
|
if (error.actual && error.expected) {
|
|
266
|
-
stack += `\n\n${chalk.bold.green(
|
|
267
|
-
|
|
268
|
-
)}`;
|
|
269
|
-
stack +=
|
|
270
|
-
`- ${error.actual.toString().split("\n").join("\n- ")}`
|
|
271
|
-
)}`;
|
|
272
|
-
stack += `\n${chalk.green(
|
|
273
|
-
`+ ${error.expected.toString().split("\n").join("\n+ ")}`
|
|
274
|
-
)}`;
|
|
275
|
-
stack += "\n\n";
|
|
231
|
+
stack += `\n\n${chalk.bold.green('+ expected')} ${chalk.bold.red('- actual')}`;
|
|
232
|
+
stack += `\n${chalk.red(`- ${error.actual.toString().split('\n').join('\n- ')}`)}`;
|
|
233
|
+
stack += `\n${chalk.green(`+ ${error.expected.toString().split('\n').join('\n+ ')}`)}`;
|
|
234
|
+
stack += '\n\n';
|
|
276
235
|
}
|
|
277
236
|
|
|
278
237
|
try {
|
|
279
238
|
const record = createCallsiteRecord({
|
|
280
239
|
forError: error,
|
|
281
240
|
});
|
|
282
|
-
if (record) {
|
|
241
|
+
if (record && !record.filename.startsWith('http')) {
|
|
283
242
|
stack += record.renderSync({
|
|
284
|
-
stackFilter: (
|
|
285
|
-
frame.getFileName().indexOf(
|
|
286
|
-
frame.getFileName().indexOf(
|
|
287
|
-
frame.getFileName().indexOf("internal") < 0,
|
|
243
|
+
stackFilter: frame => frame.getFileName().indexOf(sep) > -1 &&
|
|
244
|
+
frame.getFileName().indexOf('node_modules') < 0 &&
|
|
245
|
+
frame.getFileName().indexOf('internal') < 0,
|
|
288
246
|
});
|
|
289
247
|
}
|
|
290
248
|
return stack;
|
|
@@ -295,12 +253,3 @@ class TestomatClient {
|
|
|
295
253
|
}
|
|
296
254
|
|
|
297
255
|
module.exports = TestomatClient;
|
|
298
|
-
|
|
299
|
-
function isValidUrl(s) {
|
|
300
|
-
try {
|
|
301
|
-
new URL(s); // eslint-disable-line
|
|
302
|
-
return true;
|
|
303
|
-
} catch (err) {
|
|
304
|
-
return false;
|
|
305
|
-
}
|
|
306
|
-
}
|
package/lib/constants.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
const chalk = require(
|
|
1
|
+
const chalk = require('chalk');
|
|
2
2
|
|
|
3
|
-
const APP_PREFIX = chalk.gray(
|
|
3
|
+
const APP_PREFIX = chalk.gray('[TESTOMATIO]');
|
|
4
4
|
|
|
5
5
|
module.exports = Object.freeze({
|
|
6
|
-
PASSED:
|
|
7
|
-
FAILED:
|
|
8
|
-
SKIPPED:
|
|
9
|
-
FINISHED:
|
|
6
|
+
PASSED: 'passed',
|
|
7
|
+
FAILED: 'failed',
|
|
8
|
+
SKIPPED: 'skipped',
|
|
9
|
+
FINISHED: 'finished',
|
|
10
10
|
APP_PREFIX,
|
|
11
11
|
});
|