@testomatio/reporter 2.0.1-beta.4 → 2.0.1-beta.5-timestamp
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/codecept.js +335 -293
- package/lib/adapter/cucumber/current.js +203 -195
- package/lib/adapter/cucumber/legacy.js +155 -130
- package/lib/adapter/cucumber.js +16 -5
- package/lib/adapter/cypress-plugin/index.js +105 -91
- package/lib/adapter/jasmine.js +53 -54
- package/lib/adapter/jest.js +99 -97
- package/lib/adapter/mocha.js +141 -112
- package/lib/adapter/playwright.js +231 -199
- package/lib/adapter/vitest.js +149 -150
- package/lib/adapter/webdriver.js +121 -144
- package/lib/bin/cli.js +211 -229
- package/lib/bin/reportXml.js +52 -51
- package/lib/bin/startTest.js +95 -83
- package/lib/bin/uploadArtifacts.js +61 -56
- package/lib/client.js +465 -424
- package/lib/config.js +23 -18
- package/lib/constants.js +44 -50
- package/lib/data-storage.js +188 -216
- package/lib/junit-adapter/adapter.js +20 -17
- package/lib/junit-adapter/csharp.js +14 -28
- package/lib/junit-adapter/index.js +25 -27
- package/lib/junit-adapter/java.js +53 -41
- package/lib/junit-adapter/javascript.js +27 -30
- package/lib/junit-adapter/python.js +37 -38
- package/lib/junit-adapter/ruby.js +8 -11
- package/lib/output.js +52 -44
- package/lib/pipe/bitbucket.js +230 -223
- package/lib/pipe/csv.js +126 -113
- package/lib/pipe/debug.js +99 -118
- package/lib/pipe/github.js +213 -218
- package/lib/pipe/gitlab.js +206 -183
- package/lib/pipe/html.js +321 -258
- package/lib/pipe/index.js +66 -94
- package/lib/pipe/testomatio.js +474 -429
- package/lib/reporter-functions.js +26 -28
- package/lib/reporter.js +29 -34
- package/lib/services/artifacts.js +51 -55
- package/lib/services/index.js +12 -14
- package/lib/services/key-values.js +53 -56
- package/lib/services/logger.js +245 -226
- package/lib/template/testomatio.hbs +1366 -1026
- package/lib/uploader.js +364 -295
- package/lib/utils/pipe_utils.js +85 -89
- package/lib/utils/utils.js +307 -398
- package/lib/xmlReader.js +532 -525
- package/package.json +21 -64
- package/lib/adapter/codecept.d.ts +0 -2
- package/lib/adapter/cucumber/current.d.ts +0 -14
- package/lib/adapter/cucumber/legacy.d.ts +0 -0
- package/lib/adapter/cucumber.d.ts +0 -2
- package/lib/adapter/cypress-plugin/index.d.ts +0 -2
- package/lib/adapter/jasmine.d.ts +0 -11
- package/lib/adapter/jest.d.ts +0 -13
- package/lib/adapter/mocha.d.ts +0 -2
- package/lib/adapter/nightwatch.d.ts +0 -4
- package/lib/adapter/nightwatch.js +0 -80
- package/lib/adapter/playwright.d.ts +0 -14
- package/lib/adapter/vitest.d.ts +0 -35
- package/lib/adapter/webdriver.d.ts +0 -24
- package/lib/bin/cli.d.ts +0 -2
- package/lib/bin/reportXml.d.ts +0 -2
- package/lib/bin/startTest.d.ts +0 -2
- package/lib/bin/uploadArtifacts.d.ts +0 -2
- package/lib/client.d.ts +0 -76
- package/lib/config.d.ts +0 -1
- package/lib/constants.d.ts +0 -25
- package/lib/data-storage.d.ts +0 -34
- package/lib/junit-adapter/adapter.d.ts +0 -9
- package/lib/junit-adapter/csharp.d.ts +0 -5
- package/lib/junit-adapter/index.d.ts +0 -3
- package/lib/junit-adapter/java.d.ts +0 -5
- package/lib/junit-adapter/javascript.d.ts +0 -4
- package/lib/junit-adapter/python.d.ts +0 -5
- package/lib/junit-adapter/ruby.d.ts +0 -4
- package/lib/output.d.ts +0 -11
- package/lib/package.json +0 -3
- package/lib/pipe/bitbucket.d.ts +0 -25
- package/lib/pipe/csv.d.ts +0 -47
- package/lib/pipe/debug.d.ts +0 -29
- package/lib/pipe/github.d.ts +0 -30
- package/lib/pipe/gitlab.d.ts +0 -25
- package/lib/pipe/html.d.ts +0 -35
- package/lib/pipe/index.d.ts +0 -1
- package/lib/pipe/testomatio.d.ts +0 -71
- package/lib/replay.d.ts +0 -31
- package/lib/replay.js +0 -237
- package/lib/reporter-functions.d.ts +0 -34
- package/lib/reporter.d.ts +0 -232
- package/lib/services/artifacts.d.ts +0 -33
- package/lib/services/index.d.ts +0 -9
- package/lib/services/key-values.d.ts +0 -27
- package/lib/services/logger.d.ts +0 -64
- package/lib/uploader.d.ts +0 -60
- package/lib/utils/pipe_utils.d.ts +0 -41
- package/lib/utils/utils.d.ts +0 -54
- package/lib/xmlReader.d.ts +0 -92
- package/src/adapter/codecept.js +0 -373
- package/src/adapter/cucumber/current.js +0 -228
- package/src/adapter/cucumber/legacy.js +0 -158
- package/src/adapter/cucumber.js +0 -4
- package/src/adapter/cypress-plugin/index.js +0 -110
- package/src/adapter/jasmine.js +0 -60
- package/src/adapter/jest.js +0 -107
- package/src/adapter/mocha.cjs +0 -2
- package/src/adapter/mocha.js +0 -156
- package/src/adapter/nightwatch.js +0 -88
- package/src/adapter/playwright.js +0 -254
- package/src/adapter/vitest.js +0 -183
- package/src/adapter/webdriver.js +0 -142
- package/src/bin/cli.js +0 -348
- package/src/bin/reportXml.js +0 -77
- package/src/bin/startTest.js +0 -124
- package/src/bin/uploadArtifacts.js +0 -91
- package/src/client.js +0 -508
- package/src/config.js +0 -30
- package/src/constants.js +0 -53
- package/src/data-storage.js +0 -204
- package/src/junit-adapter/adapter.js +0 -23
- package/src/junit-adapter/csharp.js +0 -28
- package/src/junit-adapter/index.js +0 -28
- package/src/junit-adapter/java.js +0 -58
- package/src/junit-adapter/javascript.js +0 -31
- package/src/junit-adapter/python.js +0 -42
- package/src/junit-adapter/ruby.js +0 -10
- package/src/output.js +0 -57
- package/src/pipe/bitbucket.js +0 -252
- package/src/pipe/csv.js +0 -140
- package/src/pipe/debug.js +0 -119
- package/src/pipe/github.js +0 -232
- package/src/pipe/gitlab.js +0 -247
- package/src/pipe/html.js +0 -373
- package/src/pipe/index.js +0 -71
- package/src/pipe/testomatio.js +0 -504
- package/src/replay.js +0 -245
- package/src/reporter-functions.js +0 -55
- package/src/reporter.cjs_decprecated +0 -21
- package/src/reporter.js +0 -33
- package/src/services/artifacts.js +0 -59
- package/src/services/index.js +0 -13
- package/src/services/key-values.js +0 -59
- package/src/services/logger.js +0 -315
- package/src/template/emptyData.svg +0 -23
- package/src/template/testomatio.hbs +0 -1081
- package/src/uploader.js +0 -376
- package/src/utils/pipe_utils.js +0 -119
- package/src/utils/utils.js +0 -416
- package/src/xmlReader.js +0 -614
package/lib/bin/cli.js
CHANGED
|
@@ -1,293 +1,275 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const picocolors_1 = __importDefault(require("picocolors"));
|
|
18
|
-
const filesize_1 = require("filesize");
|
|
19
|
-
const dotenv_1 = __importDefault(require("dotenv"));
|
|
20
|
-
const replay_js_1 = __importDefault(require("../replay.js"));
|
|
21
|
-
const debug = (0, debug_1.default)('@testomatio/reporter:xml-cli');
|
|
22
|
-
const version = (0, utils_js_1.getPackageVersion)();
|
|
23
|
-
console.log(picocolors_1.default.cyan(picocolors_1.default.bold(` 🤩 Testomat.io Reporter v${version}`)));
|
|
24
|
-
const program = new commander_1.Command();
|
|
2
|
+
const { program } = require('commander');
|
|
3
|
+
const spawn = require('cross-spawn');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const glob = require('glob');
|
|
6
|
+
const debug = require('debug')('@testomatio/reporter:cli');
|
|
7
|
+
const TestomatClient = require('../client');
|
|
8
|
+
const XmlReader = require('../xmlReader');
|
|
9
|
+
const { APP_PREFIX, STATUS } = require('../constants');
|
|
10
|
+
const { version } = require('../../package.json');
|
|
11
|
+
const config = require('../config');
|
|
12
|
+
const { readLatestRunId } = require('../utils/utils');
|
|
13
|
+
const { filesize: prettyBytes } = require('filesize');
|
|
14
|
+
|
|
15
|
+
console.log(chalk.cyan.bold(` 🤩 Testomat.io Reporter v${version}`));
|
|
16
|
+
|
|
25
17
|
program
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
.version(version)
|
|
19
|
+
.option('--env-file <envfile>', 'Load environment variables from env file')
|
|
20
|
+
.hook('preAction', thisCommand => {
|
|
29
21
|
const opts = thisCommand.opts();
|
|
30
22
|
if (opts.envFile) {
|
|
31
|
-
|
|
23
|
+
require('dotenv').config({ path: opts.envFile });
|
|
24
|
+
} else {
|
|
25
|
+
require('dotenv').config();
|
|
32
26
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
});
|
|
27
|
+
});
|
|
28
|
+
|
|
37
29
|
program
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
.command('start')
|
|
31
|
+
.description('Start a new run and return its ID')
|
|
32
|
+
.action(async () => {
|
|
41
33
|
console.log('Starting a new Run on Testomat.io...');
|
|
42
|
-
const apiKey = process.env['INPUT_TESTOMATIO-KEY'] ||
|
|
43
|
-
const client = new
|
|
34
|
+
const apiKey = process.env['INPUT_TESTOMATIO-KEY'] || config.TESTOMATIO;
|
|
35
|
+
const client = new TestomatClient({ apiKey });
|
|
36
|
+
|
|
44
37
|
client.createRun().then(() => {
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
console.log(process.env.runId);
|
|
39
|
+
process.exit(0);
|
|
47
40
|
});
|
|
48
|
-
});
|
|
41
|
+
});
|
|
42
|
+
|
|
49
43
|
program
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
process.env.TESTOMATIO_RUN ||=
|
|
44
|
+
.command('finish')
|
|
45
|
+
.description('Finish Run by its ID')
|
|
46
|
+
.action(async () => {
|
|
47
|
+
process.env.TESTOMATIO_RUN ||= readLatestRunId();
|
|
48
|
+
|
|
54
49
|
if (!process.env.TESTOMATIO_RUN) {
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
console.log('TESTOMATIO_RUN environment variable must be set or restored from a previous run.');
|
|
51
|
+
return process.exit(1);
|
|
57
52
|
}
|
|
53
|
+
|
|
58
54
|
console.log('Finishing Run on Testomat.io...');
|
|
59
|
-
const apiKey = process.env['INPUT_TESTOMATIO-KEY'] ||
|
|
60
|
-
const client = new
|
|
61
|
-
|
|
62
|
-
client.updateRunStatus(
|
|
63
|
-
|
|
64
|
-
|
|
55
|
+
const apiKey = process.env['INPUT_TESTOMATIO-KEY'] || config.TESTOMATIO;
|
|
56
|
+
const client = new TestomatClient({ apiKey });
|
|
57
|
+
|
|
58
|
+
client.updateRunStatus(STATUS.FINISHED).then(() => {
|
|
59
|
+
console.log(chalk.yellow(`Run ${process.env.TESTOMATIO_RUN} was finished`));
|
|
60
|
+
process.exit(0);
|
|
65
61
|
});
|
|
66
|
-
});
|
|
62
|
+
});
|
|
63
|
+
|
|
67
64
|
program
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const apiKey = process.env['INPUT_TESTOMATIO-KEY'] ||
|
|
65
|
+
.command('run')
|
|
66
|
+
.description('Run tests with the specified command')
|
|
67
|
+
.argument('<command>', 'Test runner command')
|
|
68
|
+
.option('--filter <filter>', 'Additional execution filter')
|
|
69
|
+
.action(async (command, opts) => {
|
|
70
|
+
const apiKey = process.env['INPUT_TESTOMATIO-KEY'] || config.TESTOMATIO;
|
|
74
71
|
const title = process.env.TESTOMATIO_TITLE;
|
|
72
|
+
|
|
75
73
|
if (!command || !command.split) {
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
console.log(APP_PREFIX, `No command provided. Use -c option to launch a test runner.`);
|
|
75
|
+
return process.exit(255);
|
|
78
76
|
}
|
|
79
|
-
|
|
77
|
+
|
|
78
|
+
const client = new TestomatClient({ apiKey, title, parallel: true });
|
|
79
|
+
|
|
80
80
|
if (opts.filter) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
catch (err) {
|
|
90
|
-
console.log(constants_js_1.APP_PREFIX, err);
|
|
81
|
+
const [pipe, ...optsArray] = opts.filter.split(':');
|
|
82
|
+
const pipeOptions = optsArray.join(':');
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
const tests = await client.prepareRun({ pipe, pipeOptions });
|
|
86
|
+
if (tests && tests.length > 0) {
|
|
87
|
+
command += ` --grep (${tests.join('|')})`;
|
|
91
88
|
}
|
|
89
|
+
} catch (err) {
|
|
90
|
+
console.log(APP_PREFIX, err);
|
|
91
|
+
}
|
|
92
92
|
}
|
|
93
|
-
|
|
93
|
+
|
|
94
|
+
console.log(APP_PREFIX, `🚀 Running`, chalk.green(command));
|
|
95
|
+
|
|
94
96
|
const runTests = () => {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
97
|
+
const testCmds = command.split(' ');
|
|
98
|
+
const cmd = spawn(testCmds[0], testCmds.slice(1), { stdio: 'inherit' });
|
|
99
|
+
|
|
100
|
+
cmd.on('close', code => {
|
|
101
|
+
const emoji = code === 0 ? '🟢' : '🔴';
|
|
102
|
+
console.log(APP_PREFIX, emoji, `Runner exited with ${chalk.bold(code)}`);
|
|
103
|
+
if (apiKey) {
|
|
104
|
+
const status = code === 0 ? 'passed' : 'failed';
|
|
105
|
+
client.updateRunStatus(status, true);
|
|
106
|
+
}
|
|
107
|
+
process.exit(code);
|
|
108
|
+
});
|
|
106
109
|
};
|
|
110
|
+
|
|
107
111
|
if (apiKey) {
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
runTests();
|
|
112
|
+
client.createRun().then(runTests);
|
|
113
|
+
} else {
|
|
114
|
+
runTests();
|
|
112
115
|
}
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
// .command('xml')
|
|
116
|
-
// .description('Parse XML reports and upload to Testomat.io')
|
|
117
|
-
// .argument('<pattern>', 'XML file pattern')
|
|
118
|
-
// .option('-d, --dir <dir>', 'Project directory')
|
|
119
|
-
// .option('--java-tests [java-path]', 'Load Java tests from path, by default: src/test/java')
|
|
120
|
-
// .option('--lang <lang>', 'Language used (python, ruby, java)')
|
|
121
|
-
// .option('--timelimit <time>', 'default time limit in seconds to kill a stuck process')
|
|
122
|
-
// .action(async (pattern, opts) => {
|
|
123
|
-
// if (!pattern.endsWith('.xml')) {
|
|
124
|
-
// pattern += '.xml';
|
|
125
|
-
// }
|
|
126
|
-
// let { javaTests, lang } = opts;
|
|
127
|
-
// if (javaTests === true) javaTests = 'src/test/java';
|
|
128
|
-
// lang = lang?.toLowerCase();
|
|
129
|
-
// const runReader = new XmlReader({ javaTests, lang });
|
|
130
|
-
// const files = glob.sync(pattern, { cwd: opts.dir || process.cwd() });
|
|
131
|
-
// if (!files.length) {
|
|
132
|
-
// console.log(APP_PREFIX, `Report can't be created. No XML files found 😥`);
|
|
133
|
-
// process.exit(1);
|
|
134
|
-
// }
|
|
116
|
+
});
|
|
117
|
+
|
|
135
118
|
program
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
119
|
+
.command('xml')
|
|
120
|
+
.description('Parse XML reports and upload to Testomat.io')
|
|
121
|
+
.argument('<pattern>', 'XML file pattern')
|
|
122
|
+
.option('-d, --dir <dir>', 'Project directory')
|
|
123
|
+
.option('--java-tests [java-path]', 'Load Java tests from path, by default: src/test/java')
|
|
124
|
+
.option('--lang <lang>', 'Language used (python, ruby, java)')
|
|
125
|
+
.option('--timelimit <time>', 'default time limit in seconds to kill a stuck process')
|
|
126
|
+
.action(async (pattern, opts) => {
|
|
144
127
|
if (!pattern.endsWith('.xml')) {
|
|
145
|
-
|
|
128
|
+
pattern += '.xml';
|
|
146
129
|
}
|
|
147
130
|
let { javaTests, lang } = opts;
|
|
148
|
-
if (javaTests === true)
|
|
149
|
-
javaTests = 'src/test/java';
|
|
131
|
+
if (javaTests === true) javaTests = 'src/test/java';
|
|
150
132
|
lang = lang?.toLowerCase();
|
|
151
|
-
const runReader = new
|
|
152
|
-
const files =
|
|
133
|
+
const runReader = new XmlReader({ javaTests, lang });
|
|
134
|
+
const files = glob.sync(pattern, { cwd: opts.dir || process.cwd() });
|
|
153
135
|
if (!files.length) {
|
|
154
|
-
|
|
155
|
-
|
|
136
|
+
console.log(APP_PREFIX, `Report can't be created. No XML files found 😥`);
|
|
137
|
+
process.exit(1);
|
|
156
138
|
}
|
|
139
|
+
|
|
157
140
|
for (const file of files) {
|
|
158
|
-
|
|
159
|
-
|
|
141
|
+
console.log(APP_PREFIX, `Parsed ${file}`);
|
|
142
|
+
runReader.parse(file);
|
|
160
143
|
}
|
|
144
|
+
|
|
161
145
|
let timeoutTimer;
|
|
162
146
|
if (opts.timelimit) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
147
|
+
timeoutTimer = setTimeout(
|
|
148
|
+
() => {
|
|
149
|
+
console.log(
|
|
150
|
+
`⚠️ Reached timeout of ${opts.timelimit}s. Exiting... (Exit code is 0 to not fail the pipeline)`,
|
|
151
|
+
);
|
|
152
|
+
process.exit(0);
|
|
153
|
+
},
|
|
154
|
+
parseInt(opts.timelimit, 10) * 1000,
|
|
155
|
+
);
|
|
167
156
|
}
|
|
157
|
+
|
|
168
158
|
try {
|
|
169
|
-
|
|
170
|
-
|
|
159
|
+
await runReader.createRun();
|
|
160
|
+
await runReader.uploadData();
|
|
161
|
+
} catch (err) {
|
|
162
|
+
console.log(APP_PREFIX, 'Error updating status, skipping...', err);
|
|
171
163
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
clearTimeout(timeoutTimer);
|
|
177
|
-
});
|
|
164
|
+
|
|
165
|
+
if (timeoutTimer) clearTimeout(timeoutTimer);
|
|
166
|
+
});
|
|
167
|
+
|
|
178
168
|
program
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const apiKey =
|
|
169
|
+
.command('upload-artifacts')
|
|
170
|
+
.description('Upload artifacts to Testomat.io')
|
|
171
|
+
.option('--force', 'Re-upload artifacts even if they were uploaded before')
|
|
172
|
+
.action(async opts => {
|
|
173
|
+
const apiKey = config.TESTOMATIO;
|
|
174
|
+
|
|
184
175
|
process.env.TESTOMATIO_DISABLE_ARTIFACTS = '';
|
|
185
|
-
const runId = process.env.TESTOMATIO_RUN || process.env.runId ||
|
|
176
|
+
const runId = process.env.TESTOMATIO_RUN || process.env.runId || readLatestRunId();
|
|
177
|
+
|
|
186
178
|
if (!runId) {
|
|
187
|
-
|
|
188
|
-
|
|
179
|
+
console.log('TESTOMATIO_RUN environment variable must be set or restored from a previous run.');
|
|
180
|
+
return process.exit(1);
|
|
189
181
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
182
|
+
|
|
183
|
+
const client = new TestomatClient({
|
|
184
|
+
apiKey,
|
|
185
|
+
runId,
|
|
186
|
+
isBatchEnabled: false,
|
|
194
187
|
});
|
|
188
|
+
|
|
195
189
|
let testruns = client.uploader.readUploadedFiles(runId);
|
|
196
190
|
const numTotalArtifacts = testruns.length;
|
|
191
|
+
|
|
197
192
|
debug('Found testruns:', testruns);
|
|
198
|
-
|
|
199
|
-
|
|
193
|
+
|
|
194
|
+
if (!opts.force) testruns = testruns.filter(tr => !tr.uploaded);
|
|
195
|
+
|
|
200
196
|
if (!testruns.length) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
197
|
+
console.log(APP_PREFIX, '🗄️ Total artifacts:', numTotalArtifacts);
|
|
198
|
+
if (numTotalArtifacts) {
|
|
199
|
+
console.log(APP_PREFIX, 'No new artifacts to upload');
|
|
200
|
+
console.log(APP_PREFIX, 'To re-upload artifacts run this command with --force flag');
|
|
201
|
+
}
|
|
202
|
+
process.exit(0);
|
|
207
203
|
}
|
|
204
|
+
|
|
208
205
|
const testrunsByRid = testruns.reduce((acc, { rid, file }) => {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
return acc;
|
|
206
|
+
if (!acc[rid]) {
|
|
207
|
+
acc[rid] = [];
|
|
208
|
+
}
|
|
209
|
+
if (!acc[rid].includes(file)) acc[rid].push(file);
|
|
210
|
+
return acc;
|
|
215
211
|
}, {});
|
|
212
|
+
|
|
216
213
|
await client.createRun();
|
|
217
214
|
client.uploader.checkEnabled();
|
|
218
215
|
client.uploader.disableLogStorage();
|
|
216
|
+
|
|
219
217
|
for (const rid in testrunsByRid) {
|
|
220
|
-
|
|
221
|
-
|
|
218
|
+
const files = testrunsByRid[rid];
|
|
219
|
+
await client.addTestRun(undefined, { rid, files });
|
|
222
220
|
}
|
|
223
|
-
|
|
221
|
+
|
|
222
|
+
console.log(APP_PREFIX, '🗄️', client.uploader.successfulUploads.length, 'artifacts 🟢uploaded');
|
|
223
|
+
|
|
224
224
|
if (client.uploader.successfulUploads.length) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
225
|
+
debug('\n', APP_PREFIX, `🗄️ ${client.uploader.successfulUploads.length} artifacts uploaded to S3 bucket`);
|
|
226
|
+
const uploadedArtifacts = client.uploader.successfulUploads.map(file => ({
|
|
227
|
+
relativePath: file.path.replace(process.cwd(), ''),
|
|
228
|
+
link: file.link,
|
|
229
|
+
sizePretty: prettyBytes(file.size, { round: 0 }).toString(),
|
|
230
|
+
}));
|
|
231
|
+
|
|
232
|
+
uploadedArtifacts.forEach(upload => {
|
|
233
|
+
debug(
|
|
234
|
+
`🟢 Uploaded artifact`,
|
|
235
|
+
`${upload.relativePath},`,
|
|
236
|
+
'size:',
|
|
237
|
+
`${upload.sizePretty},`,
|
|
238
|
+
'link:',
|
|
239
|
+
`${upload.link}`,
|
|
240
|
+
);
|
|
241
|
+
});
|
|
234
242
|
}
|
|
243
|
+
|
|
235
244
|
const filesizeStrMaxLength = 7;
|
|
245
|
+
|
|
236
246
|
if (client.uploader.failedUploads.length) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
})
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
onLog: (message) => console.log(constants_js_1.APP_PREFIX, message),
|
|
259
|
-
onError: (message) => console.error(constants_js_1.APP_PREFIX, '⚠️ ', message),
|
|
260
|
-
onProgress: ({ current, total }) => {
|
|
261
|
-
if (current % 10 === 0 || current === total) {
|
|
262
|
-
console.log(constants_js_1.APP_PREFIX, `📊 Progress: ${current}/${total} tests processed`);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
const result = await replayService.replay(debugFile);
|
|
267
|
-
if (result.dryRun) {
|
|
268
|
-
console.log(constants_js_1.APP_PREFIX, '🔍 Dry run completed:');
|
|
269
|
-
console.log(constants_js_1.APP_PREFIX, ` - Tests found: ${result.testsCount}`);
|
|
270
|
-
console.log(constants_js_1.APP_PREFIX, ` - Environment variables: ${Object.keys(result.envVars).length}`);
|
|
271
|
-
console.log(constants_js_1.APP_PREFIX, ` - Run parameters:`, result.runParams);
|
|
272
|
-
console.log(constants_js_1.APP_PREFIX, ' Use without --dry-run to actually send the data');
|
|
273
|
-
}
|
|
274
|
-
else {
|
|
275
|
-
console.log(constants_js_1.APP_PREFIX, `✅ Successfully replayed ${result.successCount}/${result.testsCount} tests`);
|
|
276
|
-
if (result.failureCount > 0) {
|
|
277
|
-
console.log(constants_js_1.APP_PREFIX, `⚠️ ${result.failureCount} tests failed to upload`);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
process.exit(0);
|
|
281
|
-
}
|
|
282
|
-
catch (err) {
|
|
283
|
-
console.error(constants_js_1.APP_PREFIX, '❌ Error replaying debug data:', err.message);
|
|
284
|
-
if (err.message.includes('Debug file not found')) {
|
|
285
|
-
console.error(constants_js_1.APP_PREFIX, '💡 Hint: Run tests with TESTOMATIO_DEBUG=1 to generate debug files');
|
|
286
|
-
}
|
|
287
|
-
process.exit(1);
|
|
247
|
+
console.log(
|
|
248
|
+
'\n',
|
|
249
|
+
APP_PREFIX,
|
|
250
|
+
'🗄️',
|
|
251
|
+
client.uploader.failedUploads.length,
|
|
252
|
+
`artifacts 🔴${chalk.bold('failed')} to upload`,
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
const failedUploads = client.uploader.failedUploads.map(({ path, size }) => ({
|
|
256
|
+
relativePath: path.replace(process.cwd(), ''),
|
|
257
|
+
sizePretty: prettyBytes(size, { round: 0 }).toString(),
|
|
258
|
+
}));
|
|
259
|
+
|
|
260
|
+
const pathPadding = Math.max(...failedUploads.map(upload => upload.relativePath.length)) + 1;
|
|
261
|
+
failedUploads.forEach(upload => {
|
|
262
|
+
console.log(
|
|
263
|
+
` ${chalk.gray('|')} 🔴 ${upload.relativePath.padEnd(pathPadding)} ${chalk.gray(
|
|
264
|
+
`| ${upload.sizePretty.padStart(filesizeStrMaxLength)} |`,
|
|
265
|
+
)}`,
|
|
266
|
+
);
|
|
267
|
+
});
|
|
288
268
|
}
|
|
289
|
-
});
|
|
269
|
+
});
|
|
270
|
+
|
|
290
271
|
program.parse(process.argv);
|
|
272
|
+
|
|
291
273
|
if (!process.argv.slice(2).length) {
|
|
292
|
-
|
|
274
|
+
program.outputHelp();
|
|
293
275
|
}
|
package/lib/bin/reportXml.js
CHANGED
|
@@ -1,71 +1,72 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const utils_js_1 = require("../utils/utils.js");
|
|
14
|
-
const dotenv_1 = __importDefault(require("dotenv"));
|
|
15
|
-
const path_1 = __importDefault(require("path"));
|
|
16
|
-
const version = (0, utils_js_1.getPackageVersion)();
|
|
17
|
-
const debug = (0, debug_1.default)('@testomatio/reporter:xml-cli');
|
|
18
|
-
console.log(picocolors_1.default.cyan(picocolors_1.default.bold(` 🤩 Testomat.io XML Reporter v${version}`)));
|
|
19
|
-
const program = new commander_1.Command();
|
|
2
|
+
const { program } = require('commander');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const glob = require('glob');
|
|
5
|
+
const debug = require('debug')('@testomatio/reporter:xml-cli');
|
|
6
|
+
const { APP_PREFIX } = require('../constants');
|
|
7
|
+
const XmlReader = require('../xmlReader');
|
|
8
|
+
|
|
9
|
+
const { version } = require('../../package.json');
|
|
10
|
+
|
|
11
|
+
console.log(chalk.cyan.bold(` 🤩 Testomat.io XML Reporter v${version}`));
|
|
12
|
+
|
|
20
13
|
program
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
14
|
+
.arguments('<pattern>')
|
|
15
|
+
.option('-d, --dir <dir>', 'Project directory')
|
|
16
|
+
.option('--java-tests [java-path]', 'Load Java tests from path, by default: src/test/java')
|
|
17
|
+
.option('--lang <lang>', 'Language used (python, ruby, java)')
|
|
18
|
+
.option('--timelimit <time>', 'default time limit in seconds to kill a stuck process')
|
|
19
|
+
.option('--env-file <envfile>', 'Load environment variables from env file')
|
|
20
|
+
.action(async (pattern, opts) => {
|
|
28
21
|
if (!pattern.endsWith('.xml')) {
|
|
29
|
-
|
|
22
|
+
pattern += '.xml';
|
|
30
23
|
}
|
|
31
24
|
let { javaTests, lang } = opts;
|
|
32
25
|
if (opts.envFile) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
console.log(APP_PREFIX, 'Loading env file:', opts.envFile);
|
|
27
|
+
debug('Loading env file: %s', opts.envFile);
|
|
28
|
+
require('dotenv').config({ path: opts.envFile }); // eslint-disable-line
|
|
36
29
|
}
|
|
30
|
+
if (javaTests === true) javaTests = 'src/test/java';
|
|
37
31
|
lang = lang?.toLowerCase();
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const runReader = new xmlReader_js_1.default({ javaTests, lang });
|
|
41
|
-
const files = glob_1.glob.sync(pattern, { cwd: opts.dir || process.cwd() });
|
|
32
|
+
const runReader = new XmlReader({ javaTests, lang });
|
|
33
|
+
const files = glob.sync(pattern, { cwd: opts.dir || process.cwd() });
|
|
42
34
|
if (!files.length) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
35
|
+
console.log(APP_PREFIX, `Report can't be created. No XML files found 😥`);
|
|
36
|
+
process.exitCode = 1;
|
|
37
|
+
return;
|
|
46
38
|
}
|
|
39
|
+
|
|
47
40
|
for (const file of files) {
|
|
48
|
-
|
|
49
|
-
|
|
41
|
+
console.log(APP_PREFIX, `Parsed ${file}`);
|
|
42
|
+
runReader.parse(file);
|
|
50
43
|
}
|
|
44
|
+
|
|
51
45
|
let timeoutTimer;
|
|
52
46
|
if (opts.timelimit) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
+
);
|
|
57
56
|
}
|
|
57
|
+
|
|
58
58
|
try {
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
await runReader.createRun();
|
|
60
|
+
await runReader.uploadData();
|
|
61
|
+
} catch (err) {
|
|
62
|
+
console.log(APP_PREFIX, 'Error updating status, skipping...', err);
|
|
61
63
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
clearTimeout(timeoutTimer);
|
|
67
|
-
});
|
|
64
|
+
|
|
65
|
+
if (timeoutTimer) clearTimeout(timeoutTimer);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
68
|
if (process.argv.length < 3) {
|
|
69
|
-
|
|
69
|
+
program.outputHelp();
|
|
70
70
|
}
|
|
71
|
+
|
|
71
72
|
program.parse(process.argv);
|