@testomatio/reporter 2.1.0-beta-nightwatch → 2.1.0-beta.1-codeceptjs
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/lib/adapter/codecept.js +288 -202
- package/lib/adapter/cypress-plugin/index.js +0 -2
- package/lib/adapter/mocha.js +0 -1
- package/lib/adapter/nightwatch.js +5 -5
- package/lib/adapter/playwright.js +11 -3
- 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 +30 -10
- package/lib/data-storage.d.ts +5 -5
- package/lib/data-storage.js +23 -13
- 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 +27 -6
- 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.js +0 -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 +255 -0
- package/lib/reporter-functions.d.ts +7 -0
- package/lib/reporter-functions.js +36 -0
- package/lib/reporter.d.ts +15 -12
- package/lib/reporter.js +4 -1
- package/lib/services/artifacts.d.ts +1 -1
- package/lib/services/index.d.ts +2 -0
- package/lib/services/index.js +2 -0
- package/lib/services/key-values.d.ts +1 -1
- package/lib/services/labels.d.ts +22 -0
- package/lib/services/labels.js +62 -0
- 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/constants.d.ts +12 -0
- package/lib/utils/constants.js +15 -0
- package/lib/utils/utils.d.ts +10 -1
- package/lib/utils/utils.js +70 -22
- package/lib/xmlReader.js +54 -19
- package/package.json +16 -11
- package/src/adapter/codecept.js +320 -214
- package/src/adapter/cypress-plugin/index.js +0 -2
- package/src/adapter/mocha.js +0 -1
- package/src/adapter/nightwatch.js +1 -1
- package/src/adapter/playwright.js +10 -7
- 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 +18 -3
- package/src/data-storage.js +6 -6
- package/src/junit-adapter/csharp.js +13 -1
- package/src/pipe/bitbucket.js +22 -24
- package/src/pipe/debug.js +26 -5
- package/src/pipe/github.js +1 -2
- package/src/pipe/gitlab.js +27 -9
- package/src/pipe/html.js +1 -4
- package/src/pipe/testomatio.js +106 -105
- package/src/replay.js +262 -0
- package/src/reporter-functions.js +41 -0
- package/src/reporter.js +3 -0
- package/src/services/index.js +2 -0
- package/src/services/labels.js +59 -0
- package/src/services/logger.js +1 -2
- package/src/template/testomatio.hbs +443 -68
- package/src/uploader.js +11 -6
- package/src/utils/constants.js +12 -0
- package/src/utils/utils.js +46 -13
- package/src/xmlReader.js +70 -18
|
@@ -14,6 +14,7 @@ const client_js_1 = __importDefault(require("../client.js"));
|
|
|
14
14
|
const utils_js_1 = require("../utils/utils.js");
|
|
15
15
|
const index_js_1 = require("../services/index.js");
|
|
16
16
|
const data_storage_js_1 = require("../data-storage.js");
|
|
17
|
+
const constants_js_2 = require("../utils/constants.js");
|
|
17
18
|
const reportTestPromises = [];
|
|
18
19
|
class PlaywrightReporter {
|
|
19
20
|
constructor(config = {}) {
|
|
@@ -98,6 +99,10 @@ class PlaywrightReporter {
|
|
|
98
99
|
projectDependencies: project.dependencies?.length ? project.dependencies : null,
|
|
99
100
|
...testMeta,
|
|
100
101
|
...project.metadata, // metadata has any type (in playwright), but we will stringify it in client.js
|
|
102
|
+
...test.annotations?.reduce((acc, annotation) => {
|
|
103
|
+
acc[annotation.type] = annotation.description;
|
|
104
|
+
return acc;
|
|
105
|
+
}, {}),
|
|
101
106
|
},
|
|
102
107
|
file: test.location?.file,
|
|
103
108
|
});
|
|
@@ -119,9 +124,12 @@ class PlaywrightReporter {
|
|
|
119
124
|
}
|
|
120
125
|
if (artifact.body) {
|
|
121
126
|
let filePath = generateTmpFilepath(artifact.name);
|
|
122
|
-
const
|
|
123
|
-
if (
|
|
124
|
-
|
|
127
|
+
const hasExtension = artifact.name && path_1.default.extname(artifact.name);
|
|
128
|
+
if (!hasExtension && artifact.contentType) {
|
|
129
|
+
const extension = constants_js_2.extensionMap[artifact.contentType] || artifact.contentType.split('/')[1];
|
|
130
|
+
if (extension)
|
|
131
|
+
filePath += `.${extension}`;
|
|
132
|
+
}
|
|
125
133
|
fs_1.default.writeFileSync(filePath, artifact.body);
|
|
126
134
|
return filePath;
|
|
127
135
|
}
|
|
@@ -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 = {};
|
|
@@ -163,10 +172,14 @@ class Client {
|
|
|
163
172
|
title: 'Unknown test',
|
|
164
173
|
suite_title: 'Unknown suite',
|
|
165
174
|
};
|
|
175
|
+
// Add timestamp if not already present (microseconds since Unix epoch)
|
|
176
|
+
if (!testData.timestamp && !process.env.TESTOMATIO_NO_TIMESTAMP) {
|
|
177
|
+
testData.timestamp = Math.floor((performance.timeOrigin + performance.now()) * 1000);
|
|
178
|
+
}
|
|
166
179
|
/**
|
|
167
180
|
* @type {TestData}
|
|
168
181
|
*/
|
|
169
|
-
const { rid, error = null, time = 0, example = null, files = [], filesBuffers = [], steps, code = null, title, file, suite_title, suite_id, test_id, manuallyAttachedArtifacts, } = testData;
|
|
182
|
+
const { rid, error = null, time = 0, example = null, files = [], filesBuffers = [], steps, code = null, title, file, suite_title, suite_id, test_id, timestamp, manuallyAttachedArtifacts, labels, } = testData;
|
|
170
183
|
let { message = '', meta = {} } = testData;
|
|
171
184
|
// stringify meta values and limit keys and values length to 255
|
|
172
185
|
meta = Object.entries(meta)
|
|
@@ -205,6 +218,7 @@ class Client {
|
|
|
205
218
|
acc[key] = value;
|
|
206
219
|
return acc;
|
|
207
220
|
}, {});
|
|
221
|
+
// Labels are simple array of strings, no processing needed
|
|
208
222
|
let errorFormatted = '';
|
|
209
223
|
if (error) {
|
|
210
224
|
errorFormatted += this.formatError(error) || '';
|
|
@@ -231,6 +245,9 @@ class Client {
|
|
|
231
245
|
uploadedFiles.push(this.uploader.uploadFileAsBuffer(buffer, [this.runId, rid, fileName]));
|
|
232
246
|
}
|
|
233
247
|
const artifacts = (await Promise.all(uploadedFiles)).filter(n => !!n);
|
|
248
|
+
const workspaceDir = process.env.TESTOMATIO_WORKDIR || process.cwd();
|
|
249
|
+
const relativeFile = file ? path_1.default.relative(workspaceDir, file) : file;
|
|
250
|
+
const rootSuiteId = (0, utils_js_1.validateSuiteId)(process.env.TESTOMATIO_SUITE);
|
|
234
251
|
const data = {
|
|
235
252
|
rid,
|
|
236
253
|
files,
|
|
@@ -238,7 +255,7 @@ class Client {
|
|
|
238
255
|
status,
|
|
239
256
|
stack: fullLogs,
|
|
240
257
|
example,
|
|
241
|
-
file,
|
|
258
|
+
file: relativeFile,
|
|
242
259
|
code,
|
|
243
260
|
title,
|
|
244
261
|
suite_title,
|
|
@@ -246,8 +263,11 @@ class Client {
|
|
|
246
263
|
test_id,
|
|
247
264
|
message,
|
|
248
265
|
run_time: typeof time === 'number' ? time : parseFloat(time),
|
|
266
|
+
timestamp,
|
|
249
267
|
artifacts,
|
|
250
268
|
meta,
|
|
269
|
+
labels,
|
|
270
|
+
...(rootSuiteId && { root_suite_id: rootSuiteId }),
|
|
251
271
|
};
|
|
252
272
|
// debug('Adding test run...', data);
|
|
253
273
|
// @ts-ignore
|
package/lib/data-storage.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const dataStorage: DataStorage;
|
|
2
2
|
declare class DataStorage {
|
|
3
|
-
static "__#
|
|
3
|
+
static "__#12@#instance": any;
|
|
4
4
|
/**
|
|
5
5
|
*
|
|
6
6
|
* @returns {DataStorage}
|
|
@@ -12,22 +12,22 @@ declare class DataStorage {
|
|
|
12
12
|
/**
|
|
13
13
|
* Puts any data to storage (file or global variable).
|
|
14
14
|
* If file: stores data as text, if global variable – stores as array of data.
|
|
15
|
-
* @param {'log' | 'artifact' | 'keyvalue'} dataType
|
|
15
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
16
16
|
* @param {*} data anything you want to store (string, object, array, etc)
|
|
17
17
|
* @param {*} context could be testId or any context (test name, suite name, including their IDs etc)
|
|
18
18
|
* suite name + test name is used by default
|
|
19
19
|
* @returns
|
|
20
20
|
*/
|
|
21
|
-
putData(dataType: "log" | "artifact" | "keyvalue", data: any, context?: any): void;
|
|
21
|
+
putData(dataType: "log" | "artifact" | "keyvalue" | "labels", data: any, context?: any): void;
|
|
22
22
|
/**
|
|
23
23
|
* Returns data, stored for specific test/context (or data which was stored without test id specified).
|
|
24
24
|
* This method will get data from global variable and/or from from file (previosly saved with put method).
|
|
25
25
|
*
|
|
26
|
-
* @param {'log' | 'artifact' | 'keyvalue'} dataType
|
|
26
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
27
27
|
* @param {string} context
|
|
28
28
|
* @returns {any []} array of data (any type), null (if no data found for context) or string (if data type is log)
|
|
29
29
|
*/
|
|
30
|
-
getData(dataType: "log" | "artifact" | "keyvalue", context: string): any[];
|
|
30
|
+
getData(dataType: "log" | "artifact" | "keyvalue" | "labels", context: string): any[];
|
|
31
31
|
#private;
|
|
32
32
|
}
|
|
33
33
|
export function stringToMD5Hash(str: any): string;
|
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
|
};
|
|
@@ -65,7 +75,7 @@ class DataStorage {
|
|
|
65
75
|
/**
|
|
66
76
|
* Puts any data to storage (file or global variable).
|
|
67
77
|
* If file: stores data as text, if global variable – stores as array of data.
|
|
68
|
-
* @param {'log' | 'artifact' | 'keyvalue'} dataType
|
|
78
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
69
79
|
* @param {*} data anything you want to store (string, object, array, etc)
|
|
70
80
|
* @param {*} context could be testId or any context (test name, suite name, including their IDs etc)
|
|
71
81
|
* suite name + test name is used by default
|
|
@@ -93,7 +103,7 @@ class DataStorage {
|
|
|
93
103
|
* Returns data, stored for specific test/context (or data which was stored without test id specified).
|
|
94
104
|
* This method will get data from global variable and/or from from file (previosly saved with put method).
|
|
95
105
|
*
|
|
96
|
-
* @param {'log' | 'artifact' | 'keyvalue'} dataType
|
|
106
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
97
107
|
* @param {string} context
|
|
98
108
|
* @returns {any []} array of data (any type), null (if no data found for context) or string (if data type is log)
|
|
99
109
|
*/
|
|
@@ -124,7 +134,7 @@ class DataStorage {
|
|
|
124
134
|
return null;
|
|
125
135
|
}
|
|
126
136
|
/**
|
|
127
|
-
* @param {'log' | 'artifact' | 'keyvalue'} dataType
|
|
137
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
128
138
|
* @param {string} context
|
|
129
139
|
* @returns aray of data (any type)
|
|
130
140
|
*/
|
|
@@ -144,7 +154,7 @@ class DataStorage {
|
|
|
144
154
|
}
|
|
145
155
|
}
|
|
146
156
|
/**
|
|
147
|
-
* @param {'log' | 'artifact' | 'keyvalue'} dataType
|
|
157
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
148
158
|
* @param {*} context
|
|
149
159
|
* @returns array of data (any type)
|
|
150
160
|
*/
|
|
@@ -169,7 +179,7 @@ class DataStorage {
|
|
|
169
179
|
}
|
|
170
180
|
/**
|
|
171
181
|
* Puts data to global variable. Unlike the file storage, stores data in array (file storage just append as string).
|
|
172
|
-
* @param {'log' | 'artifact' | 'keyvalue'} dataType
|
|
182
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
173
183
|
* @param {*} data
|
|
174
184
|
* @param {*} context
|
|
175
185
|
*/
|
|
@@ -185,7 +195,7 @@ class DataStorage {
|
|
|
185
195
|
}
|
|
186
196
|
/**
|
|
187
197
|
* Puts data to file. Unlike the global variable storage, stores data as string
|
|
188
|
-
* @param {'log' | 'artifact' | 'keyvalue'} dataType
|
|
198
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
189
199
|
* @param {*} data
|
|
190
200
|
* @param {string} context
|
|
191
201
|
* @returns
|
|
@@ -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';
|