@testomatio/reporter 2.1.3-beta.2-xml-import → 2.1.3-beta.3-multi-links
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 +3 -3
- package/lib/adapter/mocha.js +0 -14
- package/lib/adapter/webdriver.js +4 -6
- package/lib/bin/startTest.js +91 -38
- package/lib/client.js +3 -6
- package/lib/data-storage.d.ts +4 -4
- package/lib/data-storage.js +8 -7
- package/lib/pipe/testomatio.js +2 -1
- package/lib/reporter-functions.d.ts +7 -20
- package/lib/reporter-functions.js +35 -27
- package/lib/reporter.d.ts +20 -22
- package/lib/reporter.js +7 -9
- package/lib/services/artifacts.d.ts +1 -1
- package/lib/services/index.d.ts +2 -2
- package/lib/services/index.js +2 -2
- package/lib/services/key-values.d.ts +1 -1
- package/lib/services/labels.d.ts +1 -1
- package/lib/services/labels.js +2 -2
- package/lib/services/logger.d.ts +1 -1
- package/lib/utils/cli_utils.d.ts +1 -0
- package/lib/utils/cli_utils.js +524304 -0
- package/lib/utils/utils.js +1 -3
- package/lib/xmlReader.d.ts +0 -7
- package/lib/xmlReader.js +9 -231
- package/package.json +1 -1
- package/src/adapter/codecept.js +4 -3
- package/src/adapter/mocha.js +0 -15
- package/src/adapter/webdriver.js +4 -6
- package/src/bin/startTest.js +114 -43
- package/src/client.js +3 -5
- package/src/data-storage.js +9 -7
- package/src/pipe/testomatio.js +2 -1
- package/src/reporter-functions.js +37 -27
- package/src/reporter.js +6 -8
- package/src/services/index.js +2 -2
- package/src/services/labels.js +2 -2
- package/src/utils/utils.js +3 -5
- package/src/xmlReader.js +9 -267
- package/src/services/links.js +0 -69
package/lib/adapter/codecept.js
CHANGED
|
@@ -48,6 +48,7 @@ function CodeceptReporter(config) {
|
|
|
48
48
|
step: output.step,
|
|
49
49
|
say: output.say,
|
|
50
50
|
};
|
|
51
|
+
output.stepShift = 0;
|
|
51
52
|
output.debug = function (msg) {
|
|
52
53
|
originalOutput.debug(msg);
|
|
53
54
|
data_storage_js_1.dataStorage.putData('log', repeat(this?.stepShift || 0) + picocolors_1.default.cyan(msg.toString()));
|
|
@@ -61,7 +62,6 @@ function CodeceptReporter(config) {
|
|
|
61
62
|
originalOutput.log(msg);
|
|
62
63
|
data_storage_js_1.dataStorage.putData('log', repeat(this?.stepShift || 0) + picocolors_1.default.gray(msg));
|
|
63
64
|
};
|
|
64
|
-
output.stepShift = 0;
|
|
65
65
|
recorder.startUnlessRunning();
|
|
66
66
|
const hookSteps = new Map();
|
|
67
67
|
let currentHook = null;
|
|
@@ -140,7 +140,7 @@ function CodeceptReporter(config) {
|
|
|
140
140
|
const manuallyAttachedArtifacts = index_js_1.services.artifacts.get(test.fullTitle());
|
|
141
141
|
const keyValues = index_js_1.services.keyValues.get(test.fullTitle());
|
|
142
142
|
const stepHierarchy = buildUnifiedStepHierarchy(test.steps, hookSteps);
|
|
143
|
-
const
|
|
143
|
+
const labels = index_js_1.services.labels.get(test.fullTitle());
|
|
144
144
|
index_js_1.services.setContext(null);
|
|
145
145
|
client.addTestRun(test.state, {
|
|
146
146
|
...stripExampleFromTitle(title),
|
|
@@ -153,7 +153,7 @@ function CodeceptReporter(config) {
|
|
|
153
153
|
files,
|
|
154
154
|
steps: stepHierarchy, // Array of step objects per API schema
|
|
155
155
|
logs,
|
|
156
|
-
|
|
156
|
+
labels,
|
|
157
157
|
manuallyAttachedArtifacts,
|
|
158
158
|
meta: { ...keyValues, ...test.meta },
|
|
159
159
|
});
|
package/lib/adapter/mocha.js
CHANGED
|
@@ -43,7 +43,6 @@ function MochaReporter(runner, opts) {
|
|
|
43
43
|
const logs = getTestLogs(test);
|
|
44
44
|
const artifacts = index_js_1.services.artifacts.get(test.fullTitle());
|
|
45
45
|
const keyValues = index_js_1.services.keyValues.get(test.fullTitle());
|
|
46
|
-
const links = index_js_1.services.links.get(test.fullTitle());
|
|
47
46
|
client.addTestRun(constants_js_1.STATUS.PASSED, {
|
|
48
47
|
test_id: testId,
|
|
49
48
|
suite_title: getSuiteTitle(test),
|
|
@@ -54,16 +53,12 @@ function MochaReporter(runner, opts) {
|
|
|
54
53
|
logs,
|
|
55
54
|
manuallyAttachedArtifacts: artifacts,
|
|
56
55
|
meta: keyValues,
|
|
57
|
-
links,
|
|
58
56
|
});
|
|
59
57
|
});
|
|
60
58
|
runner.on(EVENT_TEST_PENDING, test => {
|
|
61
59
|
skipped += 1;
|
|
62
60
|
console.log('skip: %s', test.fullTitle());
|
|
63
61
|
const testId = (0, utils_js_1.getTestomatIdFromTestTitle)(test.title);
|
|
64
|
-
const artifacts = index_js_1.services.artifacts.get(test.fullTitle());
|
|
65
|
-
const keyValues = index_js_1.services.keyValues.get(test.fullTitle());
|
|
66
|
-
const links = index_js_1.services.links.get(test.fullTitle());
|
|
67
62
|
client.addTestRun(constants_js_1.STATUS.SKIPPED, {
|
|
68
63
|
title: getTestName(test),
|
|
69
64
|
suite_title: getSuiteTitle(test),
|
|
@@ -71,9 +66,6 @@ function MochaReporter(runner, opts) {
|
|
|
71
66
|
file: getFile(test),
|
|
72
67
|
test_id: testId,
|
|
73
68
|
time: test.duration,
|
|
74
|
-
manuallyAttachedArtifacts: artifacts,
|
|
75
|
-
meta: keyValues,
|
|
76
|
-
links,
|
|
77
69
|
});
|
|
78
70
|
});
|
|
79
71
|
runner.on(EVENT_TEST_FAIL, async (test, err) => {
|
|
@@ -81,9 +73,6 @@ function MochaReporter(runner, opts) {
|
|
|
81
73
|
console.log(picocolors_1.default.bold(picocolors_1.default.red('✖')), test.fullTitle(), picocolors_1.default.gray(err.message));
|
|
82
74
|
const testId = (0, utils_js_1.getTestomatIdFromTestTitle)(test.title);
|
|
83
75
|
const logs = getTestLogs(test);
|
|
84
|
-
const artifacts = index_js_1.services.artifacts.get(test.fullTitle());
|
|
85
|
-
const keyValues = index_js_1.services.keyValues.get(test.fullTitle());
|
|
86
|
-
const links = index_js_1.services.links.get(test.fullTitle());
|
|
87
76
|
client.addTestRun(constants_js_1.STATUS.FAILED, {
|
|
88
77
|
error: err,
|
|
89
78
|
suite_title: getSuiteTitle(test),
|
|
@@ -93,9 +82,6 @@ function MochaReporter(runner, opts) {
|
|
|
93
82
|
code: process.env.TESTOMATIO_UPDATE_CODE ? test.body.toString() : '',
|
|
94
83
|
time: test.duration,
|
|
95
84
|
logs,
|
|
96
|
-
manuallyAttachedArtifacts: artifacts,
|
|
97
|
-
meta: keyValues,
|
|
98
|
-
links,
|
|
99
85
|
});
|
|
100
86
|
});
|
|
101
87
|
runner.on(EVENT_RUN_END, () => {
|
package/lib/adapter/webdriver.js
CHANGED
|
@@ -78,13 +78,11 @@ class WebdriverReporter extends reporter_1.default {
|
|
|
78
78
|
test.suite = test.parent;
|
|
79
79
|
const logs = getTestLogs(test.fullTitle);
|
|
80
80
|
// TODO: FIX: artifacts for some reason leads to empty report on Testomat.io
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
const artifacts = index_js_1.services.artifacts.get(test.fullTitle);
|
|
84
|
-
const keyValues = index_js_1.services.keyValues.get(test.fullTitle);
|
|
81
|
+
// const artifacts = services.artifacts.get(test.fullTitle);
|
|
82
|
+
// const keyValues = services.keyValues.get(test.fullTitle);
|
|
85
83
|
test.logs = logs;
|
|
86
|
-
test.artifacts = artifacts;
|
|
87
|
-
test.meta = keyValues;
|
|
84
|
+
// test.artifacts = artifacts;
|
|
85
|
+
// test.meta = keyValues;
|
|
88
86
|
this._addTestPromises.push(this.addTest(test));
|
|
89
87
|
}
|
|
90
88
|
// wdio-cucumber does not trigger onTestEnd hook, thus, using this one
|
package/lib/bin/startTest.js
CHANGED
|
@@ -4,50 +4,103 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
5
|
};
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const utils_js_1 = require("../utils/utils.js");
|
|
7
|
+
const cross_spawn_1 = require("cross-spawn");
|
|
8
|
+
const commander_1 = require("commander");
|
|
10
9
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
11
|
-
|
|
12
|
-
const
|
|
10
|
+
const client_js_1 = __importDefault(require("../client.js"));
|
|
11
|
+
const constants_js_1 = require("../constants.js");
|
|
12
|
+
const utils_js_1 = require("../utils/utils.js");
|
|
13
|
+
const config_js_1 = require("../config.js");
|
|
14
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
13
15
|
const version = (0, utils_js_1.getPackageVersion)();
|
|
14
16
|
console.log(picocolors_1.default.cyan(picocolors_1.default.bold(` 🤩 Testomat.io Reporter v${version}`)));
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
17
|
+
const program = new commander_1.Command();
|
|
18
|
+
program
|
|
19
|
+
.option('-c, --command <cmd>', 'Test runner command')
|
|
20
|
+
.option('--launch', 'Start a new run and return its ID')
|
|
21
|
+
.option('--finish', 'Finish Run by its ID')
|
|
22
|
+
.option('--env-file <envfile>', 'Load environment variables from env file')
|
|
23
|
+
.option('--filter <filter>', 'Additional execution filter')
|
|
24
|
+
.action(async (opts) => {
|
|
25
|
+
const { launch, finish, filter } = opts;
|
|
26
|
+
let { command } = opts;
|
|
27
|
+
if (opts.envFile)
|
|
28
|
+
dotenv_1.default.config({ path: opts.envFile });
|
|
29
|
+
const apiKey = process.env['INPUT_TESTOMATIO-KEY'] || config_js_1.config.TESTOMATIO;
|
|
30
|
+
const title = process.env.TESTOMATIO_TITLE;
|
|
31
|
+
if (launch) {
|
|
32
|
+
console.log('Starting a new Run on Testomat.io...');
|
|
33
|
+
const client = new client_js_1.default({ apiKey });
|
|
34
|
+
client.createRun().then(() => {
|
|
35
|
+
console.log(process.env.runId);
|
|
36
|
+
process.exit(0);
|
|
37
|
+
});
|
|
38
|
+
return;
|
|
27
39
|
}
|
|
28
|
-
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
if (finish) {
|
|
41
|
+
// TODO: add error in case of TESTOMATIO environment variable is not set
|
|
42
|
+
// because command is fine in console, but actually (on testomat.io) run is not finished
|
|
43
|
+
if (!process.env.TESTOMATIO_RUN) {
|
|
44
|
+
console.log('TESTOMATIO_RUN environment variable must be set.');
|
|
45
|
+
return process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
console.log('Finishing Run on Testomat.io...');
|
|
48
|
+
const client = new client_js_1.default({ apiKey });
|
|
49
|
+
// @ts-ignore
|
|
50
|
+
client.updateRunStatus(constants_js_1.STATUS.FINISHED).then(() => {
|
|
51
|
+
console.log(picocolors_1.default.yellow(`Run ${process.env.TESTOMATIO_RUN} was finished`));
|
|
52
|
+
process.exit(0);
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
32
55
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
56
|
+
let exitCode = 0;
|
|
57
|
+
if (!command.split) {
|
|
58
|
+
process.exitCode = 255;
|
|
59
|
+
console.log(constants_js_1.APP_PREFIX, `No command provided. Use -c option to launch a test runner.`);
|
|
60
|
+
return;
|
|
36
61
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
62
|
+
const client = new client_js_1.default({ apiKey, title, parallel: true });
|
|
63
|
+
if (filter) {
|
|
64
|
+
const [pipe, ...optsArray] = filter.split(':');
|
|
65
|
+
const pipeOptions = optsArray.join(':');
|
|
66
|
+
try {
|
|
67
|
+
const tests = await client.prepareRun({ pipe, pipeOptions });
|
|
68
|
+
if (!tests || tests.length === 0) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const grep = ` --grep (${tests.join('|')})`;
|
|
72
|
+
command += grep;
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
console.log(constants_js_1.APP_PREFIX, err);
|
|
76
|
+
}
|
|
40
77
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
78
|
+
const testCmds = command.split(' ');
|
|
79
|
+
console.log(constants_js_1.APP_PREFIX, `🚀 Running`, picocolors_1.default.green(command));
|
|
80
|
+
if (!apiKey) {
|
|
81
|
+
const cmd = (0, cross_spawn_1.spawn)(testCmds[0], testCmds.slice(1), { stdio: 'inherit' });
|
|
82
|
+
cmd.on('close', code => {
|
|
83
|
+
console.log(constants_js_1.APP_PREFIX, '⚠️ ', `Runner exited with ${picocolors_1.default.bold(code)}, report is ignored`);
|
|
84
|
+
if (code > exitCode)
|
|
85
|
+
exitCode = code;
|
|
86
|
+
process.exitCode = exitCode;
|
|
87
|
+
});
|
|
88
|
+
return;
|
|
44
89
|
}
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
90
|
+
client.createRun().then(() => {
|
|
91
|
+
const cmd = (0, cross_spawn_1.spawn)(testCmds[0], testCmds.slice(1), { stdio: 'inherit' });
|
|
92
|
+
cmd.on('close', code => {
|
|
93
|
+
const emoji = code === 0 ? '🟢' : '🔴';
|
|
94
|
+
console.log(constants_js_1.APP_PREFIX, emoji, `Runner exited with ${picocolors_1.default.bold(code)}`);
|
|
95
|
+
const status = code === 0 ? 'passed' : 'failed';
|
|
96
|
+
client.updateRunStatus(status, true);
|
|
97
|
+
if (code > exitCode)
|
|
98
|
+
exitCode = code;
|
|
99
|
+
process.exitCode = exitCode;
|
|
100
|
+
});
|
|
101
|
+
});
|
|
53
102
|
});
|
|
103
|
+
if (process.argv.length <= 2) {
|
|
104
|
+
program.outputHelp();
|
|
105
|
+
}
|
|
106
|
+
program.parse(process.argv);
|
package/lib/client.js
CHANGED
|
@@ -50,7 +50,6 @@ const path_1 = __importStar(require("path"));
|
|
|
50
50
|
const node_url_1 = require("node:url");
|
|
51
51
|
const uploader_js_1 = require("./uploader.js");
|
|
52
52
|
const utils_js_1 = require("./utils/utils.js");
|
|
53
|
-
const links_js_1 = require("./services/links.js");
|
|
54
53
|
const filesize_1 = require("filesize");
|
|
55
54
|
const debug = (0, debug_1.default)('@testomatio/reporter:client');
|
|
56
55
|
// removed __dirname usage, because:
|
|
@@ -182,7 +181,7 @@ class Client {
|
|
|
182
181
|
/**
|
|
183
182
|
* @type {TestData}
|
|
184
183
|
*/
|
|
185
|
-
const { rid, error = null, time = 0, example = null, files = [], filesBuffers = [], steps, code = null, title, file, suite_title, suite_id, test_id, timestamp, manuallyAttachedArtifacts, overwrite, } = testData;
|
|
184
|
+
const { rid, error = null, time = 0, example = null, files = [], filesBuffers = [], steps, code = null, title, file, suite_title, suite_id, test_id, timestamp, manuallyAttachedArtifacts, labels, overwrite, } = testData;
|
|
186
185
|
let { message = '', meta = {} } = testData;
|
|
187
186
|
// stringify meta values and limit keys and values length to 255
|
|
188
187
|
meta = Object.entries(meta)
|
|
@@ -221,9 +220,7 @@ class Client {
|
|
|
221
220
|
acc[key] = value;
|
|
222
221
|
return acc;
|
|
223
222
|
}, {});
|
|
224
|
-
//
|
|
225
|
-
const testContext = suite_title ? `${suite_title} ${title}` : title;
|
|
226
|
-
const links = links_js_1.linkStorage.get(testContext) || [];
|
|
223
|
+
// Labels are simple array of strings, no processing needed
|
|
227
224
|
let errorFormatted = '';
|
|
228
225
|
if (error) {
|
|
229
226
|
errorFormatted += this.formatError(error) || '';
|
|
@@ -271,7 +268,7 @@ class Client {
|
|
|
271
268
|
timestamp,
|
|
272
269
|
artifacts,
|
|
273
270
|
meta,
|
|
274
|
-
|
|
271
|
+
labels,
|
|
275
272
|
overwrite,
|
|
276
273
|
...(rootSuiteId && { root_suite_id: rootSuiteId }),
|
|
277
274
|
};
|
package/lib/data-storage.d.ts
CHANGED
|
@@ -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' | '
|
|
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" | "
|
|
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' | '
|
|
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" | "
|
|
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
|
@@ -45,6 +45,7 @@ const os_1 = __importDefault(require("os"));
|
|
|
45
45
|
const constants_js_1 = require("./constants.js");
|
|
46
46
|
const utils_js_1 = require("./utils/utils.js");
|
|
47
47
|
const crypto_1 = __importDefault(require("crypto"));
|
|
48
|
+
const startTime = Date.now();
|
|
48
49
|
const debug = (0, debug_1.default)('@testomatio/reporter:storage');
|
|
49
50
|
class DataStorage {
|
|
50
51
|
static #instance;
|
|
@@ -75,7 +76,7 @@ class DataStorage {
|
|
|
75
76
|
/**
|
|
76
77
|
* Puts any data to storage (file or global variable).
|
|
77
78
|
* If file: stores data as text, if global variable – stores as array of data.
|
|
78
|
-
* @param {'log' | 'artifact' | 'keyvalue' | '
|
|
79
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
79
80
|
* @param {*} data anything you want to store (string, object, array, etc)
|
|
80
81
|
* @param {*} context could be testId or any context (test name, suite name, including their IDs etc)
|
|
81
82
|
* suite name + test name is used by default
|
|
@@ -103,7 +104,7 @@ class DataStorage {
|
|
|
103
104
|
* Returns data, stored for specific test/context (or data which was stored without test id specified).
|
|
104
105
|
* This method will get data from global variable and/or from from file (previosly saved with put method).
|
|
105
106
|
*
|
|
106
|
-
* @param {'log' | 'artifact' | 'keyvalue' | '
|
|
107
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
107
108
|
* @param {string} context
|
|
108
109
|
* @returns {any []} array of data (any type), null (if no data found for context) or string (if data type is log)
|
|
109
110
|
*/
|
|
@@ -134,7 +135,7 @@ class DataStorage {
|
|
|
134
135
|
return null;
|
|
135
136
|
}
|
|
136
137
|
/**
|
|
137
|
-
* @param {'log' | 'artifact' | 'keyvalue' | '
|
|
138
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
138
139
|
* @param {string} context
|
|
139
140
|
* @returns aray of data (any type)
|
|
140
141
|
*/
|
|
@@ -154,7 +155,7 @@ class DataStorage {
|
|
|
154
155
|
}
|
|
155
156
|
}
|
|
156
157
|
/**
|
|
157
|
-
* @param {'log' | 'artifact' | 'keyvalue' | '
|
|
158
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
158
159
|
* @param {*} context
|
|
159
160
|
* @returns array of data (any type)
|
|
160
161
|
*/
|
|
@@ -179,7 +180,7 @@ class DataStorage {
|
|
|
179
180
|
}
|
|
180
181
|
/**
|
|
181
182
|
* Puts data to global variable. Unlike the file storage, stores data in array (file storage just append as string).
|
|
182
|
-
* @param {'log' | 'artifact' | 'keyvalue' | '
|
|
183
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
183
184
|
* @param {*} data
|
|
184
185
|
* @param {*} context
|
|
185
186
|
*/
|
|
@@ -195,7 +196,7 @@ class DataStorage {
|
|
|
195
196
|
}
|
|
196
197
|
/**
|
|
197
198
|
* Puts data to file. Unlike the global variable storage, stores data as string
|
|
198
|
-
* @param {'log' | 'artifact' | 'keyvalue' | '
|
|
199
|
+
* @param {'log' | 'artifact' | 'keyvalue' | 'labels'} dataType
|
|
199
200
|
* @param {*} data
|
|
200
201
|
* @param {string} context
|
|
201
202
|
* @returns
|
|
@@ -222,7 +223,7 @@ function stringToMD5Hash(str) {
|
|
|
222
223
|
const md5 = crypto_1.default.createHash('md5');
|
|
223
224
|
md5.update(str);
|
|
224
225
|
const hash = md5.digest('hex');
|
|
225
|
-
return hash
|
|
226
|
+
return `${startTime}_${hash}`;
|
|
226
227
|
}
|
|
227
228
|
exports.dataStorage = DataStorage.getInstance();
|
|
228
229
|
// TODO: consider using fs promises instead of writeSync/appendFileSync to
|
package/lib/pipe/testomatio.js
CHANGED
|
@@ -113,7 +113,8 @@ class TestomatioPipe {
|
|
|
113
113
|
const resp = await this.client.request({
|
|
114
114
|
method: 'GET',
|
|
115
115
|
url: '/api/test_grep',
|
|
116
|
-
|
|
116
|
+
params: q.params,
|
|
117
|
+
responseType: q.responseType
|
|
117
118
|
});
|
|
118
119
|
if (Array.isArray(resp.data?.tests) && resp.data?.tests?.length > 0) {
|
|
119
120
|
(0, utils_js_1.foundedTestLog)(constants_js_1.APP_PREFIX, resp.data.tests);
|
|
@@ -4,14 +4,11 @@ declare namespace _default {
|
|
|
4
4
|
export { addStep as step };
|
|
5
5
|
export { setKeyValue as keyValue };
|
|
6
6
|
export { setLabel as label };
|
|
7
|
-
export { linkTest };
|
|
8
7
|
}
|
|
9
8
|
export default _default;
|
|
10
9
|
/**
|
|
11
10
|
* Stores path to file as artifact and uploads it to the S3 storage
|
|
12
11
|
* @param {string | {path: string, type: string, name: string}} data - path to file or object with path, type and name
|
|
13
|
-
* @param {any} [context=null] - optional context parameter
|
|
14
|
-
* @returns {void}
|
|
15
12
|
*/
|
|
16
13
|
declare function saveArtifact(data: string | {
|
|
17
14
|
path: string;
|
|
@@ -20,35 +17,25 @@ declare function saveArtifact(data: string | {
|
|
|
20
17
|
}, context?: any): void;
|
|
21
18
|
/**
|
|
22
19
|
* Attach log message(s) to the test report
|
|
23
|
-
* @param
|
|
24
|
-
* @returns {void}
|
|
20
|
+
* @param string
|
|
25
21
|
*/
|
|
26
22
|
declare function logMessage(...args: any[]): void;
|
|
27
23
|
/**
|
|
28
24
|
* Similar to "log" function but marks message in report as a step
|
|
29
|
-
* @param {string} message
|
|
30
|
-
* @returns {void}
|
|
25
|
+
* @param {string} message
|
|
31
26
|
*/
|
|
32
27
|
declare function addStep(message: string): void;
|
|
33
28
|
/**
|
|
34
29
|
* Add key-value pair(s) to the test report
|
|
35
|
-
* @param {{[key: string]: string} | string} keyValue
|
|
36
|
-
* @param {string
|
|
37
|
-
* @returns {void}
|
|
30
|
+
* @param {{[key: string]: string} | string} keyValue object { key: value } (multiple props allowed) or key (string)
|
|
31
|
+
* @param {string?} value
|
|
38
32
|
*/
|
|
39
33
|
declare function setKeyValue(keyValue: {
|
|
40
34
|
[key: string]: string;
|
|
41
35
|
} | string, value?: string | null): void;
|
|
42
36
|
/**
|
|
43
|
-
* Add label
|
|
37
|
+
* Add a single label to the test report
|
|
44
38
|
* @param {string} key - label key (e.g. 'severity', 'feature', or just 'smoke' for labels without values)
|
|
45
|
-
* @param {string
|
|
46
|
-
* @returns {void}
|
|
39
|
+
* @param {string} [value] - optional label value (e.g. 'high', 'login')
|
|
47
40
|
*/
|
|
48
|
-
declare function setLabel(key: string, value?: string
|
|
49
|
-
/**
|
|
50
|
-
* Add link(s) to the test report
|
|
51
|
-
* @param {...string} testIds - test IDs to link
|
|
52
|
-
* @returns {void}
|
|
53
|
-
*/
|
|
54
|
-
declare function linkTest(...testIds: string[]): void;
|
|
41
|
+
declare function setLabel(key: string, value?: string): void;
|
|
@@ -4,8 +4,6 @@ const index_js_1 = require("./services/index.js");
|
|
|
4
4
|
/**
|
|
5
5
|
* Stores path to file as artifact and uploads it to the S3 storage
|
|
6
6
|
* @param {string | {path: string, type: string, name: string}} data - path to file or object with path, type and name
|
|
7
|
-
* @param {any} [context=null] - optional context parameter
|
|
8
|
-
* @returns {void}
|
|
9
7
|
*/
|
|
10
8
|
function saveArtifact(data, context = null) {
|
|
11
9
|
if (process.env.IS_PLAYWRIGHT)
|
|
@@ -17,8 +15,7 @@ function saveArtifact(data, context = null) {
|
|
|
17
15
|
}
|
|
18
16
|
/**
|
|
19
17
|
* Attach log message(s) to the test report
|
|
20
|
-
* @param
|
|
21
|
-
* @returns {void}
|
|
18
|
+
* @param string
|
|
22
19
|
*/
|
|
23
20
|
function logMessage(...args) {
|
|
24
21
|
if (process.env.IS_PLAYWRIGHT)
|
|
@@ -27,8 +24,7 @@ function logMessage(...args) {
|
|
|
27
24
|
}
|
|
28
25
|
/**
|
|
29
26
|
* Similar to "log" function but marks message in report as a step
|
|
30
|
-
* @param {string} message
|
|
31
|
-
* @returns {void}
|
|
27
|
+
* @param {string} message
|
|
32
28
|
*/
|
|
33
29
|
function addStep(message) {
|
|
34
30
|
if (process.env.IS_PLAYWRIGHT)
|
|
@@ -37,9 +33,8 @@ function addStep(message) {
|
|
|
37
33
|
}
|
|
38
34
|
/**
|
|
39
35
|
* Add key-value pair(s) to the test report
|
|
40
|
-
* @param {{[key: string]: string} | string} keyValue
|
|
41
|
-
* @param {string
|
|
42
|
-
* @returns {void}
|
|
36
|
+
* @param {{[key: string]: string} | string} keyValue object { key: value } (multiple props allowed) or key (string)
|
|
37
|
+
* @param {string?} value
|
|
43
38
|
*/
|
|
44
39
|
function setKeyValue(keyValue, value = null) {
|
|
45
40
|
if (process.env.IS_PLAYWRIGHT)
|
|
@@ -50,29 +45,43 @@ function setKeyValue(keyValue, value = null) {
|
|
|
50
45
|
index_js_1.services.keyValues.put(keyValue);
|
|
51
46
|
}
|
|
52
47
|
/**
|
|
53
|
-
* Add label
|
|
48
|
+
* Add a single label to the test report
|
|
54
49
|
* @param {string} key - label key (e.g. 'severity', 'feature', or just 'smoke' for labels without values)
|
|
55
|
-
* @param {string
|
|
56
|
-
* @returns {void}
|
|
50
|
+
* @param {string} [value] - optional label value (e.g. 'high', 'login')
|
|
57
51
|
*/
|
|
58
52
|
function setLabel(key, value = null) {
|
|
59
53
|
if (Array.isArray(value)) {
|
|
60
|
-
value.forEach(
|
|
54
|
+
value.forEach(v => setLabel(key, v));
|
|
61
55
|
return;
|
|
62
56
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
57
|
+
if (!key || typeof key !== 'string') {
|
|
58
|
+
console.warn('Label key must be a non-empty string');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// Limit key length to 255 characters
|
|
62
|
+
if (key.length > 255) {
|
|
63
|
+
console.warn('Label key is too long, trimmed to 255 characters:', key);
|
|
64
|
+
key = key.substring(0, 255);
|
|
65
|
+
}
|
|
66
|
+
let labelString = key;
|
|
67
|
+
if (value !== null && value !== undefined && value !== '') {
|
|
68
|
+
if (typeof value !== 'string') {
|
|
69
|
+
console.warn('Label value must be a string, converting:', value);
|
|
70
|
+
value = String(value);
|
|
71
|
+
}
|
|
72
|
+
// Limit value length to 255 characters
|
|
73
|
+
if (value.length > 255) {
|
|
74
|
+
console.warn('Label value is too long, trimmed to 255 characters:', value);
|
|
75
|
+
value = value.substring(0, 255);
|
|
76
|
+
}
|
|
77
|
+
labelString = `${key}:${value}`;
|
|
78
|
+
}
|
|
79
|
+
// Limit total label length to 255 characters
|
|
80
|
+
if (labelString.length > 255) {
|
|
81
|
+
console.warn('Label is too long, trimmed to 255 characters:', labelString);
|
|
82
|
+
labelString = labelString.substring(0, 255);
|
|
83
|
+
}
|
|
84
|
+
index_js_1.services.labels.put([labelString]);
|
|
76
85
|
}
|
|
77
86
|
module.exports = {
|
|
78
87
|
artifact: saveArtifact,
|
|
@@ -80,5 +89,4 @@ module.exports = {
|
|
|
80
89
|
step: addStep,
|
|
81
90
|
keyValue: setKeyValue,
|
|
82
91
|
label: setLabel,
|
|
83
|
-
linkTest,
|
|
84
92
|
};
|