@testomatio/reporter 2.0.1-beta-2-ignore-xml → 2.0.1-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/lib/adapter/codecept.js +0 -2
- package/lib/adapter/cypress-plugin/index.js +0 -2
- package/lib/adapter/mocha.js +0 -1
- package/lib/adapter/nightwatch.d.ts +4 -0
- package/lib/adapter/nightwatch.js +80 -0
- package/lib/adapter/webdriver.d.ts +1 -1
- package/lib/adapter/webdriver.js +18 -8
- package/lib/bin/cli.js +73 -8
- package/lib/bin/reportXml.js +4 -2
- package/lib/bin/startTest.js +3 -2
- package/lib/bin/uploadArtifacts.js +5 -4
- package/lib/client.js +18 -9
- package/lib/config.js +2 -2
- package/lib/data-storage.d.ts +1 -1
- package/lib/data-storage.js +17 -7
- package/lib/junit-adapter/csharp.d.ts +1 -0
- package/lib/junit-adapter/csharp.js +11 -1
- package/lib/pipe/bitbucket.d.ts +2 -0
- package/lib/pipe/bitbucket.js +38 -26
- package/lib/pipe/debug.js +17 -3
- package/lib/pipe/github.d.ts +2 -2
- package/lib/pipe/github.js +35 -3
- package/lib/pipe/gitlab.d.ts +2 -0
- package/lib/pipe/gitlab.js +27 -9
- package/lib/pipe/html.d.ts +1 -0
- package/lib/pipe/html.js +1 -3
- package/lib/pipe/index.js +17 -7
- package/lib/pipe/testomatio.d.ts +3 -2
- package/lib/pipe/testomatio.js +85 -75
- package/lib/replay.d.ts +31 -0
- package/lib/replay.js +237 -0
- package/lib/reporter.d.ts +12 -12
- package/lib/services/artifacts.d.ts +1 -1
- package/lib/services/key-values.d.ts +1 -1
- package/lib/services/logger.d.ts +1 -1
- package/lib/services/logger.js +1 -2
- package/lib/template/testomatio.hbs +443 -68
- package/lib/uploader.js +10 -6
- package/lib/utils/utils.d.ts +3 -1
- package/lib/utils/utils.js +54 -21
- package/lib/xmlReader.js +54 -19
- package/package.json +8 -9
- package/src/adapter/codecept.js +0 -2
- package/src/adapter/cypress-plugin/index.js +0 -2
- package/src/adapter/mocha.js +0 -1
- package/src/adapter/nightwatch.js +88 -0
- package/src/adapter/webdriver.js +2 -2
- package/src/bin/cli.js +70 -2
- package/src/bin/reportXml.js +4 -1
- package/src/bin/startTest.js +2 -1
- package/src/bin/uploadArtifacts.js +2 -1
- package/src/client.js +1 -2
- package/src/config.js +2 -2
- package/src/junit-adapter/csharp.js +13 -1
- package/src/pipe/bitbucket.js +22 -24
- package/src/pipe/debug.js +18 -3
- package/src/pipe/github.js +1 -2
- package/src/pipe/gitlab.js +27 -9
- package/src/pipe/html.js +3 -4
- package/src/pipe/testomatio.js +106 -105
- package/src/replay.js +245 -0
- package/src/services/logger.js +1 -2
- package/src/template/testomatio.hbs +443 -68
- package/src/uploader.js +11 -6
- package/src/utils/utils.js +31 -12
- package/src/xmlReader.js +69 -17
package/lib/adapter/codecept.js
CHANGED
|
@@ -10,7 +10,6 @@ const client_js_1 = __importDefault(require("../client.js"));
|
|
|
10
10
|
const constants_js_1 = require("../constants.js");
|
|
11
11
|
const utils_js_1 = require("../utils/utils.js");
|
|
12
12
|
const index_js_1 = require("../services/index.js");
|
|
13
|
-
// eslint-disable-next-line
|
|
14
13
|
const codeceptjs_1 = __importDefault(require("codeceptjs"));
|
|
15
14
|
const debug = (0, debug_1.default)('@testomatio/reporter:adapter:codeceptjs');
|
|
16
15
|
// @ts-ignore
|
|
@@ -238,7 +237,6 @@ function CodeceptReporter(config) {
|
|
|
238
237
|
for (let i = 0; i < Math.max(currentMetaStep.length, metaSteps.length); i++) {
|
|
239
238
|
if (currentMetaStep[i] !== metaSteps[i]) {
|
|
240
239
|
stepShift = 2 * i;
|
|
241
|
-
// eslint-disable-next-line no-continue
|
|
242
240
|
if (!metaSteps[i])
|
|
243
241
|
continue;
|
|
244
242
|
if (metaSteps[i].isBDD()) {
|
|
@@ -40,7 +40,6 @@ const testomatioReporter = on => {
|
|
|
40
40
|
const suiteId = (0, utils_js_1.parseSuite)(suiteTitle);
|
|
41
41
|
if (!error && test.displayError) {
|
|
42
42
|
error = { message: test.displayError };
|
|
43
|
-
// eslint-disable-next-line
|
|
44
43
|
error.inspect = function () {
|
|
45
44
|
return this.message;
|
|
46
45
|
};
|
|
@@ -50,7 +49,6 @@ const testomatioReporter = on => {
|
|
|
50
49
|
message: error.message,
|
|
51
50
|
name: error.name,
|
|
52
51
|
inspect: error.inspect ||
|
|
53
|
-
// eslint-disable-next-line
|
|
54
52
|
function () {
|
|
55
53
|
return this.message;
|
|
56
54
|
},
|
package/lib/adapter/mocha.js
CHANGED
|
@@ -3,7 +3,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
|
|
7
6
|
const mocha_1 = __importDefault(require("mocha"));
|
|
8
7
|
const client_js_1 = __importDefault(require("../client.js"));
|
|
9
8
|
const constants_js_1 = require("../constants.js");
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const client_js_1 = __importDefault(require("../client.js"));
|
|
7
|
+
const config_js_1 = require("../config.js");
|
|
8
|
+
const constants_js_1 = require("../constants.js");
|
|
9
|
+
const utils_js_1 = require("../utils/utils.js");
|
|
10
|
+
const apiKey = config_js_1.config.TESTOMATIO;
|
|
11
|
+
const client = new client_js_1.default({ apiKey });
|
|
12
|
+
module.exports = {
|
|
13
|
+
write: async (results, options, done) => {
|
|
14
|
+
await client.createRun();
|
|
15
|
+
const testFiles = results.modules;
|
|
16
|
+
for (const fileName in testFiles) {
|
|
17
|
+
// in nightwatch: object containing tests from a single file
|
|
18
|
+
const testModule = testFiles[fileName];
|
|
19
|
+
// passed and failed tests (tests with assertions)
|
|
20
|
+
const completedTests = testModule.completed;
|
|
21
|
+
// skipped tests (skipped by user or tests without assertions)
|
|
22
|
+
const skippedTests = testModule.skipped;
|
|
23
|
+
const tags = testModule.tags || [];
|
|
24
|
+
// if test file contains multiple suites, the last suite name is used as a name 🤷♂️
|
|
25
|
+
// no other places which contain suite name (even inside test object)
|
|
26
|
+
const suiteTitle = testModule.name;
|
|
27
|
+
for (const testTitle in completedTests) {
|
|
28
|
+
const test = completedTests[testTitle];
|
|
29
|
+
let status;
|
|
30
|
+
switch (test.status) {
|
|
31
|
+
case 'pass':
|
|
32
|
+
status = constants_js_1.STATUS.PASSED;
|
|
33
|
+
break;
|
|
34
|
+
case 'fail':
|
|
35
|
+
status = constants_js_1.STATUS.FAILED;
|
|
36
|
+
break;
|
|
37
|
+
// probably not required (because skipped tests are in separate array), but just in case
|
|
38
|
+
case 'skip':
|
|
39
|
+
status = constants_js_1.STATUS.SKIPPED;
|
|
40
|
+
console.info('Skipped test is in completed tests array:', test, 'Not expected behavior.');
|
|
41
|
+
break;
|
|
42
|
+
default:
|
|
43
|
+
console.error('Test status processing error:', test.status);
|
|
44
|
+
}
|
|
45
|
+
const testId = (0, utils_js_1.getTestomatIdFromTestTitle)(testTitle);
|
|
46
|
+
client.addTestRun(status, {
|
|
47
|
+
error: { name: test.assertions?.[0]?.name, message: test.assertions?.[0]?.message, stack: test.stackTrace },
|
|
48
|
+
file: testModule.modulePath?.replace(process.cwd(), ''),
|
|
49
|
+
message: test.assertions?.[0]?.message,
|
|
50
|
+
rid: `${testModule.uuid || ''}_${testTitle || ''}`,
|
|
51
|
+
stack: test.stackTrace,
|
|
52
|
+
suite_title: suiteTitle,
|
|
53
|
+
tags,
|
|
54
|
+
test_id: testId,
|
|
55
|
+
time: test.timeMs,
|
|
56
|
+
title: testTitle,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
// just array with skipped tests titles, no any other info
|
|
60
|
+
for (const testTitle of skippedTests) {
|
|
61
|
+
client.addTestRun(constants_js_1.STATUS.SKIPPED, {
|
|
62
|
+
suite_title: suiteTitle,
|
|
63
|
+
tags,
|
|
64
|
+
rid: `${testModule.uuid || ''}_${testTitle || ''}`,
|
|
65
|
+
title: testTitle,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* @type {'passed' | 'failed' | 'finished'}
|
|
71
|
+
*/
|
|
72
|
+
let runStatus = 'finished';
|
|
73
|
+
if (results.failed)
|
|
74
|
+
runStatus = 'failed';
|
|
75
|
+
else if (results.passed)
|
|
76
|
+
runStatus = 'passed';
|
|
77
|
+
await client.updateRunStatus(runStatus);
|
|
78
|
+
done();
|
|
79
|
+
},
|
|
80
|
+
};
|
|
@@ -19,6 +19,6 @@ declare class WebdriverReporter extends WDIOReporter {
|
|
|
19
19
|
*/
|
|
20
20
|
addBddScenario(scenario: import("../../types/types.js").WebdriverIOScenario): Promise<import("../../types/types.js").PipeResult[]>;
|
|
21
21
|
}
|
|
22
|
-
import WDIOReporter from '@wdio/reporter';
|
|
22
|
+
import { default as WDIOReporter } from '@wdio/reporter';
|
|
23
23
|
import TestomatClient from '../client.js';
|
|
24
24
|
import { RunnerStats } from '@wdio/reporter';
|
package/lib/adapter/webdriver.js
CHANGED
|
@@ -15,18 +15,27 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
37
|
};
|
|
28
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
// eslint-disable-next-line
|
|
30
39
|
const reporter_1 = __importStar(require("@wdio/reporter"));
|
|
31
40
|
const client_js_1 = __importDefault(require("../client.js"));
|
|
32
41
|
const utils_js_1 = require("../utils/utils.js");
|
|
@@ -92,6 +101,7 @@ class WebdriverReporter extends reporter_1.default {
|
|
|
92
101
|
.filter(el => el.endpoint === screenshotEndpoint && el.result && el.result.value)
|
|
93
102
|
.map(el => Buffer.from(el.result.value, 'base64'));
|
|
94
103
|
await this.client.addTestRun(state, {
|
|
104
|
+
rid: test.uid || '',
|
|
95
105
|
manuallyAttachedArtifacts: test.artifacts,
|
|
96
106
|
error,
|
|
97
107
|
logs: test.logs,
|
package/lib/bin/cli.js
CHANGED
|
@@ -6,22 +6,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
const commander_1 = require("commander");
|
|
8
8
|
const cross_spawn_1 = require("cross-spawn");
|
|
9
|
-
const glob_1 =
|
|
9
|
+
const glob_1 = require("glob");
|
|
10
10
|
const debug_1 = __importDefault(require("debug"));
|
|
11
11
|
const client_js_1 = __importDefault(require("../client.js"));
|
|
12
12
|
const xmlReader_js_1 = __importDefault(require("../xmlReader.js"));
|
|
13
13
|
const constants_js_1 = require("../constants.js");
|
|
14
|
-
const package_json_1 = require("../../package.json");
|
|
15
|
-
const config_js_1 = require("../config.js");
|
|
16
14
|
const utils_js_1 = require("../utils/utils.js");
|
|
15
|
+
const config_js_1 = require("../config.js");
|
|
16
|
+
const utils_js_2 = require("../utils/utils.js");
|
|
17
17
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
18
18
|
const filesize_1 = require("filesize");
|
|
19
19
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
20
|
+
const replay_js_1 = __importDefault(require("../replay.js"));
|
|
20
21
|
const debug = (0, debug_1.default)('@testomatio/reporter:xml-cli');
|
|
21
|
-
|
|
22
|
+
const version = (0, utils_js_1.getPackageVersion)();
|
|
23
|
+
console.log(picocolors_1.default.cyan(picocolors_1.default.bold(` 🤩 Testomat.io Reporter v${version}`)));
|
|
22
24
|
const program = new commander_1.Command();
|
|
23
25
|
program
|
|
24
|
-
.version(
|
|
26
|
+
.version(version)
|
|
25
27
|
.option('--env-file <envfile>', 'Load environment variables from env file')
|
|
26
28
|
.hook('preAction', thisCommand => {
|
|
27
29
|
const opts = thisCommand.opts();
|
|
@@ -48,7 +50,7 @@ program
|
|
|
48
50
|
.command('finish')
|
|
49
51
|
.description('Finish Run by its ID')
|
|
50
52
|
.action(async () => {
|
|
51
|
-
process.env.TESTOMATIO_RUN ||= (0,
|
|
53
|
+
process.env.TESTOMATIO_RUN ||= (0, utils_js_2.readLatestRunId)();
|
|
52
54
|
if (!process.env.TESTOMATIO_RUN) {
|
|
53
55
|
console.log('TESTOMATIO_RUN environment variable must be set or restored from a previous run.');
|
|
54
56
|
return process.exit(1);
|
|
@@ -109,6 +111,27 @@ program
|
|
|
109
111
|
runTests();
|
|
110
112
|
}
|
|
111
113
|
});
|
|
114
|
+
// program
|
|
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
|
+
// }
|
|
112
135
|
program
|
|
113
136
|
.command('xml')
|
|
114
137
|
.description('Parse XML reports and upload to Testomat.io')
|
|
@@ -126,7 +149,7 @@ program
|
|
|
126
149
|
javaTests = 'src/test/java';
|
|
127
150
|
lang = lang?.toLowerCase();
|
|
128
151
|
const runReader = new xmlReader_js_1.default({ javaTests, lang });
|
|
129
|
-
const files = glob_1.
|
|
152
|
+
const files = glob_1.glob.sync(pattern, { cwd: opts.dir || process.cwd() });
|
|
130
153
|
if (!files.length) {
|
|
131
154
|
console.log(constants_js_1.APP_PREFIX, `Report can't be created. No XML files found 😥`);
|
|
132
155
|
process.exit(1);
|
|
@@ -159,7 +182,7 @@ program
|
|
|
159
182
|
.action(async (opts) => {
|
|
160
183
|
const apiKey = config_js_1.config.TESTOMATIO;
|
|
161
184
|
process.env.TESTOMATIO_DISABLE_ARTIFACTS = '';
|
|
162
|
-
const runId = process.env.TESTOMATIO_RUN || process.env.runId || (0,
|
|
185
|
+
const runId = process.env.TESTOMATIO_RUN || process.env.runId || (0, utils_js_2.readLatestRunId)();
|
|
163
186
|
if (!runId) {
|
|
164
187
|
console.log('TESTOMATIO_RUN environment variable must be set or restored from a previous run.');
|
|
165
188
|
return process.exit(1);
|
|
@@ -222,6 +245,48 @@ program
|
|
|
222
245
|
});
|
|
223
246
|
}
|
|
224
247
|
});
|
|
248
|
+
program
|
|
249
|
+
.command('replay')
|
|
250
|
+
.description('Replay test data from debug file and re-send to Testomat.io')
|
|
251
|
+
.argument('[debug-file]', 'Path to debug file (defaults to /tmp/testomatio.debug.latest.json)')
|
|
252
|
+
.option('--dry-run', 'Preview the data without sending to Testomat.io')
|
|
253
|
+
.action(async (debugFile, opts) => {
|
|
254
|
+
try {
|
|
255
|
+
const replayService = new replay_js_1.default({
|
|
256
|
+
apiKey: config_js_1.config.TESTOMATIO,
|
|
257
|
+
dryRun: opts.dryRun,
|
|
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);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
225
290
|
program.parse(process.argv);
|
|
226
291
|
if (!process.argv.slice(2).length) {
|
|
227
292
|
program.outputHelp();
|
package/lib/bin/reportXml.js
CHANGED
|
@@ -10,10 +10,12 @@ const glob_1 = require("glob");
|
|
|
10
10
|
const debug_1 = __importDefault(require("debug"));
|
|
11
11
|
const constants_js_1 = require("../constants.js");
|
|
12
12
|
const xmlReader_js_1 = __importDefault(require("../xmlReader.js"));
|
|
13
|
-
const
|
|
13
|
+
const utils_js_1 = require("../utils/utils.js");
|
|
14
14
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
const version = (0, utils_js_1.getPackageVersion)();
|
|
15
17
|
const debug = (0, debug_1.default)('@testomatio/reporter:xml-cli');
|
|
16
|
-
console.log(picocolors_1.default.cyan(picocolors_1.default.bold(` 🤩 Testomat.io XML Reporter v${
|
|
18
|
+
console.log(picocolors_1.default.cyan(picocolors_1.default.bold(` 🤩 Testomat.io XML Reporter v${version}`)));
|
|
17
19
|
const program = new commander_1.Command();
|
|
18
20
|
program
|
|
19
21
|
.arguments('<pattern>')
|
package/lib/bin/startTest.js
CHANGED
|
@@ -9,10 +9,11 @@ const commander_1 = require("commander");
|
|
|
9
9
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
10
10
|
const client_js_1 = __importDefault(require("../client.js"));
|
|
11
11
|
const constants_js_1 = require("../constants.js");
|
|
12
|
-
const
|
|
12
|
+
const utils_js_1 = require("../utils/utils.js");
|
|
13
13
|
const config_js_1 = require("../config.js");
|
|
14
14
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
15
|
-
|
|
15
|
+
const version = (0, utils_js_1.getPackageVersion)();
|
|
16
|
+
console.log(picocolors_1.default.cyan(picocolors_1.default.bold(` 🤩 Testomat.io Reporter v${version}`)));
|
|
16
17
|
const program = new commander_1.Command();
|
|
17
18
|
program
|
|
18
19
|
.option('-c, --command <cmd>', 'Test runner command')
|
|
@@ -9,12 +9,13 @@ const picocolors_1 = __importDefault(require("picocolors"));
|
|
|
9
9
|
const debug_1 = __importDefault(require("debug"));
|
|
10
10
|
const client_js_1 = __importDefault(require("../client.js"));
|
|
11
11
|
const constants_js_1 = require("../constants.js");
|
|
12
|
-
const package_json_1 = require("../../package.json");
|
|
13
|
-
const config_js_1 = require("../config.js");
|
|
14
12
|
const utils_js_1 = require("../utils/utils.js");
|
|
13
|
+
const config_js_1 = require("../config.js");
|
|
14
|
+
const utils_js_2 = require("../utils/utils.js");
|
|
15
15
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
16
16
|
const debug = (0, debug_1.default)('@testomatio/reporter:upload-cli');
|
|
17
|
-
|
|
17
|
+
const version = (0, utils_js_1.getPackageVersion)();
|
|
18
|
+
console.log(picocolors_1.default.cyan(picocolors_1.default.bold(` 🤩 Testomat.io Reporter v${version}`)));
|
|
18
19
|
const program = new commander_1.Command();
|
|
19
20
|
program
|
|
20
21
|
.option('--env-file <envfile>', 'Load environment variables from env file')
|
|
@@ -28,7 +29,7 @@ program
|
|
|
28
29
|
}
|
|
29
30
|
const apiKey = config_js_1.config.TESTOMATIO;
|
|
30
31
|
process.env.TESTOMATIO_DISABLE_ARTIFACTS = '';
|
|
31
|
-
const runId = process.env.TESTOMATIO_RUN || process.env.runId || (0,
|
|
32
|
+
const runId = process.env.TESTOMATIO_RUN || process.env.runId || (0, utils_js_2.readLatestRunId)();
|
|
32
33
|
if (!runId) {
|
|
33
34
|
console.log('TESTOMATIO_RUN environment variable must be set or restored from a previous run.');
|
|
34
35
|
return process.exit(1);
|
package/lib/client.js
CHANGED
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
37
|
};
|
|
@@ -55,7 +65,6 @@ class Client {
|
|
|
55
65
|
* Create a Testomat client instance
|
|
56
66
|
* @returns
|
|
57
67
|
*/
|
|
58
|
-
// eslint-disable-next-line
|
|
59
68
|
constructor(params = {}) {
|
|
60
69
|
this.paramsForPipesFactory = params;
|
|
61
70
|
this.pipeStore = {};
|
|
@@ -98,7 +107,7 @@ class Client {
|
|
|
98
107
|
}
|
|
99
108
|
try {
|
|
100
109
|
const filterPipe = this.pipes.find(p => p.constructor.name.toLowerCase() === `${pipe.toLowerCase()}pipe`);
|
|
101
|
-
if (!filterPipe
|
|
110
|
+
if (!filterPipe?.isEnabled) {
|
|
102
111
|
// TODO:for the future for the another pipes
|
|
103
112
|
console.warn(constants_js_1.APP_PREFIX, `At the moment processing is available only for the "testomatio" key. Example: "testomatio:tag-name=xxx"`);
|
|
104
113
|
return;
|
package/lib/config.js
CHANGED
|
@@ -9,10 +9,10 @@ const debug_1 = __importDefault(require("debug"));
|
|
|
9
9
|
const debug = (0, debug_1.default)('@testomatio/reporter:config');
|
|
10
10
|
/* for possibility to use multiple env files (reading different paths)
|
|
11
11
|
const envFileVars = dotenv.config({ path: '.env' }).parsed; */
|
|
12
|
-
if (process.env.TESTOMATIO_API_KEY) {
|
|
12
|
+
if (process.env.TESTOMATIO_API_KEY && !process.env.TESTOMATIO) {
|
|
13
13
|
process.env.TESTOMATIO = process.env.TESTOMATIO_API_KEY;
|
|
14
14
|
}
|
|
15
|
-
if (process.env.TESTOMATIO_TOKEN) {
|
|
15
|
+
if (process.env.TESTOMATIO_TOKEN && !process.env.TESTOMATIO) {
|
|
16
16
|
process.env.TESTOMATIO = process.env.TESTOMATIO_TOKEN;
|
|
17
17
|
}
|
|
18
18
|
if (process.env.TESTOMATIO === 'undefined')
|
package/lib/data-storage.d.ts
CHANGED
package/lib/data-storage.js
CHANGED
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
37
|
};
|
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const path_1 = __importDefault(require("path"));
|
|
6
7
|
const adapter_js_1 = __importDefault(require("./adapter.js"));
|
|
7
8
|
class CSharpAdapter extends adapter_js_1.default {
|
|
8
9
|
formatTest(t) {
|
|
@@ -12,9 +13,18 @@ class CSharpAdapter extends adapter_js_1.default {
|
|
|
12
13
|
t.example = { ...example[1].split(',') };
|
|
13
14
|
const suite = t.suite_title.split('.');
|
|
14
15
|
t.suite_title = suite.pop();
|
|
15
|
-
t.file =
|
|
16
|
+
t.file = namespaceToFileName(t.file);
|
|
16
17
|
t.title = title.trim();
|
|
17
18
|
return t;
|
|
18
19
|
}
|
|
20
|
+
getFilePath(t) {
|
|
21
|
+
const fileName = namespaceToFileName(t.file);
|
|
22
|
+
return fileName;
|
|
23
|
+
}
|
|
19
24
|
}
|
|
20
25
|
module.exports = CSharpAdapter;
|
|
26
|
+
function namespaceToFileName(fileName) {
|
|
27
|
+
const fileParts = fileName.split('.');
|
|
28
|
+
fileParts[fileParts.length - 1] = fileParts[fileParts.length - 1]?.replace(/\$.*/, '');
|
|
29
|
+
return `${fileParts.join(path_1.default.sep)}.cs`;
|
|
30
|
+
}
|
package/lib/pipe/bitbucket.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export class BitbucketPipe {
|
|
|
11
11
|
tests: any[];
|
|
12
12
|
token: any;
|
|
13
13
|
hiddenCommentData: string;
|
|
14
|
+
client: Gaxios;
|
|
14
15
|
cleanLog(log: any): Promise<string>;
|
|
15
16
|
prepareRun(): Promise<void>;
|
|
16
17
|
createRun(): Promise<void>;
|
|
@@ -21,3 +22,4 @@ export class BitbucketPipe {
|
|
|
21
22
|
}
|
|
22
23
|
export type Pipe = import("../../types/types.js").Pipe;
|
|
23
24
|
export type TestData = import("../../types/types.js").TestData;
|
|
25
|
+
import { Gaxios } from 'gaxios';
|
package/lib/pipe/bitbucket.js
CHANGED
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
37
|
};
|
|
@@ -30,7 +40,7 @@ exports.BitbucketPipe = void 0;
|
|
|
30
40
|
const constants_js_1 = require("../constants.js");
|
|
31
41
|
const utils_js_1 = require("../utils/utils.js");
|
|
32
42
|
const pipe_utils_js_1 = require("../utils/pipe_utils.js");
|
|
33
|
-
const
|
|
43
|
+
const gaxios_1 = require("gaxios");
|
|
34
44
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
35
45
|
const humanize_duration_1 = __importDefault(require("humanize-duration"));
|
|
36
46
|
const lodash_merge_1 = __importDefault(require("lodash.merge"));
|
|
@@ -59,6 +69,13 @@ class BitbucketPipe {
|
|
|
59
69
|
return;
|
|
60
70
|
}
|
|
61
71
|
this.isEnabled = true;
|
|
72
|
+
this.client = new gaxios_1.Gaxios({
|
|
73
|
+
baseURL: 'https://api.bitbucket.org/2.0',
|
|
74
|
+
headers: {
|
|
75
|
+
'Content-Type': 'application/json',
|
|
76
|
+
'Authorization': `Bearer ${this.token}`
|
|
77
|
+
}
|
|
78
|
+
});
|
|
62
79
|
debug('Bitbucket Pipe: Enabled');
|
|
63
80
|
}
|
|
64
81
|
async cleanLog(log) {
|
|
@@ -158,18 +175,17 @@ class BitbucketPipe {
|
|
|
158
175
|
}
|
|
159
176
|
// Construct Bitbucket API URL for comments
|
|
160
177
|
// eslint-disable-next-line max-len
|
|
161
|
-
const commentsRequestURL =
|
|
178
|
+
const commentsRequestURL = `/repositories/${this.ENV.BITBUCKET_WORKSPACE}/${this.ENV.BITBUCKET_REPO_SLUG}/pullrequests/${this.ENV.BITBUCKET_PR_ID}/comments`;
|
|
162
179
|
// Delete previous report
|
|
163
|
-
await deletePreviousReport(
|
|
180
|
+
await deletePreviousReport(this.client, commentsRequestURL, this.hiddenCommentData);
|
|
164
181
|
// Add current report
|
|
165
182
|
debug(`Adding comment via URL: ${commentsRequestURL}`);
|
|
166
183
|
debug(`Final Bitbucket API call body: ${body}`);
|
|
167
184
|
try {
|
|
168
|
-
const addCommentResponse = await
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
},
|
|
185
|
+
const addCommentResponse = await this.client.request({
|
|
186
|
+
method: 'POST',
|
|
187
|
+
url: commentsRequestURL,
|
|
188
|
+
data: { content: { raw: body } }
|
|
173
189
|
});
|
|
174
190
|
const commentID = addCommentResponse.data.id;
|
|
175
191
|
// eslint-disable-next-line max-len
|
|
@@ -188,17 +204,15 @@ class BitbucketPipe {
|
|
|
188
204
|
updateRun() { }
|
|
189
205
|
}
|
|
190
206
|
exports.BitbucketPipe = BitbucketPipe;
|
|
191
|
-
async function deletePreviousReport(
|
|
207
|
+
async function deletePreviousReport(client, commentsRequestURL, hiddenCommentData) {
|
|
192
208
|
if (process.env.BITBUCKET_KEEP_OUTDATED_REPORTS)
|
|
193
209
|
return;
|
|
194
210
|
// Get comments
|
|
195
211
|
let comments = [];
|
|
196
212
|
try {
|
|
197
|
-
const response = await
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
'Content-Type': 'application/json',
|
|
201
|
-
},
|
|
213
|
+
const response = await client.request({
|
|
214
|
+
method: 'GET',
|
|
215
|
+
url: commentsRequestURL
|
|
202
216
|
});
|
|
203
217
|
comments = response.data.values;
|
|
204
218
|
}
|
|
@@ -213,11 +227,9 @@ async function deletePreviousReport(axiosInstance, commentsRequestURL, hiddenCom
|
|
|
213
227
|
try {
|
|
214
228
|
// Delete previous comment
|
|
215
229
|
const deleteCommentURL = `${commentsRequestURL}/${comment.id}`;
|
|
216
|
-
await
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
'Content-Type': 'application/json',
|
|
220
|
-
},
|
|
230
|
+
await client.request({
|
|
231
|
+
method: 'DELETE',
|
|
232
|
+
url: deleteCommentURL
|
|
221
233
|
});
|
|
222
234
|
}
|
|
223
235
|
catch (e) {
|