@testomatio/reporter 1.6.0-beta-2-artifacts → 1.6.0-beta-3-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 +24 -10
- package/lib/bin/reportXml.js +9 -4
- package/lib/bin/uploadArtifacts.js +4 -8
- package/lib/client.js +19 -18
- package/lib/pipe/gitlab.js +4 -4
- package/lib/pipe/testomatio.js +1 -1
- package/lib/uploader.js +28 -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,10 +168,16 @@ 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
|
+
process.env.TESTOMATIO_RUN ||= readLatestRunId();
|
|
176
|
+
|
|
177
|
+
if (!process.env.TESTOMATIO_RUN) {
|
|
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,
|
|
@@ -203,9 +217,9 @@ program
|
|
|
203
217
|
await client.addTestRun(undefined, { rid, files });
|
|
204
218
|
}
|
|
205
219
|
|
|
206
|
-
console.log(APP_PREFIX, client.uploader.
|
|
207
|
-
if (client.uploader.
|
|
208
|
-
console.log(APP_PREFIX, client.uploader.
|
|
220
|
+
console.log(APP_PREFIX, client.uploader.totalUploadsCount, 'artifacts uploaded');
|
|
221
|
+
if (client.uploader.failedUploadsCount) {
|
|
222
|
+
console.log(APP_PREFIX, client.uploader.failedUploadsCount, 'artifacts failed to upload');
|
|
209
223
|
}
|
|
210
224
|
});
|
|
211
225
|
|
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 {
|
|
@@ -13,7 +13,6 @@ program
|
|
|
13
13
|
.option('--env-file <envfile>', 'Load environment variables from env file')
|
|
14
14
|
.option('--force', 'Re-upload artifacts even if they were uploaded before')
|
|
15
15
|
.action(async opts => {
|
|
16
|
-
|
|
17
16
|
if (opts.envFile) {
|
|
18
17
|
require('dotenv').config(opts.envFile); // eslint-disable-line
|
|
19
18
|
} else {
|
|
@@ -29,7 +28,7 @@ program
|
|
|
29
28
|
const client = new TestomatClient({
|
|
30
29
|
apiKey,
|
|
31
30
|
isBatchEnabled: false,
|
|
32
|
-
|
|
31
|
+
});
|
|
33
32
|
|
|
34
33
|
let testruns = client.uploader.readUploadedFiles(process.env.TESTOMATIO_RUN);
|
|
35
34
|
|
|
@@ -56,8 +55,6 @@ program
|
|
|
56
55
|
return acc;
|
|
57
56
|
}, {});
|
|
58
57
|
|
|
59
|
-
let numArtifacts = 0;
|
|
60
|
-
|
|
61
58
|
// we need to obtain S3 credentials
|
|
62
59
|
await client.createRun();
|
|
63
60
|
|
|
@@ -66,16 +63,15 @@ program
|
|
|
66
63
|
|
|
67
64
|
for (const rid in testrunsByRid) {
|
|
68
65
|
const files = testrunsByRid[rid];
|
|
69
|
-
numArtifacts += files.length;
|
|
70
66
|
await client.addTestRun(undefined, {
|
|
71
67
|
rid,
|
|
72
68
|
files,
|
|
73
69
|
});
|
|
74
70
|
}
|
|
75
71
|
|
|
76
|
-
|
|
77
|
-
if (client.uploader.
|
|
78
|
-
console.log(APP_PREFIX, client.uploader.
|
|
72
|
+
console.log(APP_PREFIX, client.uploader.totalUploadsCount, 'artifacts uploaded');
|
|
73
|
+
if (client.uploader.failedUploadsCount) {
|
|
74
|
+
console.log(APP_PREFIX, client.uploader.failedUploadsCount, 'artifacts failed to upload');
|
|
79
75
|
}
|
|
80
76
|
});
|
|
81
77
|
|
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,33 @@ 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(APP_PREFIX, `${this.uploader.
|
|
265
|
+
if (this.uploader.failedUploadsCount) {
|
|
266
|
+
console.log(APP_PREFIX, `${this.uploader.failedUploadsCount} artifacts failed to upload`);
|
|
269
267
|
}
|
|
270
268
|
|
|
271
|
-
if (this.uploader.isEnabled && this.uploader.
|
|
272
|
-
console.log(APP_PREFIX, `${chalk.bold(this.uploader.
|
|
269
|
+
if (this.uploader.isEnabled && this.uploader.skippedUploadsCount) {
|
|
270
|
+
console.log(APP_PREFIX, `${chalk.bold(this.uploader.skippedUploadsCount)} artifacts skipped to upload`);
|
|
273
271
|
}
|
|
274
272
|
|
|
275
|
-
if (this.uploader.
|
|
276
|
-
|
|
273
|
+
if (this.uploader.skippedUploadsCount || this.uploader.failedUploadsCount) {
|
|
274
|
+
const command = `TESTOMATIO_RUN=${this.runId} npx upload-artifacts`;
|
|
275
|
+
console.log(
|
|
276
|
+
APP_PREFIX,
|
|
277
|
+
`Run "${chalk.magenta(command)}" with valid S3 credentials to upload skipped & failed artifacts`,
|
|
278
|
+
);
|
|
277
279
|
}
|
|
278
|
-
|
|
279
280
|
})
|
|
280
281
|
.catch(err => console.log(APP_PREFIX, err));
|
|
281
282
|
|
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,18 +153,18 @@ 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) {
|
|
@@ -179,21 +172,18 @@ class S3Uploader {
|
|
|
179
172
|
|
|
180
173
|
if (!this.isEnabled) {
|
|
181
174
|
this.storeUploadedFile(filePath, runId, rid, false);
|
|
182
|
-
this.
|
|
175
|
+
this.skippedUploadsCount++;
|
|
183
176
|
return;
|
|
184
177
|
}
|
|
185
178
|
|
|
186
|
-
const {
|
|
187
|
-
S3_BUCKET,
|
|
188
|
-
TESTOMATIO_ARTIFACTS_SIZE,
|
|
189
|
-
} = this.getConfig();
|
|
179
|
+
const { S3_BUCKET, TESTOMATIO_ARTIFACT_MAX_SIZE_MB } = this.getConfig();
|
|
190
180
|
|
|
191
181
|
debug('Started upload', filePath, 'to', S3_BUCKET);
|
|
192
182
|
|
|
193
183
|
const isFileExist = await this.checkFileExists(filePath, 20, 500);
|
|
194
184
|
|
|
195
185
|
if (!isFileExist) {
|
|
196
|
-
this.
|
|
186
|
+
this.failedUploadsCount++;
|
|
197
187
|
console.error(chalk.yellow(`Artifacts file ${filePath} does not exist. Skipping...`));
|
|
198
188
|
return;
|
|
199
189
|
}
|
|
@@ -201,8 +191,8 @@ class S3Uploader {
|
|
|
201
191
|
const fileSize = fs.statSync(filePath).size;
|
|
202
192
|
const fileSizeInMb = fileSize / (1024 * 1024);
|
|
203
193
|
|
|
204
|
-
if (
|
|
205
|
-
this.
|
|
194
|
+
if (TESTOMATIO_ARTIFACT_MAX_SIZE_MB && fileSizeInMb > parseInt(TESTOMATIO_ARTIFACT_MAX_SIZE_MB, 10)) {
|
|
195
|
+
this.skippedUploadsCount++;
|
|
206
196
|
console.error(chalk.yellow(`Artifacts file ${filePath} exceeds the maximum allowed size. Skipping...`));
|
|
207
197
|
return;
|
|
208
198
|
}
|
|
@@ -242,7 +232,9 @@ class S3Uploader {
|
|
|
242
232
|
return false;
|
|
243
233
|
}
|
|
244
234
|
debug(`File not found, retrying (attempt ${number}/${attempts})`);
|
|
245
|
-
await new Promise(
|
|
235
|
+
await new Promise(resolve => {
|
|
236
|
+
setTimeout(resolve, intervalMs);
|
|
237
|
+
});
|
|
246
238
|
retry(err);
|
|
247
239
|
}
|
|
248
240
|
},
|
|
@@ -250,7 +242,7 @@ class S3Uploader {
|
|
|
250
242
|
retries: attempts,
|
|
251
243
|
minTimeout: intervalMs,
|
|
252
244
|
maxTimeout: intervalMs,
|
|
253
|
-
}
|
|
245
|
+
},
|
|
254
246
|
);
|
|
255
247
|
}
|
|
256
248
|
|
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,
|