@testomatio/reporter 1.6.0-beta-2-artifacts → 1.6.0-beta-4-artifacts
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 +4 -2
- package/lib/adapter/playwright.js +1 -2
- package/lib/bin/cli.js +25 -10
- package/lib/bin/reportXml.js +9 -4
- package/lib/bin/uploadArtifacts.js +13 -12
- package/lib/client.js +23 -18
- package/lib/pipe/gitlab.js +4 -4
- package/lib/pipe/testomatio.js +1 -1
- package/lib/uploader.js +29 -36
- package/lib/utils/utils.js +23 -0
- package/package.json +1 -1
package/lib/adapter/codecept.js
CHANGED
|
@@ -301,9 +301,11 @@ function CodeceptReporter(config) {
|
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
async function uploadAttachments(client, attachments, messagePrefix, attachmentType) {
|
|
304
|
-
if (!attachments?.length) return;
|
|
304
|
+
if (!attachments?.length) return;
|
|
305
305
|
|
|
306
|
-
if (client.uploader.isEnabled)
|
|
306
|
+
if (client.uploader.isEnabled) {
|
|
307
|
+
console.log(APP_PREFIX, `Attachments: ${messagePrefix} ${attachments.length} ${attachmentType} ...`);
|
|
308
|
+
}
|
|
307
309
|
|
|
308
310
|
const promises = attachments.map(async attachment => {
|
|
309
311
|
const { rid, title, path, type } = attachment;
|
|
@@ -106,7 +106,7 @@ class PlaywrightReporter {
|
|
|
106
106
|
await Promise.all(reportTestPromises);
|
|
107
107
|
|
|
108
108
|
if (!this.uploads.length) return;
|
|
109
|
-
|
|
109
|
+
|
|
110
110
|
if (this.client.uploader.isEnabled) console.log(APP_PREFIX, `🎞️ Uploading ${this.uploads.length} files...`);
|
|
111
111
|
|
|
112
112
|
const promises = [];
|
|
@@ -135,7 +135,6 @@ class PlaywrightReporter {
|
|
|
135
135
|
);
|
|
136
136
|
}
|
|
137
137
|
await Promise.all(promises);
|
|
138
|
-
|
|
139
138
|
|
|
140
139
|
await this.client.updateRunStatus(checkStatus(result.status));
|
|
141
140
|
}
|
package/lib/bin/cli.js
CHANGED
|
@@ -9,13 +9,14 @@ const XmlReader = require('../xmlReader');
|
|
|
9
9
|
const { APP_PREFIX, STATUS } = require('../constants');
|
|
10
10
|
const { version } = require('../../package.json');
|
|
11
11
|
const config = require('../config');
|
|
12
|
+
const { readLatestRunId } = require('../utils/utils');
|
|
12
13
|
|
|
13
14
|
console.log(chalk.cyan.bold(` 🤩 Testomat.io Reporter v${version}`));
|
|
14
15
|
|
|
15
16
|
program
|
|
16
17
|
.version(version)
|
|
17
18
|
.option('--env-file <envfile>', 'Load environment variables from env file')
|
|
18
|
-
.hook('preAction',
|
|
19
|
+
.hook('preAction', thisCommand => {
|
|
19
20
|
const opts = thisCommand.opts();
|
|
20
21
|
if (opts.envFile) {
|
|
21
22
|
require('dotenv').config({ path: opts.envFile });
|
|
@@ -42,8 +43,10 @@ program
|
|
|
42
43
|
.command('finish')
|
|
43
44
|
.description('Finish Run by its ID')
|
|
44
45
|
.action(async () => {
|
|
46
|
+
process.env.TESTOMATIO_RUN ||= readLatestRunId();
|
|
47
|
+
|
|
45
48
|
if (!process.env.TESTOMATIO_RUN) {
|
|
46
|
-
console.log('TESTOMATIO_RUN environment variable must be set.');
|
|
49
|
+
console.log('TESTOMATIO_RUN environment variable must be set or restored from a previous run.');
|
|
47
50
|
return process.exit(1);
|
|
48
51
|
}
|
|
49
52
|
|
|
@@ -140,10 +143,15 @@ program
|
|
|
140
143
|
|
|
141
144
|
let timeoutTimer;
|
|
142
145
|
if (opts.timelimit) {
|
|
143
|
-
timeoutTimer = setTimeout(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
146
|
+
timeoutTimer = setTimeout(
|
|
147
|
+
() => {
|
|
148
|
+
console.log(
|
|
149
|
+
`⚠️ Reached timeout of ${opts.timelimit}s. Exiting... (Exit code is 0 to not fail the pipeline)`,
|
|
150
|
+
);
|
|
151
|
+
process.exit(0);
|
|
152
|
+
},
|
|
153
|
+
parseInt(opts.timelimit, 10) * 1000,
|
|
154
|
+
);
|
|
147
155
|
}
|
|
148
156
|
|
|
149
157
|
try {
|
|
@@ -160,13 +168,20 @@ program
|
|
|
160
168
|
.command('upload-artifacts')
|
|
161
169
|
.description('Upload artifacts to Testomat.io')
|
|
162
170
|
.option('--force', 'Re-upload artifacts even if they were uploaded before')
|
|
163
|
-
.action(async
|
|
171
|
+
.action(async opts => {
|
|
164
172
|
const apiKey = config.TESTOMATIO;
|
|
165
173
|
|
|
166
174
|
process.env.TESTOMATIO_DISABLE_ARTIFACTS = '';
|
|
175
|
+
const runId = process.env.TESTOMATIO_RUN || process.env.runId || readLatestRunId();
|
|
176
|
+
|
|
177
|
+
if (!runId) {
|
|
178
|
+
console.log('TESTOMATIO_RUN environment variable must be set or restored from a previous run.');
|
|
179
|
+
return process.exit(1);
|
|
180
|
+
}
|
|
167
181
|
|
|
168
182
|
const client = new TestomatClient({
|
|
169
183
|
apiKey,
|
|
184
|
+
runId,
|
|
170
185
|
isBatchEnabled: false,
|
|
171
186
|
});
|
|
172
187
|
|
|
@@ -203,9 +218,9 @@ program
|
|
|
203
218
|
await client.addTestRun(undefined, { rid, files });
|
|
204
219
|
}
|
|
205
220
|
|
|
206
|
-
console.log(APP_PREFIX, client.uploader.
|
|
207
|
-
if (client.uploader.
|
|
208
|
-
console.log(APP_PREFIX, client.uploader.
|
|
221
|
+
console.log(APP_PREFIX, client.uploader.totalUploadsCount, 'artifacts uploaded');
|
|
222
|
+
if (client.uploader.failedUploadsCount) {
|
|
223
|
+
console.log(APP_PREFIX, client.uploader.failedUploadsCount, 'artifacts failed to upload');
|
|
209
224
|
}
|
|
210
225
|
});
|
|
211
226
|
|
package/lib/bin/reportXml.js
CHANGED
|
@@ -44,10 +44,15 @@ program
|
|
|
44
44
|
|
|
45
45
|
let timeoutTimer;
|
|
46
46
|
if (opts.timelimit) {
|
|
47
|
-
timeoutTimer = setTimeout(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
timeoutTimer = setTimeout(
|
|
48
|
+
() => {
|
|
49
|
+
console.log(
|
|
50
|
+
`⚠️ Reached timeout of ${opts.timelimit}s. Exiting... (Exit code is 0 to not fail the pipeline)`,
|
|
51
|
+
);
|
|
52
|
+
process.exit(0);
|
|
53
|
+
},
|
|
54
|
+
parseInt(opts.timelimit, 10) * 1000,
|
|
55
|
+
);
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
try {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const program = require('commander');
|
|
2
|
+
const { program } = require('commander');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const debug = require('debug')('@testomatio/reporter:upload-cli');
|
|
5
5
|
const TestomatClient = require('../client');
|
|
6
6
|
const { APP_PREFIX } = require('../constants');
|
|
7
7
|
const { version } = require('../../package.json');
|
|
8
8
|
const config = require('../config');
|
|
9
|
+
const { readLatestRunId } = require('../utils/utils');
|
|
9
10
|
|
|
10
11
|
console.log(chalk.cyan.bold(` 🤩 Testomat.io Reporter v${version}`));
|
|
11
12
|
|
|
@@ -13,7 +14,6 @@ program
|
|
|
13
14
|
.option('--env-file <envfile>', 'Load environment variables from env file')
|
|
14
15
|
.option('--force', 'Re-upload artifacts even if they were uploaded before')
|
|
15
16
|
.action(async opts => {
|
|
16
|
-
|
|
17
17
|
if (opts.envFile) {
|
|
18
18
|
require('dotenv').config(opts.envFile); // eslint-disable-line
|
|
19
19
|
} else {
|
|
@@ -22,15 +22,19 @@ program
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const apiKey = config.TESTOMATIO;
|
|
25
|
-
|
|
26
25
|
process.env.TESTOMATIO_DISABLE_ARTIFACTS = '';
|
|
27
|
-
|
|
26
|
+
const runId = process.env.TESTOMATIO_RUN || process.env.runId || readLatestRunId();
|
|
27
|
+
|
|
28
|
+
if (!runId) {
|
|
29
|
+
console.log('TESTOMATIO_RUN environment variable must be set or restored from a previous run.');
|
|
30
|
+
return process.exit(1);
|
|
31
|
+
}
|
|
28
32
|
|
|
29
33
|
const client = new TestomatClient({
|
|
30
34
|
apiKey,
|
|
35
|
+
runId,
|
|
31
36
|
isBatchEnabled: false,
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
});
|
|
34
38
|
let testruns = client.uploader.readUploadedFiles(process.env.TESTOMATIO_RUN);
|
|
35
39
|
|
|
36
40
|
const numTotalArtifacts = testruns.length;
|
|
@@ -56,8 +60,6 @@ program
|
|
|
56
60
|
return acc;
|
|
57
61
|
}, {});
|
|
58
62
|
|
|
59
|
-
let numArtifacts = 0;
|
|
60
|
-
|
|
61
63
|
// we need to obtain S3 credentials
|
|
62
64
|
await client.createRun();
|
|
63
65
|
|
|
@@ -66,16 +68,15 @@ program
|
|
|
66
68
|
|
|
67
69
|
for (const rid in testrunsByRid) {
|
|
68
70
|
const files = testrunsByRid[rid];
|
|
69
|
-
numArtifacts += files.length;
|
|
70
71
|
await client.addTestRun(undefined, {
|
|
71
72
|
rid,
|
|
72
73
|
files,
|
|
73
74
|
});
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
if (client.uploader.
|
|
78
|
-
console.log(APP_PREFIX, client.uploader.
|
|
77
|
+
console.log(APP_PREFIX, client.uploader.totalUploadsCount, 'artifacts uploaded');
|
|
78
|
+
if (client.uploader.failedUploadsCount) {
|
|
79
|
+
console.log(APP_PREFIX, client.uploader.failedUploadsCount, 'artifacts failed to upload');
|
|
79
80
|
}
|
|
80
81
|
});
|
|
81
82
|
|
package/lib/client.js
CHANGED
|
@@ -10,6 +10,7 @@ const { APP_PREFIX, STATUS } = require('./constants');
|
|
|
10
10
|
const pipesFactory = require('./pipe');
|
|
11
11
|
const { glob } = require('glob');
|
|
12
12
|
const path = require('path');
|
|
13
|
+
const { storeRunId } = require('./utils/utils');
|
|
13
14
|
|
|
14
15
|
let listOfTestFilesToExcludeFromReport = null;
|
|
15
16
|
|
|
@@ -107,6 +108,8 @@ class Client {
|
|
|
107
108
|
.then(() => {
|
|
108
109
|
const runId = this.pipeStore?.runId;
|
|
109
110
|
if (runId) this.runId = runId;
|
|
111
|
+
storeRunId(this.runId);
|
|
112
|
+
|
|
110
113
|
this.uploader.checkEnabled();
|
|
111
114
|
})
|
|
112
115
|
.then(() => undefined); // fixes return type
|
|
@@ -182,12 +185,7 @@ class Client {
|
|
|
182
185
|
f = f.path;
|
|
183
186
|
}
|
|
184
187
|
|
|
185
|
-
uploadedFiles.push(this.uploader.uploadFileByPath(f, [
|
|
186
|
-
this.runId,
|
|
187
|
-
rid,
|
|
188
|
-
path.basename(f)
|
|
189
|
-
]));
|
|
190
|
-
|
|
188
|
+
uploadedFiles.push(this.uploader.uploadFileByPath(f, [this.runId, rid, path.basename(f)]));
|
|
191
189
|
}
|
|
192
190
|
|
|
193
191
|
for (const [idx, buffer] of filesBuffers.entries()) {
|
|
@@ -252,30 +250,37 @@ class Client {
|
|
|
252
250
|
this.queue = this.queue
|
|
253
251
|
.then(() => Promise.all(this.pipes.map(p => p.finishRun(runParams))))
|
|
254
252
|
.then(() => {
|
|
255
|
-
debug('TOTAL artifacts', this.uploader.
|
|
256
|
-
debug(`${this.uploader.
|
|
253
|
+
debug('TOTAL artifacts', this.uploader.totalUploadsCount);
|
|
254
|
+
debug(`${this.uploader.skippedUploadsCount} artifacts skipped`);
|
|
257
255
|
|
|
258
|
-
if (this.uploader.
|
|
256
|
+
if (this.uploader.totalUploadsCount && this.uploader.isEnabled) {
|
|
259
257
|
console.log(
|
|
260
258
|
APP_PREFIX,
|
|
261
|
-
`🗄️ ${this.uploader.
|
|
259
|
+
`🗄️ ${this.uploader.totalUploadsCount} artifacts ${
|
|
262
260
|
process.env.TESTOMATIO_PRIVATE_ARTIFACTS ? 'privately' : chalk.bold('publicly')
|
|
263
261
|
} uploaded to S3 bucket`,
|
|
264
|
-
);
|
|
262
|
+
);
|
|
265
263
|
}
|
|
266
264
|
|
|
267
|
-
if (this.uploader.
|
|
268
|
-
console.log(
|
|
265
|
+
if (this.uploader.failedUploadsCount) {
|
|
266
|
+
console.log(
|
|
267
|
+
APP_PREFIX,
|
|
268
|
+
chalk.gray('[CLIENT]'),
|
|
269
|
+
`${this.uploader.failedUploadsCount} artifacts failed to upload`,
|
|
270
|
+
);
|
|
269
271
|
}
|
|
270
272
|
|
|
271
|
-
if (this.uploader.isEnabled && this.uploader.
|
|
272
|
-
console.log(APP_PREFIX, `${chalk.bold(this.uploader.
|
|
273
|
+
if (this.uploader.isEnabled && this.uploader.skippedUploadsCount) {
|
|
274
|
+
console.log(APP_PREFIX, `${chalk.bold(this.uploader.skippedUploadsCount)} artifacts skipped to upload`);
|
|
273
275
|
}
|
|
274
276
|
|
|
275
|
-
if (this.uploader.
|
|
276
|
-
|
|
277
|
+
if (this.uploader.skippedUploadsCount || this.uploader.failedUploadsCount) {
|
|
278
|
+
const command = `TESTOMATIO_RUN=${this.runId} npx @testomatio/reporter upload-artifacts`;
|
|
279
|
+
console.log(
|
|
280
|
+
APP_PREFIX,
|
|
281
|
+
`Run "${chalk.magenta(command)}" with valid S3 credentials to upload skipped & failed artifacts`,
|
|
282
|
+
);
|
|
277
283
|
}
|
|
278
|
-
|
|
279
284
|
})
|
|
280
285
|
.catch(err => console.log(APP_PREFIX, err));
|
|
281
286
|
|
package/lib/pipe/gitlab.js
CHANGED
|
@@ -79,13 +79,13 @@ class GitLabPipe {
|
|
|
79
79
|
let summary = `${this.hiddenCommentData}
|
|
80
80
|
|
|
81
81
|
| [](https://testomat.io) | ${statusEmoji(
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
runParams.status,
|
|
83
|
+
)} ${runParams.status.toUpperCase()} ${statusEmoji(runParams.status)} |
|
|
84
84
|
| --- | --- |
|
|
85
85
|
| Tests | ✔️ **${this.tests.length}** tests run |
|
|
86
86
|
| Summary | ${statusEmoji('failed')} **${failedCount}** failed; ${statusEmoji(
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
'passed',
|
|
88
|
+
)} **${passedCount}** passed; **${statusEmoji('skipped')}** ${skippedCount} skipped |
|
|
89
89
|
| Duration | 🕐 **${humanizeDuration(
|
|
90
90
|
parseInt(
|
|
91
91
|
this.tests.reduce((a, t) => a + (t.run_time || 0), 0),
|
package/lib/pipe/testomatio.js
CHANGED
|
@@ -214,7 +214,7 @@ class TestomatioPipe {
|
|
|
214
214
|
this.store.runPublicUrl = this.runPublicUrl;
|
|
215
215
|
this.store.runId = this.runId;
|
|
216
216
|
console.log(APP_PREFIX, '📊 Report created. Report ID:', this.runId);
|
|
217
|
-
process.env.runId = this.runId;
|
|
217
|
+
process.env.runId = this.runId;
|
|
218
218
|
debug('Run created', this.runId);
|
|
219
219
|
} catch (err) {
|
|
220
220
|
console.error(
|
package/lib/uploader.js
CHANGED
|
@@ -15,9 +15,9 @@ class S3Uploader {
|
|
|
15
15
|
this.config = undefined;
|
|
16
16
|
|
|
17
17
|
// counters
|
|
18
|
-
this.
|
|
19
|
-
this.
|
|
20
|
-
this.
|
|
18
|
+
this.skippedUploadsCount = 0;
|
|
19
|
+
this.failedUploadsCount = 0;
|
|
20
|
+
this.totalUploadsCount = 0;
|
|
21
21
|
|
|
22
22
|
this.succesfulUploads = {};
|
|
23
23
|
|
|
@@ -31,7 +31,7 @@ class S3Uploader {
|
|
|
31
31
|
'S3_FORCE_PATH_STYLE',
|
|
32
32
|
'TESTOMATIO_DISABLE_ARTIFACTS',
|
|
33
33
|
'TESTOMATIO_PRIVATE_ARTIFACTS',
|
|
34
|
-
'
|
|
34
|
+
'TESTOMATIO_ARTIFACT_MAX_SIZE_MB',
|
|
35
35
|
];
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -84,7 +84,11 @@ class S3Uploader {
|
|
|
84
84
|
const ACL = TESTOMATIO_PRIVATE_ARTIFACTS ? 'private' : 'public-read';
|
|
85
85
|
|
|
86
86
|
if (!S3_BUCKET || !Body) {
|
|
87
|
-
console.log(
|
|
87
|
+
console.log(
|
|
88
|
+
APP_PREFIX,
|
|
89
|
+
chalk.bold.red(`Failed uploading '${Key}'. Please check S3 credentials`),
|
|
90
|
+
this.getMaskedConfig(),
|
|
91
|
+
);
|
|
88
92
|
return;
|
|
89
93
|
}
|
|
90
94
|
|
|
@@ -104,17 +108,17 @@ class S3Uploader {
|
|
|
104
108
|
});
|
|
105
109
|
|
|
106
110
|
const link = await this.getS3LocationLink(upload);
|
|
107
|
-
this.
|
|
111
|
+
this.totalUploadsCount++;
|
|
108
112
|
this.succesfulUploads[Key] = link;
|
|
109
113
|
return link;
|
|
110
114
|
} catch (e) {
|
|
111
|
-
this.
|
|
115
|
+
this.failedUploadsCount++;
|
|
112
116
|
debug('S3 uploading error:', e);
|
|
113
|
-
console.log(APP_PREFIX,
|
|
117
|
+
console.log(APP_PREFIX, 'Upload failed:', e.message, this.getMaskedConfig());
|
|
114
118
|
}
|
|
115
119
|
}
|
|
116
120
|
|
|
117
|
-
readUploadedFiles(runId
|
|
121
|
+
readUploadedFiles(runId) {
|
|
118
122
|
const tempFilePath = this.#getUploadFilePath(runId);
|
|
119
123
|
|
|
120
124
|
debug('Reading file', tempFilePath);
|
|
@@ -125,10 +129,10 @@ class S3Uploader {
|
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
const stats = fs.statSync(tempFilePath);
|
|
128
|
-
const diff =
|
|
132
|
+
const diff = +new Date() - +stats.mtime;
|
|
129
133
|
const diffHours = diff / 1000 / 60 / 60;
|
|
130
134
|
if (diffHours > 3) {
|
|
131
|
-
console.log(APP_PREFIX,
|
|
135
|
+
console.log(APP_PREFIX, "Artifacts file is too old, can't process artifacts. Please re-run the tests.");
|
|
132
136
|
return [];
|
|
133
137
|
}
|
|
134
138
|
|
|
@@ -137,22 +141,11 @@ class S3Uploader {
|
|
|
137
141
|
return lines.map(line => JSON.parse(line));
|
|
138
142
|
}
|
|
139
143
|
|
|
140
|
-
#getUploadFilePath(runId
|
|
141
|
-
if (!runId && !forceCreate) {
|
|
142
|
-
return path.join(os.tmpdir(), 'testomatio.run.latest.jsonl');
|
|
143
|
-
}
|
|
144
|
-
|
|
144
|
+
#getUploadFilePath(runId, forceCreate = false) {
|
|
145
145
|
const tempFilePath = path.join(os.tmpdir(), `testomatio.run.${runId}.jsonl`);
|
|
146
146
|
if (!fs.existsSync(tempFilePath) || forceCreate) {
|
|
147
147
|
debug('Creating artifacts file:', tempFilePath);
|
|
148
148
|
fs.writeFileSync(tempFilePath, '');
|
|
149
|
-
// make symlink to 'testomatio.run.latest.jsonl' file
|
|
150
|
-
const latestFilePath = path.join(os.tmpdir(), 'testomatio.run.latest.jsonl');
|
|
151
|
-
if (fs.existsSync(latestFilePath)) {
|
|
152
|
-
fs.unlinkSync(latestFilePath);
|
|
153
|
-
}
|
|
154
|
-
fs.symlinkSync(tempFilePath, latestFilePath);
|
|
155
|
-
|
|
156
149
|
}
|
|
157
150
|
return tempFilePath;
|
|
158
151
|
}
|
|
@@ -160,40 +153,38 @@ class S3Uploader {
|
|
|
160
153
|
storeUploadedFile(filePath, runId, rid, uploaded = false) {
|
|
161
154
|
if (!this.storeEnabled) return;
|
|
162
155
|
|
|
163
|
-
if (!filePath || !runId || !rid
|
|
156
|
+
if (!filePath || !runId || !rid) return;
|
|
164
157
|
|
|
165
158
|
const tempFilePath = this.#getUploadFilePath(runId);
|
|
166
159
|
|
|
167
160
|
const data = { rid, file: filePath, uploaded };
|
|
168
|
-
const jsonLine = JSON.stringify(data)
|
|
161
|
+
const jsonLine = `${JSON.stringify(data)}\n`;
|
|
169
162
|
|
|
170
163
|
fs.appendFileSync(tempFilePath, jsonLine);
|
|
171
164
|
}
|
|
172
165
|
|
|
173
166
|
getskippedUpload() {
|
|
174
|
-
return this.
|
|
167
|
+
return this.skippedUploadsCount;
|
|
175
168
|
}
|
|
176
169
|
|
|
177
170
|
async uploadFileByPath(filePath, pathInS3) {
|
|
178
171
|
const [runId, rid] = pathInS3;
|
|
179
172
|
|
|
173
|
+
if (!filePath) return;
|
|
174
|
+
|
|
180
175
|
if (!this.isEnabled) {
|
|
181
176
|
this.storeUploadedFile(filePath, runId, rid, false);
|
|
182
|
-
this.
|
|
177
|
+
this.skippedUploadsCount++;
|
|
183
178
|
return;
|
|
184
179
|
}
|
|
185
180
|
|
|
186
|
-
const {
|
|
187
|
-
S3_BUCKET,
|
|
188
|
-
TESTOMATIO_ARTIFACTS_SIZE,
|
|
189
|
-
} = this.getConfig();
|
|
181
|
+
const { S3_BUCKET, TESTOMATIO_ARTIFACT_MAX_SIZE_MB } = this.getConfig();
|
|
190
182
|
|
|
191
183
|
debug('Started upload', filePath, 'to', S3_BUCKET);
|
|
192
184
|
|
|
193
185
|
const isFileExist = await this.checkFileExists(filePath, 20, 500);
|
|
194
186
|
|
|
195
187
|
if (!isFileExist) {
|
|
196
|
-
this.failedUpload++;
|
|
197
188
|
console.error(chalk.yellow(`Artifacts file ${filePath} does not exist. Skipping...`));
|
|
198
189
|
return;
|
|
199
190
|
}
|
|
@@ -201,8 +192,8 @@ class S3Uploader {
|
|
|
201
192
|
const fileSize = fs.statSync(filePath).size;
|
|
202
193
|
const fileSizeInMb = fileSize / (1024 * 1024);
|
|
203
194
|
|
|
204
|
-
if (
|
|
205
|
-
this.
|
|
195
|
+
if (TESTOMATIO_ARTIFACT_MAX_SIZE_MB && fileSizeInMb > parseInt(TESTOMATIO_ARTIFACT_MAX_SIZE_MB, 10)) {
|
|
196
|
+
this.skippedUploadsCount++;
|
|
206
197
|
console.error(chalk.yellow(`Artifacts file ${filePath} exceeds the maximum allowed size. Skipping...`));
|
|
207
198
|
return;
|
|
208
199
|
}
|
|
@@ -242,7 +233,9 @@ class S3Uploader {
|
|
|
242
233
|
return false;
|
|
243
234
|
}
|
|
244
235
|
debug(`File not found, retrying (attempt ${number}/${attempts})`);
|
|
245
|
-
await new Promise(
|
|
236
|
+
await new Promise(resolve => {
|
|
237
|
+
setTimeout(resolve, intervalMs);
|
|
238
|
+
});
|
|
246
239
|
retry(err);
|
|
247
240
|
}
|
|
248
241
|
},
|
|
@@ -250,7 +243,7 @@ class S3Uploader {
|
|
|
250
243
|
retries: attempts,
|
|
251
244
|
minTimeout: intervalMs,
|
|
252
245
|
maxTimeout: intervalMs,
|
|
253
|
-
}
|
|
246
|
+
},
|
|
254
247
|
);
|
|
255
248
|
}
|
|
256
249
|
|
package/lib/utils/utils.js
CHANGED
|
@@ -3,6 +3,8 @@ const { sep, basename } = require('path');
|
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const isValid = require('is-valid-path');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
6
8
|
const debug = require('debug')('@testomatio/reporter:util');
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -318,7 +320,28 @@ const testRunnerHelper = {
|
|
|
318
320
|
},
|
|
319
321
|
};
|
|
320
322
|
|
|
323
|
+
function storeRunId(runId) {
|
|
324
|
+
const filePath = path.join(os.tmpdir(), `testomatio.latest.run`);
|
|
325
|
+
fs.writeFileSync(filePath, runId);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function readLatestRunId() {
|
|
329
|
+
try {
|
|
330
|
+
const filePath = path.join(os.tmpdir(), `testomatio.latest.run`);
|
|
331
|
+
const stats = fs.statSync(filePath);
|
|
332
|
+
const diff = +new Date() - +stats.mtime;
|
|
333
|
+
const diffHours = diff / 1000 / 60 / 60;
|
|
334
|
+
if (diffHours > 1) return;
|
|
335
|
+
|
|
336
|
+
return fs.readFileSync(filePath)?.toString()?.trim();
|
|
337
|
+
} catch (e) {
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
321
342
|
module.exports = {
|
|
343
|
+
storeRunId,
|
|
344
|
+
readLatestRunId,
|
|
322
345
|
isSameTest,
|
|
323
346
|
fetchSourceCode,
|
|
324
347
|
fetchSourceCodeFromStackTrace,
|