@testomatio/reporter 0.4.2 → 0.4.6
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/Changelog.md +17 -0
- package/README.md +6 -0
- package/lib/adapter/codecept.js +13 -5
- package/lib/adapter/playwright.js +2 -1
- package/lib/bin/startTest.js +8 -2
- package/lib/client.js +5 -4
- package/lib/fileUploader.js +40 -10
- package/package.json +1 -1
package/Changelog.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
# 0.4.6
|
|
2
|
+
|
|
3
|
+
* Fixed CodeceptJS reporter to report tests failed in hooks
|
|
4
|
+
|
|
5
|
+
# 0.4.5
|
|
6
|
+
|
|
7
|
+
* Fixed "Total XX artifacts publicly uploaded to S3 bucket" when no S3 bucket is configured
|
|
8
|
+
* Improved S3 connection error messages
|
|
9
|
+
|
|
10
|
+
# 0.4.4
|
|
11
|
+
|
|
12
|
+
* Fixed returning 0 exit code when a process fails when running tests in parallel via `start-test-run`. Previously was using the last exit code returned by a process. Currently prefers the highest exit code that was returned by a process.
|
|
13
|
+
|
|
14
|
+
# 0.4.3
|
|
15
|
+
|
|
16
|
+
* Added `TESTOMATIO_DISABLE_ARTIFACTS` env variable to disable publishing artifacts.
|
|
17
|
+
|
|
1
18
|
# 0.4.2
|
|
2
19
|
|
|
3
20
|
* print version of reporter
|
package/README.md
CHANGED
|
@@ -248,6 +248,12 @@ global.testomatioArtifacts.push({ name: 'Screenshot', path: 'img/file.png' });
|
|
|
248
248
|
|
|
249
249
|
Artifacts will be uploaded for the current test when it is finished.
|
|
250
250
|
|
|
251
|
+
To disable uploading artifacts add `TESTOMATIO_DISABLE_ARTIFACTS` environment variable:
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
TESTOMATIO_DISABLE_ARTIFACTS=1
|
|
255
|
+
```
|
|
256
|
+
|
|
251
257
|
|
|
252
258
|
## Starting an Empty Run
|
|
253
259
|
|
package/lib/adapter/codecept.js
CHANGED
|
@@ -7,9 +7,11 @@ const chalk = require("chalk");
|
|
|
7
7
|
const TestomatClient = require("../client");
|
|
8
8
|
const { FAILED } = require("../constants");
|
|
9
9
|
const TRConstants = require("../constants");
|
|
10
|
+
const upload = require("../fileUploader");
|
|
10
11
|
const Output = require("../output");
|
|
11
12
|
|
|
12
13
|
let currentMetaStep = [];
|
|
14
|
+
let error;
|
|
13
15
|
let stepShift = 0;
|
|
14
16
|
const output = new Output({
|
|
15
17
|
filterFn: (stack) => !stack.includes("codeceptjs/lib/output"), // output from codeceptjs
|
|
@@ -84,10 +86,11 @@ module.exports = (config) => {
|
|
|
84
86
|
|
|
85
87
|
event.dispatcher.on(event.test.started, (test) => {
|
|
86
88
|
testTimeMap[test.id] = Date.now();
|
|
89
|
+
err = null;
|
|
87
90
|
});
|
|
88
91
|
|
|
89
92
|
event.dispatcher.on(event.all.result, async () => {
|
|
90
|
-
if (videos.length) {
|
|
93
|
+
if (videos.length && upload.isEnabled()) {
|
|
91
94
|
console.log(TRConstants.APP_PREFIX, `🎞️ Uploading ${videos.length} videos...`);
|
|
92
95
|
|
|
93
96
|
let promises = [];
|
|
@@ -122,14 +125,19 @@ module.exports = (config) => {
|
|
|
122
125
|
output.stop();
|
|
123
126
|
});
|
|
124
127
|
|
|
128
|
+
event.dispatcher.on(event.test.failed, (test, err) => {
|
|
129
|
+
error = err;
|
|
130
|
+
});
|
|
131
|
+
|
|
125
132
|
event.dispatcher.on(event.test.after, (test) => {
|
|
126
133
|
if (test.state && test.state !== FAILED) return;
|
|
127
|
-
|
|
134
|
+
if (test.err) error = test.err;
|
|
135
|
+
const { id, tags, title, artifacts } = test;
|
|
128
136
|
failedTests.push(id || title);
|
|
129
137
|
const testId = parseTest(tags);
|
|
130
138
|
const testObj = getTestAndMessage(title);
|
|
131
|
-
if (
|
|
132
|
-
|
|
139
|
+
if (error && error.stack && test.steps && test.steps.length) {
|
|
140
|
+
error.stack = test.steps[test.steps.length - 1].line();
|
|
133
141
|
}
|
|
134
142
|
|
|
135
143
|
const files = [];
|
|
@@ -139,7 +147,7 @@ module.exports = (config) => {
|
|
|
139
147
|
|
|
140
148
|
client.addTestRun(testId, TRConstants.FAILED, {
|
|
141
149
|
...stripExampleFromTitle(title),
|
|
142
|
-
error
|
|
150
|
+
error,
|
|
143
151
|
message: testObj.message,
|
|
144
152
|
time: getDuration(test),
|
|
145
153
|
files,
|
|
@@ -5,6 +5,7 @@ const path = require('path');
|
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const Status = require('../constants');
|
|
7
7
|
const TestomatioClient = require("../client");
|
|
8
|
+
const upload = require("../fileUploader");
|
|
8
9
|
const { parseTest } = require('../util');
|
|
9
10
|
|
|
10
11
|
class TestomatioReporter {
|
|
@@ -75,7 +76,7 @@ class TestomatioReporter {
|
|
|
75
76
|
async onEnd(result) {
|
|
76
77
|
if (!this.client) return;
|
|
77
78
|
|
|
78
|
-
if (this.videos.length) {
|
|
79
|
+
if (this.videos.length && upload.isEnabled()) {
|
|
79
80
|
console.log(Status.APP_PREFIX, `🎞️ Uploading ${this.videos.length} videos...`);
|
|
80
81
|
|
|
81
82
|
let promises = [];
|
package/lib/bin/startTest.js
CHANGED
|
@@ -43,6 +43,8 @@ program
|
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
let exitCode = 0;
|
|
47
|
+
|
|
46
48
|
const testCmds = command.split(" ");
|
|
47
49
|
console.log(APP_PREFIX, `🚀 Running`, chalk.green(command));
|
|
48
50
|
|
|
@@ -55,7 +57,9 @@ program
|
|
|
55
57
|
"⚠️ ",
|
|
56
58
|
`Runner exited with ${chalk.bold(code)}, report is ignored`
|
|
57
59
|
);
|
|
58
|
-
|
|
60
|
+
|
|
61
|
+
if (code > exitCode) exitCode = code;
|
|
62
|
+
process.exitCode = exitCode;
|
|
59
63
|
});
|
|
60
64
|
|
|
61
65
|
return;
|
|
@@ -71,7 +75,9 @@ program
|
|
|
71
75
|
console.log(APP_PREFIX, emoji, `Runner exited with ${chalk.bold(code)}`);
|
|
72
76
|
const status = code === 0 ? "passed" : "failed";
|
|
73
77
|
client.updateRunStatus(status, true);
|
|
74
|
-
|
|
78
|
+
|
|
79
|
+
if (code > exitCode) exitCode = code;
|
|
80
|
+
process.exitCode = exitCode;
|
|
75
81
|
});
|
|
76
82
|
});
|
|
77
83
|
});
|
package/lib/client.js
CHANGED
|
@@ -5,7 +5,7 @@ const createCallsiteRecord = require("callsite-record");
|
|
|
5
5
|
const { sep, join } = require("path");
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
const chalk = require("chalk");
|
|
8
|
-
const
|
|
8
|
+
const upload = require("./fileUploader");
|
|
9
9
|
const { PASSED, FAILED, FINISHED, APP_PREFIX } = require("./constants");
|
|
10
10
|
|
|
11
11
|
const TESTOMAT_URL = process.env.TESTOMATIO_URL || "https://app.testomat.io";
|
|
@@ -125,6 +125,7 @@ class TestomatClient {
|
|
|
125
125
|
|
|
126
126
|
if (error) {
|
|
127
127
|
stack = this.formatError(error);
|
|
128
|
+
message = error.message;
|
|
128
129
|
}
|
|
129
130
|
if (steps) {
|
|
130
131
|
stack = this.formatSteps(stack, steps);
|
|
@@ -137,7 +138,7 @@ class TestomatClient {
|
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
for (const file of files) {
|
|
140
|
-
uploadedFiles.push(uploadFile(file, this.runId));
|
|
141
|
+
uploadedFiles.push(upload.uploadFile(file, this.runId));
|
|
141
142
|
}
|
|
142
143
|
}
|
|
143
144
|
|
|
@@ -233,11 +234,11 @@ class TestomatClient {
|
|
|
233
234
|
);
|
|
234
235
|
}
|
|
235
236
|
|
|
236
|
-
if (this.totalUploaded > 0) {
|
|
237
|
+
if (upload.isEnabled() && this.totalUploaded > 0) {
|
|
237
238
|
console.log(
|
|
238
239
|
APP_PREFIX,
|
|
239
240
|
`🗄️ Total ${this.totalUploaded} artifacts ${
|
|
240
|
-
isPrivate ? "privately" : chalk.bold("publicly")
|
|
241
|
+
upload.isPrivate ? "privately" : chalk.bold("publicly")
|
|
241
242
|
} uploaded to S3 bucket `
|
|
242
243
|
);
|
|
243
244
|
}
|
package/lib/fileUploader.js
CHANGED
|
@@ -2,14 +2,22 @@ const AWS = require("aws-sdk");
|
|
|
2
2
|
const fs = require("fs");
|
|
3
3
|
const path = require("path");
|
|
4
4
|
const chalk = require("chalk");
|
|
5
|
+
const { APP_PREFIX } = require("./constants");
|
|
5
6
|
|
|
6
7
|
const isPrivate = process.env.TESTOMATIO_PRIVATE_ARTIFACTS;
|
|
7
8
|
|
|
9
|
+
function isEnabled() {
|
|
10
|
+
return process.env.S3_BUCKET && !process.env.TESTOMATIO_DISABLE_ARTIFACTS;
|
|
11
|
+
}
|
|
12
|
+
|
|
8
13
|
const uploadUsingS3 = async (filePath, runId) => {
|
|
9
14
|
const region = process.env.S3_REGION;
|
|
10
15
|
const bucket = process.env.S3_BUCKET;
|
|
11
16
|
const accessKeyId = process.env.S3_ACCESS_KEY_ID;
|
|
12
17
|
const secretAccessKey = process.env.S3_SECRET_ACCESS_KEY;
|
|
18
|
+
const isDisabled = process.env.TESTOMATIO_DISABLE_ARTIFACTS;
|
|
19
|
+
|
|
20
|
+
if (isDisabled) return;
|
|
13
21
|
|
|
14
22
|
let contentType;
|
|
15
23
|
let fileName;
|
|
@@ -29,22 +37,43 @@ const uploadUsingS3 = async (filePath, runId) => {
|
|
|
29
37
|
const file = fs.readFileSync(filePath);
|
|
30
38
|
|
|
31
39
|
fileName = `${runId}/${fileName || path.basename(filePath)}`;
|
|
40
|
+
const acl = isPrivate ? "private" : "public-read"
|
|
32
41
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
try {
|
|
43
|
+
const out = await s3
|
|
44
|
+
.upload({
|
|
45
|
+
Bucket: bucket,
|
|
46
|
+
Key: fileName,
|
|
47
|
+
Body: file,
|
|
48
|
+
ContentType: contentType,
|
|
49
|
+
ACL: acl,
|
|
50
|
+
})
|
|
51
|
+
.promise();
|
|
52
|
+
return out.Location;
|
|
53
|
+
} catch (e) {
|
|
54
|
+
console.log(APP_PREFIX, chalk.bold.red(`Failed uploading '${fileName}'. Please check S3 credentials`), {
|
|
55
|
+
accessKeyId,
|
|
56
|
+
secretAccessKey: secretAccessKey ? '**** (hidden) ***' : '(empty)',
|
|
57
|
+
region,
|
|
58
|
+
bucket,
|
|
59
|
+
acl,
|
|
60
|
+
endpoint: process.env.S3_ENDPOINT
|
|
40
61
|
})
|
|
41
|
-
|
|
42
|
-
|
|
62
|
+
|
|
63
|
+
console.log(APP_PREFIX, `To ${chalk.bold('disable')} artifact uploads set: TESTOMATIO_DISABLE_ARTIFACTS=1`)
|
|
64
|
+
if (!isPrivate) {
|
|
65
|
+
console.log(APP_PREFIX, `To enable ${chalk.bold('PRIVATE')} uploads set: TESTOMATIO_PRIVATE_ARTIFACTS=1`)
|
|
66
|
+
} else {
|
|
67
|
+
console.log(APP_PREFIX, `To enable ${chalk.bold('PUBLIC')} uploads remove TESTOMATIO_PRIVATE_ARTIFACTS env variable`)
|
|
68
|
+
}
|
|
69
|
+
console.log(APP_PREFIX, '---------------')
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
43
72
|
};
|
|
44
73
|
|
|
45
74
|
const uploadFile = async (filePath, runId) => {
|
|
46
75
|
try {
|
|
47
|
-
if (
|
|
76
|
+
if (isEnabled()) {
|
|
48
77
|
return uploadUsingS3(filePath, runId);
|
|
49
78
|
}
|
|
50
79
|
} catch (e) {
|
|
@@ -56,4 +85,5 @@ const uploadFile = async (filePath, runId) => {
|
|
|
56
85
|
module.exports = {
|
|
57
86
|
uploadFile,
|
|
58
87
|
isPrivate,
|
|
88
|
+
isEnabled,
|
|
59
89
|
};
|