@testomatio/reporter 1.3.6-beta → 1.4.1-beta-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 +4 -4
- package/lib/adapter/codecept.js +11 -9
- package/lib/adapter/cucumber/current.js +4 -4
- package/lib/adapter/cucumber/legacy.js +3 -3
- package/lib/adapter/cypress-plugin/index.js +1 -1
- package/lib/adapter/jasmine.js +1 -1
- package/lib/adapter/jest.js +12 -17
- package/lib/adapter/mocha.js +22 -50
- package/lib/adapter/playwright.js +34 -22
- package/lib/adapter/webdriver.js +1 -1
- package/lib/bin/reportXml.js +1 -0
- package/lib/bin/startTest.js +25 -4
- package/lib/client.js +93 -27
- package/lib/constants.js +4 -6
- package/lib/fileUploader.js +106 -38
- package/lib/junit-adapter/java.js +27 -9
- package/lib/pipe/csv.js +4 -1
- package/lib/pipe/github.js +5 -16
- package/lib/pipe/gitlab.js +5 -16
- package/lib/pipe/testomatio.js +136 -34
- package/lib/reporter-functions.js +43 -0
- package/lib/reporter.js +11 -5
- package/lib/storages/artifact-storage.js +70 -0
- package/lib/storages/data-storage.js +307 -0
- package/lib/storages/key-value-storage.js +58 -0
- package/lib/{logger.js → storages/logger.js} +103 -114
- package/lib/utils/pipe_utils.js +135 -0
- package/lib/{util.js → utils/utils.js} +129 -12
- package/lib/xmlReader.js +132 -44
- package/package.json +9 -7
- package/lib/_ArtifactStorageOld.js +0 -142
- package/lib/artifactStorage.js +0 -25
- package/lib/dataStorage.js +0 -244
package/lib/pipe/testomatio.js
CHANGED
|
@@ -3,8 +3,8 @@ const chalk = require('chalk');
|
|
|
3
3
|
const axios = require('axios');
|
|
4
4
|
const JsonCycle = require('json-cycle');
|
|
5
5
|
const { APP_PREFIX, STATUS } = require('../constants');
|
|
6
|
-
const { isValidUrl } = require('../
|
|
7
|
-
const {
|
|
6
|
+
const { isValidUrl, foundedTestLog } = require('../utils/utils');
|
|
7
|
+
const { parseFilterParams, generateFilterRequestParams, setS3Credentials, } = require('../utils/pipe_utils');
|
|
8
8
|
|
|
9
9
|
const { TESTOMATIO_RUN } = process.env;
|
|
10
10
|
if (TESTOMATIO_RUN) {
|
|
@@ -33,12 +33,19 @@ class TestomatioPipe {
|
|
|
33
33
|
this.sharedRun = !!process.env.TESTOMATIO_SHARED_RUN;
|
|
34
34
|
this.groupTitle = params.groupTitle || process.env.TESTOMATIO_RUNGROUP_TITLE;
|
|
35
35
|
this.env = process.env.TESTOMATIO_ENV;
|
|
36
|
-
|
|
36
|
+
|
|
37
|
+
this.axios = axios.create({
|
|
38
|
+
baseURL: `${this.url.trim()}`,
|
|
39
|
+
timeout: 30000
|
|
40
|
+
});
|
|
41
|
+
|
|
37
42
|
this.isEnabled = true;
|
|
38
43
|
// do not finish this run (for parallel testing)
|
|
39
44
|
this.proceed = process.env.TESTOMATIO_PROCEED;
|
|
45
|
+
this.jiraId = process.env.TESTOMATIO_JIRA_ID;
|
|
40
46
|
this.runId = params.runId || process.env.runId;
|
|
41
|
-
this.createNewTests = !!process.env.TESTOMATIO_CREATE;
|
|
47
|
+
this.createNewTests = params.createNewTests ?? !!process.env.TESTOMATIO_CREATE;
|
|
48
|
+
this.hasUnmatchedTests = false;
|
|
42
49
|
|
|
43
50
|
if (!isValidUrl(this.url.trim())) {
|
|
44
51
|
this.isEnabled = false;
|
|
@@ -46,62 +53,135 @@ class TestomatioPipe {
|
|
|
46
53
|
}
|
|
47
54
|
}
|
|
48
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Asynchronously prepares and retrieves the Testomat.io test grepList based on the provided options.
|
|
58
|
+
* @param {Object} opts - The options for preparing the test grepList.
|
|
59
|
+
* @returns {Promise<string[]>} - An array containing the retrieved
|
|
60
|
+
* test grepList, or an empty array if no tests are found or the request is disabled.
|
|
61
|
+
* @throws {Error} - Throws an error if there was a problem while making the request.
|
|
62
|
+
*/
|
|
63
|
+
async prepareRun(opts) {
|
|
64
|
+
if (!this.isEnabled) return [];
|
|
65
|
+
|
|
66
|
+
const { type, id } = parseFilterParams(opts);
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const q = generateFilterRequestParams({
|
|
70
|
+
type,
|
|
71
|
+
id,
|
|
72
|
+
apiKey: this.apiKey.trim()
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (!q) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const resp = await this.axios.get('/api/test_grep', q);
|
|
80
|
+
const { data } = resp;
|
|
81
|
+
|
|
82
|
+
if (Array.isArray(data?.tests) && data?.tests?.length > 0) {
|
|
83
|
+
foundedTestLog(APP_PREFIX, data.tests);
|
|
84
|
+
return data.tests;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
console.log(APP_PREFIX, `⛔ No tests found for your --filter --> ${type}=${id}`);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
console.error(
|
|
91
|
+
APP_PREFIX,
|
|
92
|
+
`🚩 Error getting Testomat.io test grepList: ${err}`,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
49
97
|
/**
|
|
50
98
|
* @returns Promise<void>
|
|
51
99
|
*/
|
|
52
100
|
async createRun() {
|
|
101
|
+
debug('Creating run...');
|
|
53
102
|
if (!this.isEnabled) return;
|
|
54
103
|
|
|
104
|
+
let buildUrl = process.env.BUILD_URL || process.env.CI_JOB_URL || process.env.CIRCLE_BUILD_URL;
|
|
105
|
+
|
|
106
|
+
// GitHub Actions Url
|
|
107
|
+
if (!buildUrl && process.env.GITHUB_RUN_ID) {
|
|
108
|
+
// eslint-disable-next-line max-len
|
|
109
|
+
buildUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Azure DevOps Url
|
|
113
|
+
if (!buildUrl && process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI) {
|
|
114
|
+
const collectionUri = process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI;
|
|
115
|
+
const project = process.env.SYSTEM_TEAMPROJECT;
|
|
116
|
+
const buildId = process.env.BUILD_BUILDID;
|
|
117
|
+
buildUrl = `${collectionUri}/${project}/_build/results?buildId=${buildId}`;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (buildUrl && !buildUrl.startsWith('http')) buildUrl = undefined;
|
|
121
|
+
|
|
122
|
+
const accessEvent = process.env.TESTOMATIO_PUBLISH ? 'publish' : null;
|
|
123
|
+
|
|
55
124
|
const runParams = Object.fromEntries(
|
|
56
125
|
Object.entries({
|
|
126
|
+
ci_build_url: buildUrl,
|
|
57
127
|
parallel: this.parallel,
|
|
58
128
|
api_key: this.apiKey.trim(),
|
|
59
129
|
group_title: this.groupTitle,
|
|
130
|
+
access_event: accessEvent,
|
|
131
|
+
jira_id: this.jiraId,
|
|
60
132
|
env: this.env,
|
|
61
133
|
title: this.title,
|
|
62
134
|
shared_run: this.sharedRun,
|
|
63
|
-
}).filter(([, value]) => !!value)
|
|
135
|
+
}).filter(([, value]) => !!value),
|
|
64
136
|
);
|
|
137
|
+
debug('Run params', JSON.stringify(runParams, null, 2));
|
|
65
138
|
|
|
66
139
|
if (this.runId) {
|
|
67
|
-
|
|
140
|
+
debug(`Run with id ${this.runId} already created, updating...`);
|
|
141
|
+
const resp = await this.axios.put(`/api/reporter/${this.runId}`, runParams);
|
|
68
142
|
if (resp.data.artifacts) setS3Credentials(resp.data.artifacts);
|
|
69
143
|
return;
|
|
70
144
|
}
|
|
71
145
|
|
|
72
146
|
try {
|
|
73
|
-
const resp = await this.axios.post(
|
|
147
|
+
const resp = await this.axios.post(`/api/reporter`, runParams, {
|
|
74
148
|
maxContentLength: Infinity,
|
|
75
149
|
maxBodyLength: Infinity,
|
|
76
150
|
});
|
|
77
151
|
this.runId = resp.data.uid;
|
|
78
152
|
this.runUrl = `${this.url}/${resp.data.url.split('/').splice(3).join('/')}`;
|
|
153
|
+
this.runPublicUrl = resp.data.public_url;
|
|
79
154
|
if (resp.data.artifacts) setS3Credentials(resp.data.artifacts);
|
|
80
155
|
this.store.runUrl = this.runUrl;
|
|
156
|
+
this.store.runPublicUrl = this.runPublicUrl;
|
|
81
157
|
this.store.runId = this.runId;
|
|
82
158
|
console.log(APP_PREFIX, '📊 Report created. Report ID:', this.runId);
|
|
83
159
|
process.env.runId = this.runId;
|
|
160
|
+
debug('Run created', this.runId);
|
|
84
161
|
} catch (err) {
|
|
85
162
|
console.error(
|
|
86
163
|
APP_PREFIX,
|
|
87
164
|
'Error creating Testomat.io report, please check if your API key is valid. Skipping report',
|
|
165
|
+
err,
|
|
88
166
|
);
|
|
89
167
|
}
|
|
168
|
+
debug('"createRun" function finished');
|
|
90
169
|
}
|
|
91
170
|
|
|
92
171
|
/**
|
|
93
|
-
*
|
|
94
|
-
* @param testData data
|
|
95
|
-
* @returns
|
|
172
|
+
*
|
|
173
|
+
* @param testData data
|
|
174
|
+
* @returns
|
|
96
175
|
*/
|
|
97
176
|
addTest(data) {
|
|
177
|
+
debug('Adding test...');
|
|
98
178
|
if (!this.isEnabled) return;
|
|
99
179
|
if (!this.runId) return;
|
|
100
180
|
data.api_key = this.apiKey;
|
|
101
181
|
data.create = this.createNewTests;
|
|
102
182
|
const json = JsonCycle.stringify(data);
|
|
103
183
|
|
|
104
|
-
return this.axios.post(
|
|
184
|
+
return this.axios.post(`/api/reporter/${this.runId}/testrun`, json, {
|
|
105
185
|
maxContentLength: Infinity,
|
|
106
186
|
maxBodyLength: Infinity,
|
|
107
187
|
headers: {
|
|
@@ -109,29 +189,37 @@ class TestomatioPipe {
|
|
|
109
189
|
'Content-Type': 'application/json',
|
|
110
190
|
},
|
|
111
191
|
})
|
|
112
|
-
.catch(
|
|
192
|
+
.catch(err => {
|
|
113
193
|
if (err.response) {
|
|
114
194
|
if (err.response.status >= 400) {
|
|
115
195
|
const responseData = err.response.data || { message: '' };
|
|
116
196
|
console.log(
|
|
117
197
|
APP_PREFIX,
|
|
118
|
-
chalk.
|
|
119
|
-
|
|
198
|
+
chalk.yellow(`Warning: ${responseData.message} (${err.response.status})`),
|
|
199
|
+
chalk.grey(data?.title || ''),
|
|
120
200
|
);
|
|
201
|
+
if (err.response.data.message.includes('could not be matched')) {
|
|
202
|
+
this.hasUnmatchedTests = true;
|
|
203
|
+
}
|
|
121
204
|
return;
|
|
122
205
|
}
|
|
123
|
-
console.log(
|
|
206
|
+
console.log(
|
|
207
|
+
APP_PREFIX,
|
|
208
|
+
chalk.yellow(`Warning: ${data?.title || ''} (${err.response?.status})`),
|
|
209
|
+
`Report couldn't be processed: ${err?.response?.data?.message}`,
|
|
210
|
+
);
|
|
124
211
|
} else {
|
|
125
|
-
console.log(APP_PREFIX, chalk.blue(
|
|
212
|
+
console.log(APP_PREFIX, chalk.blue(data?.title || ''), "Report couldn't be processed", err);
|
|
126
213
|
}
|
|
127
214
|
});
|
|
128
215
|
}
|
|
129
216
|
|
|
130
217
|
/**
|
|
131
|
-
* @param {import('../../types').RunData} params
|
|
132
|
-
* @returns
|
|
218
|
+
* @param {import('../../types').RunData} params
|
|
219
|
+
* @returns
|
|
133
220
|
*/
|
|
134
221
|
async finishRun(params) {
|
|
222
|
+
debug('Finishing run...');
|
|
135
223
|
if (!this.isEnabled) return;
|
|
136
224
|
|
|
137
225
|
const { status, parallel } = params;
|
|
@@ -145,7 +233,7 @@ class TestomatioPipe {
|
|
|
145
233
|
|
|
146
234
|
try {
|
|
147
235
|
if (this.runId && !this.proceed) {
|
|
148
|
-
await this.axios.put(
|
|
236
|
+
await this.axios.put(`/api/reporter/${this.runId}`, {
|
|
149
237
|
api_key: this.apiKey,
|
|
150
238
|
status_event,
|
|
151
239
|
tests: params.tests,
|
|
@@ -153,15 +241,44 @@ class TestomatioPipe {
|
|
|
153
241
|
if (this.runUrl) {
|
|
154
242
|
console.log(APP_PREFIX, '📊 Report Saved. Report URL:', chalk.magenta(this.runUrl));
|
|
155
243
|
}
|
|
244
|
+
if (this.runPublicUrl) {
|
|
245
|
+
console.log(APP_PREFIX, '🌟 Public URL:', chalk.magenta(this.runPublicUrl));
|
|
246
|
+
}
|
|
156
247
|
}
|
|
157
248
|
if (this.runUrl && this.proceed) {
|
|
158
249
|
const notFinishedMessage = chalk.yellow.bold('Run was not finished because of $TESTOMATIO_PROCEED');
|
|
159
250
|
console.log(APP_PREFIX, `📊 ${notFinishedMessage}. Report URL: ${chalk.magenta(this.runUrl)}`);
|
|
160
251
|
console.log(APP_PREFIX, `🛬 Run to finish it: TESTOMATIO_RUN=${this.runId} npx start-test-run --finish`);
|
|
161
252
|
}
|
|
253
|
+
if (this.hasUnmatchedTests) {
|
|
254
|
+
console.log('');
|
|
255
|
+
// eslint-disable-next-line max-len
|
|
256
|
+
console.log(APP_PREFIX, chalk.yellow.bold('⚠️ Some reported tests were not found in Testomat.io project'));
|
|
257
|
+
// eslint-disable-next-line max-len
|
|
258
|
+
console.log(
|
|
259
|
+
APP_PREFIX,
|
|
260
|
+
`If you use Testomat.io as a reporter only, please re-run tests using ${chalk.bold('TESTOMATIO_CREATE=1')}`,
|
|
261
|
+
);
|
|
262
|
+
// eslint-disable-next-line max-len
|
|
263
|
+
console.log(
|
|
264
|
+
APP_PREFIX,
|
|
265
|
+
`But to keep your tests consistent it is recommended to ${chalk.bold('import tests first')}`,
|
|
266
|
+
);
|
|
267
|
+
console.log(APP_PREFIX, 'If tests were imported but still not matched, assign test IDs to your tests.');
|
|
268
|
+
console.log(APP_PREFIX, 'You can do that automatically via command line tools:');
|
|
269
|
+
console.log(APP_PREFIX, chalk.bold('npx check-tests ... --update-ids'), 'See: https://bit.ly/js-update-ids');
|
|
270
|
+
console.log(APP_PREFIX, 'or for Cucumber:');
|
|
271
|
+
// eslint-disable-next-line max-len
|
|
272
|
+
console.log(
|
|
273
|
+
APP_PREFIX,
|
|
274
|
+
chalk.bold('npx check-cucumber ... --update-ids'),
|
|
275
|
+
'See: https://bit.ly/bdd-update-ids',
|
|
276
|
+
);
|
|
277
|
+
}
|
|
162
278
|
} catch (err) {
|
|
163
279
|
console.log(APP_PREFIX, 'Error updating status, skipping...', err);
|
|
164
280
|
}
|
|
281
|
+
debug('Run finished');
|
|
165
282
|
}
|
|
166
283
|
|
|
167
284
|
toString() {
|
|
@@ -170,18 +287,3 @@ class TestomatioPipe {
|
|
|
170
287
|
}
|
|
171
288
|
|
|
172
289
|
module.exports = TestomatioPipe;
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
function setS3Credentials(artifacts) {
|
|
176
|
-
if (!Object.keys(artifacts).length) return;
|
|
177
|
-
|
|
178
|
-
console.log(APP_PREFIX, 'S3 were credentials obtained from Testomat.io...');
|
|
179
|
-
|
|
180
|
-
if (artifacts.ACCESS_KEY_ID) process.env.S3_ACCESS_KEY_ID = artifacts.ACCESS_KEY_ID;
|
|
181
|
-
if (artifacts.SECRET_ACCESS_KEY) process.env.S3_SECRET_ACCESS_KEY = artifacts.SECRET_ACCESS_KEY;
|
|
182
|
-
if (artifacts.REGION) process.env.S3_REGION = artifacts.REGION;
|
|
183
|
-
if (artifacts.BUCKET) process.env.S3_BUCKET = artifacts.BUCKET;
|
|
184
|
-
if (artifacts.ENDPOINT) process.env.S3_ENDPOINT = artifacts.ENDPOINT;
|
|
185
|
-
if (artifacts.presign) process.env.TESTOMATIO_PRIVATE_ARTIFACTS = '1';
|
|
186
|
-
resetConfig();
|
|
187
|
-
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const logger = require('./storages/logger');
|
|
2
|
+
const artifactStorage = require('./storages/artifact-storage');
|
|
3
|
+
const keyValueStorage = require('./storages/key-value-storage');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Stores path to file as artifact and uploads it to the S3 storage
|
|
7
|
+
* @param {string | {path: string, type: string, name: string}} data - path to file or object with path, type and name
|
|
8
|
+
*/
|
|
9
|
+
function saveArtifact(data, context = null) {
|
|
10
|
+
if (!data) return;
|
|
11
|
+
artifactStorage.put(data, context);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Attach log message(s) to the test report
|
|
16
|
+
* @param {...any} args
|
|
17
|
+
*/
|
|
18
|
+
function logMessage(...args) {
|
|
19
|
+
logger.log(...args);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Similar to "log" function but marks message in report as a step
|
|
24
|
+
* @param {*} message
|
|
25
|
+
*/
|
|
26
|
+
function addStep(message) {
|
|
27
|
+
logger.step(message);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Add key-value pair(s) to the test report
|
|
32
|
+
* @param {*} keyValue
|
|
33
|
+
*/
|
|
34
|
+
function setKeyValue(keyValue) {
|
|
35
|
+
keyValueStorage.put(keyValue);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
artifact: saveArtifact,
|
|
40
|
+
log: logMessage,
|
|
41
|
+
step: addStep,
|
|
42
|
+
keyValue: setKeyValue,
|
|
43
|
+
};
|
package/lib/reporter.js
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
|
-
const logger = require('./logger');
|
|
1
|
+
const logger = require('./storages/logger');
|
|
2
2
|
const TestomatClient = require('./client');
|
|
3
3
|
const TRConstants = require('./constants');
|
|
4
|
-
const TRArtifacts = require('./_ArtifactStorageOld');
|
|
5
4
|
|
|
6
|
-
const log = logger.
|
|
5
|
+
const log = logger.templateLiteralLog.bind(logger);
|
|
7
6
|
const step = logger.step.bind(logger);
|
|
7
|
+
const reporterFunctions = require('./reporter-functions');
|
|
8
8
|
|
|
9
9
|
module.exports = {
|
|
10
10
|
logger,
|
|
11
|
+
testomatioLogger: logger,
|
|
11
12
|
log,
|
|
12
13
|
step,
|
|
13
14
|
TestomatClient,
|
|
14
15
|
TRConstants,
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
module.exports.testomat = {
|
|
19
|
+
artifact: reporterFunctions.artifact,
|
|
20
|
+
log: reporterFunctions.log,
|
|
21
|
+
step: reporterFunctions.step,
|
|
22
|
+
meta: reporterFunctions.keyValue,
|
|
17
23
|
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const debug = require('debug')('@testomatio/reporter:artifact-storage');
|
|
2
|
+
const DataStorage = require('./data-storage');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Artifact storage is supposed to store file paths
|
|
6
|
+
*/
|
|
7
|
+
class ArtifactStorage {
|
|
8
|
+
|
|
9
|
+
// there is autocompletion for the class methods if implemented singleton this way
|
|
10
|
+
constructor() {
|
|
11
|
+
this.dataStorage = new DataStorage('artifact');
|
|
12
|
+
|
|
13
|
+
// singleton
|
|
14
|
+
if (!ArtifactStorage.instance) {
|
|
15
|
+
ArtifactStorage.instance = this;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// singleton
|
|
20
|
+
static getInstance() {
|
|
21
|
+
if (!ArtifactStorage.instance) {
|
|
22
|
+
ArtifactStorage.instance = new ArtifactStorage();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return ArtifactStorage.instance;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Stores path to file as artifact and uploads it to the S3 storage
|
|
30
|
+
* @param {string | {path: string, type: string, name: string}} data - path to file or object with path, type and name
|
|
31
|
+
* @param {*} context testId or test title
|
|
32
|
+
*/
|
|
33
|
+
put(data, context = null) {
|
|
34
|
+
if (!data) return;
|
|
35
|
+
debug('Save artifact:', data);
|
|
36
|
+
this.dataStorage.putData(data, context);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Returns list of artifacts to upload
|
|
41
|
+
* @param {*} context testId or test context from test runner
|
|
42
|
+
* @returns {string | {path: string, type: string, name: string}[]}
|
|
43
|
+
*/
|
|
44
|
+
get(context) {
|
|
45
|
+
if (!context) return null;
|
|
46
|
+
|
|
47
|
+
// array of any data
|
|
48
|
+
let artifacts = this.dataStorage.getData(context);
|
|
49
|
+
if (!artifacts || !artifacts.length) return null;
|
|
50
|
+
|
|
51
|
+
artifacts = artifacts.map(artifactData => {
|
|
52
|
+
// artifact could be an object ({type, path, name} props) or string
|
|
53
|
+
let artifact;
|
|
54
|
+
try {
|
|
55
|
+
artifact = JSON.parse(artifactData);
|
|
56
|
+
} catch (e) {
|
|
57
|
+
artifact = artifactData;
|
|
58
|
+
}
|
|
59
|
+
return artifact;
|
|
60
|
+
});
|
|
61
|
+
artifacts = artifacts.filter(artifact => !!artifact);
|
|
62
|
+
return artifacts.length ? artifacts : null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
ArtifactStorage.instance = null;
|
|
67
|
+
|
|
68
|
+
// const artifactStorage = ArtifactStorage.getInstance();
|
|
69
|
+
const artifactStorage = new ArtifactStorage();
|
|
70
|
+
module.exports = artifactStorage;
|