@testomatio/reporter 2.6.0-beta.1.allure → 2.6.1
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 +9 -11
- package/lib/adapter/playwright.d.ts +2 -0
- package/lib/adapter/playwright.js +29 -5
- package/lib/adapter/utils/playwright.d.ts +25 -0
- package/lib/adapter/utils/playwright.js +123 -0
- package/lib/adapter/vitest.js +2 -1
- package/lib/bin/cli.js +36 -36
- package/lib/data-storage.d.ts +1 -1
- package/lib/data-storage.js +1 -0
- package/lib/junit-adapter/index.js +0 -4
- package/lib/pipe/coverage.js +63 -5
- package/lib/pipe/debug.js +1 -2
- package/lib/pipe/github.js +15 -0
- package/lib/pipe/html.d.ts +2 -3
- package/lib/pipe/html.js +745 -37
- package/lib/pipe/testomatio.js +83 -36
- package/lib/reporter-functions.d.ts +36 -11
- package/lib/reporter-functions.js +72 -22
- package/lib/reporter.d.ts +90 -38
- package/lib/services/artifacts.d.ts +1 -1
- package/lib/services/key-values.d.ts +1 -1
- package/lib/services/links.d.ts +5 -3
- package/lib/services/links.js +1 -1
- package/lib/services/logger.d.ts +1 -1
- package/lib/template/testomatio-old.hbs +1421 -0
- package/lib/template/testomatio.hbs +3200 -1157
- package/lib/utils/log-formatter.d.ts +1 -2
- package/lib/utils/log-formatter.js +8 -4
- package/lib/utils/utils.js +0 -9
- package/package.json +2 -2
- package/src/adapter/playwright.js +32 -6
- package/src/adapter/utils/playwright.js +121 -0
- package/src/adapter/vitest.js +2 -1
- package/src/bin/cli.js +39 -47
- package/src/data-storage.js +1 -0
- package/src/junit-adapter/index.js +0 -4
- package/src/pipe/coverage.js +90 -32
- package/src/pipe/debug.js +1 -2
- package/src/pipe/github.js +14 -0
- package/src/pipe/html.js +844 -38
- package/src/pipe/testomatio.js +98 -53
- package/src/reporter-functions.js +73 -25
- package/src/services/links.js +1 -1
- package/src/template/testomatio-old.hbs +1421 -0
- package/src/template/testomatio.hbs +3200 -1157
- package/src/utils/log-formatter.js +9 -4
- package/src/utils/utils.js +0 -5
- package/types/types.d.ts +30 -6
- package/lib/allureReader.d.ts +0 -65
- package/lib/allureReader.js +0 -448
- package/lib/junit-adapter/kotlin.d.ts +0 -5
- package/lib/junit-adapter/kotlin.js +0 -46
- package/lib/services/labels.d.ts +0 -0
- package/lib/services/labels.js +0 -0
- package/src/allureReader.js +0 -523
- package/src/junit-adapter/kotlin.js +0 -48
- package/src/services/labels.js +0 -1
package/src/pipe/testomatio.js
CHANGED
|
@@ -3,11 +3,12 @@ import pc from 'picocolors';
|
|
|
3
3
|
import { Gaxios } from 'gaxios';
|
|
4
4
|
import JsonCycle from 'json-cycle';
|
|
5
5
|
import { APP_PREFIX, STATUS, AXIOS_TIMEOUT, REPORTER_REQUEST_RETRIES } from '../constants.js';
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
import {
|
|
7
|
+
isValidUrl,
|
|
8
|
+
foundedTestLog,
|
|
9
|
+
readLatestRunId,
|
|
10
|
+
transformEnvVarToBoolean,
|
|
11
|
+
getGitCommitSha,
|
|
11
12
|
} from '../utils/utils.js';
|
|
12
13
|
import { parseFilterParams, generateFilterRequestParams, setS3Credentials } from '../utils/pipe_utils.js';
|
|
13
14
|
import { config } from '../config.js';
|
|
@@ -25,7 +26,7 @@ if (process.env.TESTOMATIO_RUN) process.env.runId = process.env.TESTOMATIO_RUN;
|
|
|
25
26
|
class TestomatioPipe {
|
|
26
27
|
constructor(params, store) {
|
|
27
28
|
this.batch = {
|
|
28
|
-
isEnabled: params?.isBatchEnabled ?? !
|
|
29
|
+
isEnabled: params?.isBatchEnabled ?? !process.env.TESTOMATIO_DISABLE_BATCH_UPLOAD ?? true,
|
|
29
30
|
intervalFunction: null, // will be created in createRun by setInterval function
|
|
30
31
|
intervalTime: 5000, // how often tests are sent
|
|
31
32
|
tests: [], // array of tests in batch
|
|
@@ -198,6 +199,9 @@ class TestomatioPipe {
|
|
|
198
199
|
if (!this.isEnabled) return;
|
|
199
200
|
if (this.batch.isEnabled && this.isEnabled)
|
|
200
201
|
this.batch.intervalFunction = setInterval(this.#batchUpload, this.batch.intervalTime);
|
|
202
|
+
if (this.store) {
|
|
203
|
+
this.store.runKind = params.kind;
|
|
204
|
+
}
|
|
201
205
|
|
|
202
206
|
let buildUrl = process.env.BUILD_URL || process.env.CI_JOB_URL || process.env.CIRCLE_BUILD_URL;
|
|
203
207
|
|
|
@@ -219,6 +223,16 @@ class TestomatioPipe {
|
|
|
219
223
|
|
|
220
224
|
const accessEvent = process.env.TESTOMATIO_PUBLISH ? 'publish' : null;
|
|
221
225
|
|
|
226
|
+
const coverageConfiguration = this.store?.coverageConfiguration;
|
|
227
|
+
let description = null;
|
|
228
|
+
let configuration = null;
|
|
229
|
+
if (coverageConfiguration && (coverageConfiguration.tests?.length || coverageConfiguration.suites?.length)) {
|
|
230
|
+
description = this.store?.coverageDescription || null;
|
|
231
|
+
configuration = {
|
|
232
|
+
tests: coverageConfiguration.tests?.map(id => id.replace(/^T/, '')) || [],
|
|
233
|
+
suites: coverageConfiguration.suites?.map(id => id.replace(/^S/, '')) || [],
|
|
234
|
+
};
|
|
235
|
+
}
|
|
222
236
|
const runParams = Object.fromEntries(
|
|
223
237
|
Object.entries({
|
|
224
238
|
ci_build_url: buildUrl,
|
|
@@ -232,6 +246,8 @@ class TestomatioPipe {
|
|
|
232
246
|
shared_run: this.sharedRun,
|
|
233
247
|
shared_run_timeout: this.sharedRunTimeout,
|
|
234
248
|
kind: params.kind,
|
|
249
|
+
configuration,
|
|
250
|
+
description,
|
|
235
251
|
}).filter(([, value]) => !!value),
|
|
236
252
|
);
|
|
237
253
|
debug(' >>>>>> Run params', JSON.stringify(runParams, null, 2));
|
|
@@ -246,6 +262,15 @@ class TestomatioPipe {
|
|
|
246
262
|
responseType: 'json',
|
|
247
263
|
});
|
|
248
264
|
if (resp.data.artifacts) setS3Credentials(resp.data.artifacts);
|
|
265
|
+
if (resp.data.url) {
|
|
266
|
+
const respUrl = new URL(resp.data.url);
|
|
267
|
+
this.runUrl = `${this.url}${respUrl.pathname}`;
|
|
268
|
+
this.runPublicUrl = resp.data.public_url;
|
|
269
|
+
this.store.runUrl = this.runUrl;
|
|
270
|
+
this.store.runPublicUrl = this.runPublicUrl;
|
|
271
|
+
console.log(APP_PREFIX, '📊 Using existing run. Report ID:', this.runId);
|
|
272
|
+
console.log(APP_PREFIX, '📊 Report URL:', pc.magenta(this.runUrl));
|
|
273
|
+
}
|
|
249
274
|
return;
|
|
250
275
|
}
|
|
251
276
|
|
|
@@ -278,11 +303,13 @@ class TestomatioPipe {
|
|
|
278
303
|
if (!this.apiKey) console.error('Testomat.io API key is not set');
|
|
279
304
|
if (!this.apiKey?.startsWith('tstmt')) console.error('Testomat.io API key is invalid');
|
|
280
305
|
|
|
306
|
+
if (process.env.DEBUG || process.env.TESTOMATIO_DEBUG) this.#logFailedResponse(err);
|
|
307
|
+
|
|
281
308
|
console.error(
|
|
282
309
|
APP_PREFIX,
|
|
283
310
|
'Error creating Testomat.io report (see details above), please check if your API key is valid. Skipping report',
|
|
284
311
|
);
|
|
285
|
-
printCreateIssue(
|
|
312
|
+
printCreateIssue();
|
|
286
313
|
}
|
|
287
314
|
debug('"createRun" function finished');
|
|
288
315
|
}
|
|
@@ -329,24 +356,8 @@ class TestomatioPipe {
|
|
|
329
356
|
this.requestFailures++;
|
|
330
357
|
this.notReportedTestsCount++;
|
|
331
358
|
if (err.response) {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
console.log(
|
|
335
|
-
APP_PREFIX,
|
|
336
|
-
pc.yellow(`Warning: ${responseData.message} (${err.response.status})`),
|
|
337
|
-
pc.gray(data?.title || ''),
|
|
338
|
-
);
|
|
339
|
-
if (err.response?.data?.message?.includes('could not be matched')) {
|
|
340
|
-
this.hasUnmatchedTests = true;
|
|
341
|
-
}
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
|
-
console.log(
|
|
345
|
-
APP_PREFIX,
|
|
346
|
-
pc.yellow(`Warning: ${data?.title || ''} (${err.response?.status})`),
|
|
347
|
-
`Report couldn't be processed: ${err?.response?.data?.message}`,
|
|
348
|
-
);
|
|
349
|
-
printCreateIssue(err);
|
|
359
|
+
this.#logFailedResponse(err);
|
|
360
|
+
printCreateIssue();
|
|
350
361
|
} else {
|
|
351
362
|
console.log(APP_PREFIX, pc.blue(data?.title || ''), "Report couldn't be processed", err);
|
|
352
363
|
}
|
|
@@ -395,20 +406,8 @@ class TestomatioPipe {
|
|
|
395
406
|
this.requestFailures++;
|
|
396
407
|
this.notReportedTestsCount += testsToSend.length;
|
|
397
408
|
if (err.response) {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
console.log(APP_PREFIX, pc.yellow(`Warning: ${responseData.message} (${err.response.status})`));
|
|
401
|
-
if (err.response?.data?.message?.includes('could not be matched')) {
|
|
402
|
-
this.hasUnmatchedTests = true;
|
|
403
|
-
}
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
console.log(
|
|
407
|
-
APP_PREFIX,
|
|
408
|
-
pc.yellow(`Warning: (${err.response?.status})`),
|
|
409
|
-
`Report couldn't be processed: ${err?.response?.data?.message}`,
|
|
410
|
-
);
|
|
411
|
-
printCreateIssue(err);
|
|
409
|
+
this.#logFailedResponse(err);
|
|
410
|
+
printCreateIssue();
|
|
412
411
|
} else {
|
|
413
412
|
console.log(APP_PREFIX, "Report couldn't be processed", err);
|
|
414
413
|
}
|
|
@@ -521,37 +520,83 @@ class TestomatioPipe {
|
|
|
521
520
|
}
|
|
522
521
|
} catch (err) {
|
|
523
522
|
console.log(APP_PREFIX, 'Error updating status, skipping...', err);
|
|
524
|
-
|
|
523
|
+
if (process.env.DEBUG || process.env.TESTOMATIO_DEBUG) this.#logFailedResponse(err);
|
|
524
|
+
printCreateIssue();
|
|
525
525
|
}
|
|
526
526
|
debug('Run finished');
|
|
527
527
|
}
|
|
528
528
|
|
|
529
|
+
#logFailedResponse(error) {
|
|
530
|
+
let responseBody = stringify(error.response?.data ?? error.response ?? error, { pretty: true });
|
|
531
|
+
if (!responseBody) responseBody = '<empty>';
|
|
532
|
+
responseBody = hideTestomatioToken(responseBody);
|
|
533
|
+
|
|
534
|
+
const statusCode = error.status || error.code || error.response?.status || '<unknown status code>';
|
|
535
|
+
const method = error.response?.config.method || '<unknown method>';
|
|
536
|
+
const url = error.response?.config.url || '<unknown url>';
|
|
537
|
+
|
|
538
|
+
let message = pc.yellow('\n⚠️ Request to Testomat.io failed:\n');
|
|
539
|
+
message += pc.bold(`${pc.red(statusCode)} ${method} ${url}\n`);
|
|
540
|
+
message += `\t${pc.bold('response: ')}${pc.gray(responseBody)}\n`;
|
|
541
|
+
|
|
542
|
+
const requestBody = hideTestomatioToken(stringify(error.response?.config?.data));
|
|
543
|
+
if (process.env.DEBUG || process.env.TESTOMATIO_DEBUG) {
|
|
544
|
+
message += `\t${pc.bold('request: ')}${pc.gray(requestBody)}\n`;
|
|
545
|
+
} else {
|
|
546
|
+
const requestBodyCut = requestBody.slice(0, 1000);
|
|
547
|
+
message += `\t${pc.bold('request: ')}${pc.gray(`${requestBodyCut}.....`)}\n`;
|
|
548
|
+
message += '\trequest body is cut, run with TESTOMATIO_DEBUG=1 to see full body\n';
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
console.log(message);
|
|
552
|
+
|
|
553
|
+
if (error.response?.data?.message?.includes('could not be matched')) {
|
|
554
|
+
this.hasUnmatchedTests = true;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
529
558
|
toString() {
|
|
530
559
|
return 'Testomatio Reporter';
|
|
531
560
|
}
|
|
532
561
|
}
|
|
533
562
|
|
|
534
563
|
let registeredErrorHints = false;
|
|
535
|
-
function printCreateIssue(
|
|
564
|
+
function printCreateIssue() {
|
|
536
565
|
if (registeredErrorHints) return;
|
|
537
566
|
registeredErrorHints = true;
|
|
538
567
|
process.on('exit', () => {
|
|
539
|
-
console.log();
|
|
540
|
-
console.log(APP_PREFIX, 'There was an error reporting to Testomat.io:');
|
|
541
568
|
console.log(
|
|
542
569
|
APP_PREFIX,
|
|
543
|
-
'
|
|
570
|
+
'There was an error reporting to Testomat.io.\n',
|
|
571
|
+
pc.yellow(
|
|
572
|
+
'If you think this is a bug please create an issue: https://github.com/testomatio/reporter/issues/new.',
|
|
573
|
+
),
|
|
574
|
+
pc.yellow('Provide the logs from above'),
|
|
544
575
|
);
|
|
545
|
-
console.log(APP_PREFIX, 'Provide this information:');
|
|
546
|
-
console.log('Error:', err.message || err.code);
|
|
547
|
-
if (!err.config) return;
|
|
548
|
-
|
|
549
|
-
const time = new Date().toUTCString();
|
|
550
|
-
const { body, url, baseURL, method } = err?.config || {};
|
|
551
|
-
console.log('```js');
|
|
552
|
-
console.log({ body: body?.replace(/"(tstmt_[^"]+)"/g, 'tstmt_*'), url, baseURL, method, time });
|
|
553
|
-
console.log('```');
|
|
554
576
|
});
|
|
555
577
|
}
|
|
556
578
|
|
|
579
|
+
/**
|
|
580
|
+
* Removes Testomatio token from string data
|
|
581
|
+
*
|
|
582
|
+
* @param {string} data
|
|
583
|
+
* @returns {string}
|
|
584
|
+
*/
|
|
585
|
+
function hideTestomatioToken(data) {
|
|
586
|
+
return (typeof data === 'string' ? data : '')
|
|
587
|
+
.replace(/"api_key"\s*:\s*"[^"]+"/g, '"api_key": "<hidden>"')
|
|
588
|
+
.replace(/"(tstmt_[^"]+)"/g, '"tstmt_***"');
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* Stringifies provided data
|
|
593
|
+
*
|
|
594
|
+
* @param {any} anything
|
|
595
|
+
* @param {{ pretty: boolean }} opts
|
|
596
|
+
* @returns {string}
|
|
597
|
+
*/
|
|
598
|
+
function stringify(anything, opts = { pretty: false }) {
|
|
599
|
+
return typeof anything === 'string' ? anything : JSON.stringify(anything, null, opts.pretty ? 2 : undefined);
|
|
600
|
+
}
|
|
601
|
+
|
|
557
602
|
export default TestomatioPipe;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { playwrightLogsMarkers } from './adapter/utils/playwright.js';
|
|
1
2
|
import { isPlaywright } from './helpers.js';
|
|
2
3
|
import { services } from './services/index.js';
|
|
4
|
+
import pc from 'picocolors';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Stores path to file as artifact and uploads it to the S3 storage
|
|
@@ -8,7 +10,10 @@ import { services } from './services/index.js';
|
|
|
8
10
|
* @returns {void}
|
|
9
11
|
*/
|
|
10
12
|
function saveArtifact(data, context = null) {
|
|
11
|
-
|
|
13
|
+
if (isPlaywright)
|
|
14
|
+
console.warn(`[TESTOMATIO] 'artifact' function is not supported for Playwright
|
|
15
|
+
Playwright supports artifacts out of the box.`);
|
|
16
|
+
|
|
12
17
|
if (!data) return;
|
|
13
18
|
services.artifacts.put(data, context);
|
|
14
19
|
}
|
|
@@ -41,59 +46,102 @@ function addStep(message, logs) {
|
|
|
41
46
|
|
|
42
47
|
/**
|
|
43
48
|
* Add key-value pair(s) to the test report
|
|
44
|
-
* @param {{[key: string]: string} | string} keyValue - object { key: value } (multiple props allowed)
|
|
45
|
-
* @param {string|
|
|
49
|
+
* @param {{[key: string]: string} | string} keyValue - object { key: value } (multiple props allowed) OR key (string)
|
|
50
|
+
* @param {string|undefined} [value=undefined] - optional value when keyValue is a string
|
|
46
51
|
* @returns {void}
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* meta('key', 'value');
|
|
55
|
+
* meta({ key: 'value' });
|
|
56
|
+
* meta({ key1: 'value1', key2: 'value2' });
|
|
47
57
|
*/
|
|
48
|
-
function setKeyValue(keyValue, value =
|
|
49
|
-
|
|
50
|
-
|
|
58
|
+
function setKeyValue(keyValue, value = undefined) {
|
|
59
|
+
// in this case keyValue acts as key (value passed as second argument)
|
|
51
60
|
if (typeof keyValue === 'string') {
|
|
52
|
-
|
|
61
|
+
const key = keyValue;
|
|
62
|
+
keyValue = { [key]: value };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (isPlaywright) {
|
|
66
|
+
console.log(`${playwrightLogsMarkers.meta} ${JSON.stringify(keyValue)}`);
|
|
67
|
+
return;
|
|
53
68
|
}
|
|
69
|
+
|
|
70
|
+
// in this case keyValue is expected to be an object
|
|
54
71
|
services.keyValues.put(keyValue);
|
|
55
72
|
}
|
|
56
73
|
|
|
57
74
|
/**
|
|
58
|
-
*
|
|
59
|
-
* @param {string
|
|
60
|
-
*
|
|
75
|
+
* Adds label(s) to the test
|
|
76
|
+
* @param {string | {
|
|
77
|
+
* [key: string]: string}
|
|
78
|
+
* } key - just label OR custom field name OR object with custom field name and value
|
|
79
|
+
* @param {string | null} [value=null] - optional label value (of custom field value)
|
|
80
|
+
* (used when key is a string)
|
|
61
81
|
* @returns {void}
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* label('high');
|
|
85
|
+
* label('priority', 'high');
|
|
86
|
+
* label({priority: 'high'});
|
|
62
87
|
*/
|
|
63
88
|
function setLabel(key, value = null) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
89
|
+
let labelsArr = [];
|
|
90
|
+
|
|
91
|
+
// process label('priority', 'high') and label('high'
|
|
92
|
+
if (typeof key === 'string') {
|
|
93
|
+
labelsArr = [value ? `${key}:${value}` : key];
|
|
94
|
+
// process label({priority: 'high'}), label({priority: 'high', scope: 'smoke'})
|
|
95
|
+
} else if (key !== null && typeof key === 'object') {
|
|
96
|
+
labelsArr = Object.entries(key).map(([key, value]) => `${key}:${value}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const labels = labelsArr.map(l => ({ label: l }));
|
|
100
|
+
if (isPlaywright) {
|
|
101
|
+
console.log(`${playwrightLogsMarkers.label} ${JSON.stringify(labels)}`);
|
|
102
|
+
return;
|
|
67
103
|
}
|
|
68
|
-
|
|
69
|
-
value !== null && value !== undefined && value !== '' ? { label: `${key}:${value}` } : { label: key };
|
|
70
|
-
services.links.put([labelObject]);
|
|
104
|
+
services.links.put(labels);
|
|
71
105
|
}
|
|
72
106
|
|
|
73
107
|
/**
|
|
74
108
|
* Add link(s) to the test report
|
|
75
|
-
* @param {...string} testIds - test IDs to link
|
|
109
|
+
* @param {...string | string[]} testIds - test IDs to link
|
|
76
110
|
* @returns {void}
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* linkTest('T11111111', 'T22222222')
|
|
114
|
+
* or
|
|
115
|
+
* linkTest(['T11111111', 'T22222222'])
|
|
77
116
|
*/
|
|
78
117
|
function linkTest(...testIds) {
|
|
79
|
-
const
|
|
118
|
+
const testIdsArr = testIds.flat();
|
|
119
|
+
const links = testIdsArr.map(testId => ({ test: testId }));
|
|
120
|
+
if (isPlaywright) {
|
|
121
|
+
console.log(`${playwrightLogsMarkers.linkTest} ${JSON.stringify(links)}`);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
80
124
|
services.links.put(links);
|
|
81
125
|
}
|
|
82
126
|
|
|
83
127
|
/**
|
|
84
128
|
* Add JIRA issue link(s) to the test report
|
|
85
|
-
* @param {...string} jiraIds - JIRA issue IDs to link
|
|
129
|
+
* @param {...(string | string[])} jiraIds - JIRA issue IDs to link
|
|
86
130
|
* @returns {void}
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* linkJira('TICKET-1', 'TICKET-2')
|
|
134
|
+
* or
|
|
135
|
+
* linkJira(['TICKET-1', 'TICKET-2'])
|
|
87
136
|
*/
|
|
88
137
|
function linkJira(...jiraIds) {
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function showPlaywrightWarning(functionName, recommendation) {
|
|
138
|
+
const jiraIdsArr = jiraIds.flat();
|
|
139
|
+
const links = jiraIdsArr.map(jiraId => ({ jira: jiraId }));
|
|
94
140
|
if (isPlaywright) {
|
|
95
|
-
console.
|
|
141
|
+
console.log(`${playwrightLogsMarkers.linkJira} ${JSON.stringify(links)}`);
|
|
142
|
+
return;
|
|
96
143
|
}
|
|
144
|
+
services.links.put(links);
|
|
97
145
|
}
|
|
98
146
|
|
|
99
147
|
export default {
|
package/src/services/links.js
CHANGED
|
@@ -30,7 +30,7 @@ class LinkStorage {
|
|
|
30
30
|
/**
|
|
31
31
|
* Returns links array for the test
|
|
32
32
|
* @param {*} context testId or test context from test runner
|
|
33
|
-
* @returns {
|
|
33
|
+
* @returns {{[key: 'test' | 'jira']: string}[]} links array, e.g. [{test: 'TEST-123'}, {jira: 'JIRA-456'}]
|
|
34
34
|
*/
|
|
35
35
|
get(context = null) {
|
|
36
36
|
const linksList = dataStorage.getData('links', context);
|