@testomatio/reporter 1.1.0-beta-3 → 1.1.0-beta.artifact-count-retry-msg-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/lib/adapter/codecept.js +3 -6
- package/lib/adapter/cypress-plugin/index.js +35 -14
- package/lib/adapter/playwright.js +8 -3
- package/lib/bin/startTest.js +6 -6
- package/lib/client.js +24 -6
- package/lib/config.js +24 -0
- package/lib/constants.js +7 -0
- package/lib/fileUploader.js +118 -61
- package/lib/pipe/gitlab.js +1 -1
- package/lib/pipe/html.js +316 -0
- package/lib/pipe/index.js +2 -0
- package/lib/pipe/testomatio.js +123 -29
- package/lib/storages/logger.js +2 -2
- package/lib/template/template-draft.hbs +249 -0
- package/lib/template/testomatio.hbs +750 -0
- package/lib/xmlReader.js +1 -2
- package/package.json +6 -2
- package/Changelog.md +0 -355
package/lib/adapter/codecept.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const debug = require('debug')('@testomatio/reporter:adapter:codeceptjs');
|
|
2
2
|
const chalk = require('chalk');
|
|
3
3
|
const TestomatClient = require('../client');
|
|
4
|
-
const { STATUS,
|
|
4
|
+
const { STATUS, TESTOMAT_TMP_STORAGE_DIR } = require('../constants');
|
|
5
5
|
const upload = require('../fileUploader');
|
|
6
6
|
const { parseTest: getIdFromTestTitle, fileSystem } = require('../utils/utils');
|
|
7
7
|
|
|
@@ -89,7 +89,7 @@ function CodeceptReporter(config) {
|
|
|
89
89
|
await Promise.all(reportTestPromises);
|
|
90
90
|
|
|
91
91
|
if (upload.isArtifactsEnabled()) {
|
|
92
|
-
uploadAttachments(client, videos, '🎞️
|
|
92
|
+
uploadAttachments(client, videos, '🎞️ Uploading', 'video');
|
|
93
93
|
uploadAttachments(client, traces, '📁 Uploading', 'trace');
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -147,9 +147,6 @@ function CodeceptReporter(config) {
|
|
|
147
147
|
failedTests.push(id || title);
|
|
148
148
|
let testId = parseTest(tags);
|
|
149
149
|
const testObj = getTestAndMessage(title);
|
|
150
|
-
if (error && error.stack && test.steps && test.steps.length) {
|
|
151
|
-
error.stack = test.steps[test.steps.length - 1].line();
|
|
152
|
-
}
|
|
153
150
|
|
|
154
151
|
const files = [];
|
|
155
152
|
if (artifacts.screenshot) files.push({ path: artifacts.screenshot, type: 'image/png' });
|
|
@@ -256,7 +253,7 @@ function CodeceptReporter(config) {
|
|
|
256
253
|
|
|
257
254
|
async function uploadAttachments(client, attachments, messagePrefix, attachmentType) {
|
|
258
255
|
if (attachments.length > 0) {
|
|
259
|
-
|
|
256
|
+
debug(`Attachments: ${messagePrefix} ${attachments.length} ${attachmentType}/-s ...`);
|
|
260
257
|
|
|
261
258
|
const promises = attachments.map(async (attachment) => {
|
|
262
259
|
const { testId, title, path, type } = attachment;
|
|
@@ -10,6 +10,7 @@ const testomatioReporter = on => {
|
|
|
10
10
|
const client = new TestomatClient({ apiKey: process.env.TESTOMATIO });
|
|
11
11
|
|
|
12
12
|
on('before:run', async (run) => {
|
|
13
|
+
// TODO: looks like client.env does not exist
|
|
13
14
|
if (!client.env) {
|
|
14
15
|
client.env = `${run.browser.displayName},${run.system.osName}`
|
|
15
16
|
}
|
|
@@ -25,8 +26,9 @@ const testomatioReporter = on => {
|
|
|
25
26
|
const lastAttemptIndex = test.attempts.length - 1;
|
|
26
27
|
const latestAttempt = test.attempts[lastAttemptIndex];
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
const
|
|
29
|
+
// latestAttempt.duration && latestAttempt.error were available in adapters version up to 13 JFYI
|
|
30
|
+
const time = latestAttempt.duration || latestAttempt.wallClockDuration || test.duration;
|
|
31
|
+
let error = latestAttempt.error;
|
|
30
32
|
|
|
31
33
|
let title = test.title.pop();
|
|
32
34
|
const examples = title.match(/\(example (#\d+)\)/);
|
|
@@ -39,19 +41,30 @@ const testomatioReporter = on => {
|
|
|
39
41
|
const testId = parseTest(title);
|
|
40
42
|
const suiteId = parseSuite(suiteTitle);
|
|
41
43
|
|
|
42
|
-
if (error) {
|
|
44
|
+
if (!error && test.displayError) {
|
|
45
|
+
error = { message: test.displayError };
|
|
43
46
|
error.inspect = function() { // eslint-disable-line func-names
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
return '';
|
|
48
|
-
}
|
|
47
|
+
return this.message;
|
|
48
|
+
};
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
const formattedError = error
|
|
52
|
+
? {
|
|
53
|
+
message: error.message,
|
|
54
|
+
inspect: error.inspect || function() { return this.message; },
|
|
55
|
+
}
|
|
56
|
+
: '';
|
|
57
|
+
|
|
58
|
+
const screenshots = Array.isArray(results.screenshots)
|
|
59
|
+
? results.screenshots
|
|
60
|
+
.filter(
|
|
61
|
+
screenshot =>
|
|
62
|
+
screenshot?.path &&
|
|
63
|
+
screenshot?.path.includes(title) &&
|
|
64
|
+
screenshot?.takenAt
|
|
65
|
+
)
|
|
66
|
+
.map(screenshot => screenshot.path)
|
|
67
|
+
: [];
|
|
55
68
|
|
|
56
69
|
const files = [...videos, ...screenshots];
|
|
57
70
|
|
|
@@ -65,8 +78,16 @@ const testomatioReporter = on => {
|
|
|
65
78
|
state = STATUS.SKIPPED;
|
|
66
79
|
}
|
|
67
80
|
|
|
68
|
-
addSpecTestsPromises.push(
|
|
69
|
-
|
|
81
|
+
addSpecTestsPromises.push(
|
|
82
|
+
client.addTestRun(state, {
|
|
83
|
+
title,
|
|
84
|
+
time,
|
|
85
|
+
example,
|
|
86
|
+
error: formattedError,
|
|
87
|
+
files,
|
|
88
|
+
suite_title: suiteTitle,
|
|
89
|
+
test_id: testId,
|
|
90
|
+
suite_id: suiteId
|
|
70
91
|
}));
|
|
71
92
|
}
|
|
72
93
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
const debug = require('debug')('@testomatio/reporter:adapter:playwright');
|
|
1
2
|
const chalk = require('chalk');
|
|
2
3
|
const crypto = require('crypto');
|
|
3
4
|
const os = require('os');
|
|
4
5
|
const path = require('path');
|
|
5
6
|
const fs = require('fs');
|
|
6
|
-
const {
|
|
7
|
+
const { STATUS: Status, TESTOMAT_TMP_STORAGE_DIR } = require('../constants');
|
|
7
8
|
const TestomatioClient = require('../client');
|
|
8
9
|
const { isArtifactsEnabled } = require('../fileUploader');
|
|
9
10
|
const { parseTest, fileSystem } = require('../utils/utils');
|
|
@@ -83,7 +84,7 @@ class PlaywrightReporter {
|
|
|
83
84
|
await Promise.all(reportTestPromises);
|
|
84
85
|
|
|
85
86
|
if (this.uploads.length && isArtifactsEnabled()) {
|
|
86
|
-
|
|
87
|
+
debug(`Attachments: 📁 Uploading ${this.uploads.length} files...`);
|
|
87
88
|
|
|
88
89
|
const promises = [];
|
|
89
90
|
|
|
@@ -95,7 +96,11 @@ class PlaywrightReporter {
|
|
|
95
96
|
const fileName = tmpFile();
|
|
96
97
|
fs.writeFileSync(fileName, attachment.body);
|
|
97
98
|
}
|
|
98
|
-
return {
|
|
99
|
+
return {
|
|
100
|
+
path: attachment.path,
|
|
101
|
+
title,
|
|
102
|
+
type: attachment.contentType
|
|
103
|
+
};
|
|
99
104
|
});
|
|
100
105
|
|
|
101
106
|
promises.push(
|
package/lib/bin/startTest.js
CHANGED
|
@@ -53,6 +53,12 @@ program
|
|
|
53
53
|
|
|
54
54
|
let exitCode = 0;
|
|
55
55
|
|
|
56
|
+
if (!command.split) {
|
|
57
|
+
process.exitCode = 255;
|
|
58
|
+
console.log(APP_PREFIX, `No command provided. Use -c option to launch a test runner.`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
56
62
|
const client = new TestomatClient({ apiKey, title, parallel: true });
|
|
57
63
|
|
|
58
64
|
if(filter) {
|
|
@@ -74,12 +80,6 @@ program
|
|
|
74
80
|
}
|
|
75
81
|
}
|
|
76
82
|
|
|
77
|
-
if (!command.split) {
|
|
78
|
-
process.exitCode = 255;
|
|
79
|
-
console.log(APP_PREFIX, `No command provided. Use -c option to launch a test runner.`);
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
83
|
const testCmds = command.split(' ');
|
|
84
84
|
console.log(APP_PREFIX, `🚀 Running`, chalk.green(command));
|
|
85
85
|
|
package/lib/client.js
CHANGED
|
@@ -169,19 +169,19 @@ class Client {
|
|
|
169
169
|
|
|
170
170
|
for (const file of files) {
|
|
171
171
|
uploadedFiles.push(upload.uploadFileByPath(file, this.uuid));
|
|
172
|
+
this.totalUploaded++;
|
|
172
173
|
}
|
|
173
174
|
|
|
174
175
|
for (const [idx, buffer] of filesBuffers.entries()) {
|
|
175
176
|
const fileName = `${idx + 1}-${title.replace(/\s+/g, '-')}`;
|
|
176
177
|
uploadedFiles.push(upload.uploadFileAsBuffer(buffer, fileName, this.uuid));
|
|
178
|
+
this.totalUploaded++;
|
|
177
179
|
}
|
|
178
180
|
|
|
179
181
|
const artifacts = await Promise.all(uploadedFiles);
|
|
180
182
|
|
|
181
183
|
// global.testomatioArtifacts = [];
|
|
182
184
|
|
|
183
|
-
this.totalUploaded += uploadedFiles.filter(n => n).length;
|
|
184
|
-
|
|
185
185
|
const data = {
|
|
186
186
|
files,
|
|
187
187
|
steps,
|
|
@@ -204,8 +204,13 @@ class Client {
|
|
|
204
204
|
this.pipes.map(async p => {
|
|
205
205
|
try {
|
|
206
206
|
const result = await p.addTest(data);
|
|
207
|
-
|
|
208
|
-
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
pipe: p.toString(),
|
|
210
|
+
result
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
209
214
|
console.log(APP_PREFIX, p.toString(), err);
|
|
210
215
|
}
|
|
211
216
|
}),
|
|
@@ -233,14 +238,27 @@ class Client {
|
|
|
233
238
|
.then(() => Promise.all(this.pipes.map(p => p.finishRun(runParams))))
|
|
234
239
|
.then(() => {
|
|
235
240
|
debug('TOTAL artifacts', this.totalUploaded);
|
|
236
|
-
if (this.totalUploaded && !upload.isArtifactsEnabled())
|
|
241
|
+
if (this.totalUploaded && !upload.isArtifactsEnabled()) {
|
|
237
242
|
debug(`${this.totalUploaded} artifacts are not uploaded, because artifacts uploading is not enabled`);
|
|
243
|
+
console.log(APP_PREFIX, `To ${chalk.bold('disable')} artifact uploads set: TESTOMATIO_DISABLE_ARTIFACTS=1`);
|
|
244
|
+
}
|
|
238
245
|
|
|
239
246
|
if (this.totalUploaded && upload.isArtifactsEnabled()) {
|
|
247
|
+
const isPrivate = process.env.TESTOMATIO_PRIVATE_ARTIFACTS;
|
|
248
|
+
|
|
249
|
+
if (!isPrivate) {
|
|
250
|
+
console.log(APP_PREFIX, `To enable ${chalk.bold('PRIVATE')} uploads set: TESTOMATIO_PRIVATE_ARTIFACTS=1`);
|
|
251
|
+
}
|
|
252
|
+
console.log(
|
|
253
|
+
APP_PREFIX,
|
|
254
|
+
`To enable ${chalk.bold('PUBLIC')} uploads remove TESTOMATIO_PRIVATE_ARTIFACTS env variable`,
|
|
255
|
+
);
|
|
256
|
+
console.log(APP_PREFIX, '---------------');
|
|
257
|
+
|
|
240
258
|
console.log(
|
|
241
259
|
APP_PREFIX,
|
|
242
260
|
`🗄️ ${this.totalUploaded} artifacts ${
|
|
243
|
-
|
|
261
|
+
isPrivate ? 'privately' : chalk.bold('publicly')
|
|
244
262
|
} uploaded to S3 bucket`,
|
|
245
263
|
);
|
|
246
264
|
}
|
package/lib/config.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// This file is used to read environment variables from .env file and process.env
|
|
2
|
+
|
|
3
|
+
// ! uncommenting next line leads ro reading vars from .env file
|
|
4
|
+
// require('dotenv').config();
|
|
5
|
+
const debug = require('debug')('@testomatio/reporter:config');
|
|
6
|
+
|
|
7
|
+
/* for possibility to use multiple env files (reading different paths)
|
|
8
|
+
const dotenv = require('dotenv');
|
|
9
|
+
const envFileVars = dotenv.config({ path: '.env' }).parsed; */
|
|
10
|
+
|
|
11
|
+
// select only TESTOMATIO related variables (only to print them in debug)
|
|
12
|
+
const testomatioEnvVars =
|
|
13
|
+
Object.keys(process.env)
|
|
14
|
+
.filter(key => key.startsWith('TESTOMATIO') || key.startsWith('S3_'))
|
|
15
|
+
.reduce((obj, key) => {
|
|
16
|
+
obj[key] = process.env[key];
|
|
17
|
+
return obj;
|
|
18
|
+
}, {}) || {};
|
|
19
|
+
debug('TESTOMATIO variables:', testomatioEnvVars);
|
|
20
|
+
|
|
21
|
+
// includes variables from .env file and process.env
|
|
22
|
+
const config = process.env;
|
|
23
|
+
|
|
24
|
+
module.exports = config;
|
package/lib/constants.js
CHANGED
|
@@ -20,10 +20,17 @@ const STATUS = {
|
|
|
20
20
|
SKIPPED: 'skipped',
|
|
21
21
|
FINISHED: 'finished',
|
|
22
22
|
};
|
|
23
|
+
// html pipe var
|
|
24
|
+
const HTML_REPORT = {
|
|
25
|
+
FOLDER: "html-report",
|
|
26
|
+
REPORT_DEFAULT_NAME: "testomatio-report.html",
|
|
27
|
+
TEMPLATE_NAME: 'testomatio.hbs'
|
|
28
|
+
};
|
|
23
29
|
|
|
24
30
|
module.exports = {
|
|
25
31
|
APP_PREFIX,
|
|
26
32
|
TESTOMAT_TMP_STORAGE_DIR,
|
|
27
33
|
CSV_HEADERS,
|
|
28
34
|
STATUS,
|
|
35
|
+
HTML_REPORT
|
|
29
36
|
}
|
package/lib/fileUploader.js
CHANGED
|
@@ -3,10 +3,16 @@ const { S3 } = require('@aws-sdk/client-s3');
|
|
|
3
3
|
const { Upload } = require('@aws-sdk/lib-storage');
|
|
4
4
|
|
|
5
5
|
const fs = require('fs');
|
|
6
|
+
const util = require('util');
|
|
6
7
|
const path = require('path');
|
|
8
|
+
const promiseRetry = require('promise-retry');
|
|
9
|
+
|
|
10
|
+
const readFile = util.promisify(fs.readFile);
|
|
11
|
+
const stat = util.promisify(fs.stat);
|
|
7
12
|
const chalk = require('chalk');
|
|
8
13
|
const { randomUUID } = require('crypto');
|
|
9
14
|
const memoize = require('lodash.memoize');
|
|
15
|
+
|
|
10
16
|
const { APP_PREFIX } = require('./constants');
|
|
11
17
|
|
|
12
18
|
const keys = [
|
|
@@ -93,62 +99,63 @@ const uploadUsingS3 = async (filePath, runId) => {
|
|
|
93
99
|
Key = filePath.name;
|
|
94
100
|
}
|
|
95
101
|
|
|
96
|
-
if (!fs.existsSync(filePath)) {
|
|
97
|
-
console.error(chalk.yellow(`Artifacts file ${filePath} does not exist. Skipping...`));
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
102
|
const {
|
|
102
|
-
TESTOMATIO_PRIVATE_ARTIFACTS,
|
|
103
|
+
TESTOMATIO_PRIVATE_ARTIFACTS,
|
|
104
|
+
S3_BUCKET
|
|
103
105
|
} = getConfig();
|
|
104
106
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const fileData = fs.readFileSync(filePath);
|
|
109
|
-
|
|
110
|
-
Key = `${runId}/${randomUUID()}-${Key || path.basename(filePath)}`;
|
|
111
|
-
const ACL = TESTOMATIO_PRIVATE_ARTIFACTS ? 'private' : 'public-read';
|
|
107
|
+
try {
|
|
108
|
+
debug('S3 config', getMaskedConfig());
|
|
109
|
+
debug('Started upload', filePath, 'to ', S3_BUCKET);
|
|
112
110
|
|
|
113
|
-
|
|
111
|
+
// Verification that the file was actually created: 20 attempts of 0.5 second => 10sec
|
|
112
|
+
const isFileExist = await checkFileExists(filePath, 20, 500);
|
|
114
113
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
ContentType,
|
|
120
|
-
ACL,
|
|
121
|
-
};
|
|
114
|
+
if (!isFileExist) {
|
|
115
|
+
console.error(chalk.yellow(`Artifacts file ${filePath} does not exist. Skipping...`));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
122
118
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
params
|
|
127
|
-
});
|
|
119
|
+
debug('File: ', filePath, ' exists');
|
|
120
|
+
|
|
121
|
+
const fileData = await readFile(filePath);
|
|
128
122
|
|
|
129
|
-
|
|
130
|
-
debug('Uploaded', out.singleUploadResult.Location)
|
|
123
|
+
Key = `${runId}/${randomUUID()}-${Key || path.basename(filePath)}`;
|
|
131
124
|
|
|
132
|
-
|
|
133
|
-
} catch (e) {
|
|
134
|
-
console.log(e);
|
|
135
|
-
console.log(APP_PREFIX, chalk.red(`Failed uploading '${Key}'. Please check S3 credentials`), getMaskedConfig());
|
|
125
|
+
const ACL = TESTOMATIO_PRIVATE_ARTIFACTS ? 'private' : 'public-read';
|
|
136
126
|
|
|
137
|
-
|
|
138
|
-
if (!TESTOMATIO_PRIVATE_ARTIFACTS) {
|
|
139
|
-
console.log(APP_PREFIX, `To enable ${chalk.bold('PRIVATE')} uploads set: TESTOMATIO_PRIVATE_ARTIFACTS=1`);
|
|
140
|
-
} else {
|
|
127
|
+
if (!S3_BUCKET || !fileData) {
|
|
141
128
|
console.log(
|
|
142
129
|
APP_PREFIX,
|
|
143
|
-
`
|
|
144
|
-
|
|
130
|
+
chalk.bold.red(`Failed uploading '${Key}'. Please check S3 credentials`), getMaskedConfig());
|
|
131
|
+
return;
|
|
145
132
|
}
|
|
133
|
+
|
|
134
|
+
const s3 = new S3(_getS3Config());
|
|
135
|
+
|
|
136
|
+
const params = {
|
|
137
|
+
Bucket: S3_BUCKET,
|
|
138
|
+
Key,
|
|
139
|
+
Body: fileData,
|
|
140
|
+
ContentType,
|
|
141
|
+
ACL,
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const out = new Upload({
|
|
145
|
+
client: s3,
|
|
146
|
+
params
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
return await getS3LocationLink(out);
|
|
150
|
+
}
|
|
151
|
+
catch (e) {
|
|
152
|
+
debug('S3 file uploading error: ', e);
|
|
153
|
+
console.log(APP_PREFIX, 'S3 file uploading error: ', e);
|
|
146
154
|
console.log(APP_PREFIX, '---------------');
|
|
147
155
|
}
|
|
148
156
|
};
|
|
149
157
|
|
|
150
158
|
const uploadUsingS3AsBuffer = async (buffer, fileName, runId) => {
|
|
151
|
-
|
|
152
159
|
const {
|
|
153
160
|
S3_REGION, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_ENDPOINT, TESTOMATIO_PRIVATE_ARTIFACTS, S3_BUCKET
|
|
154
161
|
} = getConfig();
|
|
@@ -158,6 +165,18 @@ const uploadUsingS3AsBuffer = async (buffer, fileName, runId) => {
|
|
|
158
165
|
const fileExtension = _getFileExtBase64(buffer.toString('base64'));
|
|
159
166
|
const Key = `${runId}/${fileName}${fileExtension}`;
|
|
160
167
|
|
|
168
|
+
if (!S3_BUCKET || !buffer) {
|
|
169
|
+
console.log(APP_PREFIX, chalk.bold.red(`Failed uploading '${Key}'. Please check S3 credentials`), {
|
|
170
|
+
accessKeyId: S3_ACCESS_KEY_ID,
|
|
171
|
+
secretAccessKey: S3_SECRET_ACCESS_KEY ? '**** (hidden) ***' : '(empty)',
|
|
172
|
+
region: S3_REGION,
|
|
173
|
+
bucket: S3_BUCKET,
|
|
174
|
+
acl: ACL,
|
|
175
|
+
endpoint: S3_ENDPOINT,
|
|
176
|
+
});
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
161
180
|
const s3 = new S3(_getS3Config());
|
|
162
181
|
|
|
163
182
|
try {
|
|
@@ -171,28 +190,13 @@ const uploadUsingS3AsBuffer = async (buffer, fileName, runId) => {
|
|
|
171
190
|
ACL,
|
|
172
191
|
}
|
|
173
192
|
});
|
|
174
|
-
await out.done();
|
|
175
193
|
|
|
176
|
-
return out
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
secretAccessKey: S3_SECRET_ACCESS_KEY ? '**** (hidden) ***' : '(empty)',
|
|
181
|
-
region: S3_REGION,
|
|
182
|
-
bucket: S3_BUCKET,
|
|
183
|
-
acl: ACL,
|
|
184
|
-
endpoint: S3_ENDPOINT,
|
|
185
|
-
});
|
|
194
|
+
return await getS3LocationLink(out);
|
|
195
|
+
}
|
|
196
|
+
catch (e) {
|
|
197
|
+
debug('S3 buffer uploading error: ', e);
|
|
186
198
|
|
|
187
|
-
console.log(APP_PREFIX,
|
|
188
|
-
if (!TESTOMATIO_PRIVATE_ARTIFACTS) {
|
|
189
|
-
console.log(APP_PREFIX, `To enable ${chalk.bold('PRIVATE')} uploads set: TESTOMATIO_PRIVATE_ARTIFACTS=1`);
|
|
190
|
-
} else {
|
|
191
|
-
console.log(
|
|
192
|
-
APP_PREFIX,
|
|
193
|
-
`To enable ${chalk.bold('PUBLIC')} uploads remove TESTOMATIO_PRIVATE_ARTIFACTS env variable`,
|
|
194
|
-
);
|
|
195
|
-
}
|
|
199
|
+
console.log(APP_PREFIX, 'S3 buffer uploading error: ', e);
|
|
196
200
|
console.log(APP_PREFIX, '---------------');
|
|
197
201
|
}
|
|
198
202
|
};
|
|
@@ -203,7 +207,9 @@ const uploadFileByPath = async (filePath, runId) => {
|
|
|
203
207
|
return uploadUsingS3(filePath, runId);
|
|
204
208
|
}
|
|
205
209
|
} catch (e) {
|
|
206
|
-
|
|
210
|
+
debug(e);
|
|
211
|
+
|
|
212
|
+
console.error(chalk.red('Error occurred while uploading artifacts! '), e);
|
|
207
213
|
}
|
|
208
214
|
};
|
|
209
215
|
|
|
@@ -213,10 +219,61 @@ const uploadFileAsBuffer = async (buffer, fileName, runId) => {
|
|
|
213
219
|
return uploadUsingS3AsBuffer(buffer, fileName, runId);
|
|
214
220
|
}
|
|
215
221
|
} catch (e) {
|
|
216
|
-
|
|
222
|
+
debug(e);
|
|
223
|
+
|
|
224
|
+
console.error(chalk.red('Error occurred while uploading artifacts! '), e);
|
|
217
225
|
}
|
|
218
226
|
};
|
|
219
227
|
|
|
228
|
+
const checkFileExists = async (filePath, attempts = 5, intervalMs = 500) => {
|
|
229
|
+
const checkFile = async () => {
|
|
230
|
+
const fileStats = await stat(filePath);
|
|
231
|
+
if (fileStats.isFile()) {
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
throw new Error('File not found');
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
try {
|
|
239
|
+
await promiseRetry(
|
|
240
|
+
{
|
|
241
|
+
retries: attempts,
|
|
242
|
+
minTimeout: intervalMs
|
|
243
|
+
},
|
|
244
|
+
checkFile
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
return true;
|
|
248
|
+
} catch (err) {
|
|
249
|
+
console.error(
|
|
250
|
+
chalk.yellow(`File ${filePath} was not found or did not have time to be generated...`)
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const getS3LocationLink = async (out) => {
|
|
258
|
+
const response = await out.done();
|
|
259
|
+
|
|
260
|
+
let s3Location = response?.Location;
|
|
261
|
+
|
|
262
|
+
debug('Uploaded response.Location', s3Location);
|
|
263
|
+
|
|
264
|
+
if (!s3Location) {
|
|
265
|
+
// TODO: out: a fallback case - remove after deeper testing
|
|
266
|
+
s3Location = out?.singleUploadResult?.Location;
|
|
267
|
+
debug('Uploaded singleUploadResult.Location', s3Location);
|
|
268
|
+
|
|
269
|
+
if (!s3Location) {
|
|
270
|
+
throw new Error("Problems getting the S3 artifact's link. Please check S3 permissions!");
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return s3Location;
|
|
275
|
+
};
|
|
276
|
+
|
|
220
277
|
module.exports = {
|
|
221
278
|
uploadFileByPath: memoize(uploadFileByPath),
|
|
222
279
|
uploadFileAsBuffer: memoize(uploadFileAsBuffer),
|
package/lib/pipe/gitlab.js
CHANGED
|
@@ -23,7 +23,7 @@ class GitLabPipe {
|
|
|
23
23
|
this.store = store;
|
|
24
24
|
this.tests = [];
|
|
25
25
|
// GitLab PAT looks like glpat-nKGdja3jsG4850sGksh7
|
|
26
|
-
this.token = params.GITLAB_PAT || this.ENV.GITLAB_PAT;
|
|
26
|
+
this.token = params.GITLAB_PAT || process.env.GITLAB_PAT || this.ENV.GITLAB_PAT;
|
|
27
27
|
this.hiddenCommentData = `<!--- testomat.io report ${process.env.CI_JOB_NAME || ''} -->`;
|
|
28
28
|
|
|
29
29
|
debug(
|