Skip to content

Commit bf47a98

Browse files
authored
chore: compress attachments (#257)
* chore: compress attachments * chore: bump version
1 parent 0f46f6d commit bf47a98

File tree

5 files changed

+53
-7
lines changed

5 files changed

+53
-7
lines changed

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "testbeats",
3-
"version": "2.1.5",
3+
"version": "2.1.6",
44
"description": "Publish test results to Microsoft Teams, Google Chat, Slack and InfluxDB",
55
"main": "src/index.js",
66
"types": "./src/index.d.ts",

src/beats/beats.attachments.js

+44-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
const fs = require('fs');
22
const path = require('path');
3+
const zlib = require('zlib');
4+
const stream = require('stream');
35
const FormData = require('form-data-lite');
6+
const ml = require('mime-lite')
47
const TestResult = require('test-results-parser/src/models/TestResult');
58
const { BeatsApi } = require('./beats.api');
69
const logger = require('../utils/logger');
@@ -23,12 +26,14 @@ class BeatsAttachments {
2326
this.test_run_id = test_run_id;
2427
this.failed_test_cases = [];
2528
this.attachments = [];
29+
this.compressed_attachment_paths = [];
2630
}
2731

2832
async upload() {
2933
this.#setAllFailedTestCases();
3034
this.#setAttachments();
3135
await this.#uploadAttachments();
36+
this.#deleteCompressedAttachments();
3237
}
3338

3439
#setAllFailedTestCases() {
@@ -67,17 +72,22 @@ class BeatsAttachments {
6772
form.append('test_run_id', this.test_run_id);
6873
const file_images = []
6974
for (const attachment of attachments_subset) {
70-
const attachment_path = this.#getAttachmentFilePath(attachment);
75+
let attachment_path = this.#getAttachmentFilePath(attachment);
7176
if (!attachment_path) {
7277
logger.warn(`⚠️ Unable to find attachment ${attachment.path}`);
7378
continue;
7479
}
80+
attachment_path = await this.#compressAttachment(attachment_path);
7581
const stats = fs.statSync(attachment_path);
7682
if (stats.size > MAX_ATTACHMENT_SIZE) {
7783
logger.warn(`⚠️ Attachment ${attachment.path} is too big (${stats.size} bytes). Allowed size is ${MAX_ATTACHMENT_SIZE} bytes.`);
7884
continue;
7985
}
80-
form.append('images', fs.readFileSync(attachment_path), { filename: path.basename(attachment_path), filepath: attachment_path });
86+
form.append('images', fs.readFileSync(attachment_path), {
87+
filename: path.basename(attachment_path),
88+
filepath: attachment_path,
89+
contentType: ml.getType(attachment.path),
90+
});
8191
file_images.push({
8292
file_name: attachment.name,
8393
file_path: attachment.path,
@@ -123,7 +133,39 @@ class BeatsAttachments {
123133
return null;
124134
}
125135

136+
/**
137+
*
138+
* @param {string} attachment_path
139+
*/
140+
#compressAttachment(attachment_path) {
141+
return new Promise((resolve, _) => {
142+
console.log(attachment_path)
143+
if (attachment_path.endsWith('.br') || attachment_path.endsWith('.gz') || attachment_path.endsWith('.zst') || attachment_path.endsWith('.zip') || attachment_path.endsWith('.7z') || attachment_path.endsWith('.png') || attachment_path.endsWith('.jpg') || attachment_path.endsWith('.jpeg') || attachment_path.endsWith('.svg') || attachment_path.endsWith('.gif') || attachment_path.endsWith('.webp')) {
144+
resolve(attachment_path);
145+
return;
146+
}
147+
const read_stream = fs.createReadStream(attachment_path);
148+
const br = zlib.createBrotliCompress();
126149

150+
const compressed_file_path = attachment_path + '.br';
151+
const write_stream = fs.createWriteStream(compressed_file_path);
152+
stream.pipeline(read_stream, br, write_stream, (err) => {
153+
if (err) {
154+
resolve(attachment_path);
155+
return;
156+
}
157+
this.compressed_attachment_paths.push(compressed_file_path);
158+
resolve(compressed_file_path);
159+
return;
160+
});
161+
});
162+
}
163+
164+
#deleteCompressedAttachments() {
165+
for (const attachment_path of this.compressed_attachment_paths) {
166+
fs.unlinkSync(attachment_path);
167+
}
168+
}
127169

128170
}
129171

test/beats.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ describe('TestBeats', () => {
7878
assert.equal(mock.getInteraction(id4).exercised, true);
7979
});
8080

81-
it('should send results with attachments to beats', async () => {
81+
it('should send results with image attachments to beats', async () => {
8282
const id1 = mock.addInteraction('post test results to beats');
8383
const id2 = mock.addInteraction('get test results from beats');
8484
const id3 = mock.addInteraction('upload attachments');
@@ -114,7 +114,7 @@ describe('TestBeats', () => {
114114
assert.equal(mock.getInteraction(id5).exercised, true);
115115
});
116116

117-
it('should send results with attachments from cucumber to beats', async () => {
117+
it('should send results with file attachments from cucumber to beats', async () => {
118118
const id1 = mock.addInteraction('post test results to beats');
119119
const id2 = mock.addInteraction('get test results from beats');
120120
const id3 = mock.addInteraction('upload attachments');

test/data/cucumber/failed-tests-with-attachments.json

+4
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@
9191
{
9292
"data": "eyJyZXEiOnsidXJsIjoiaHR0cHM6Ly9yZXFyZXMuaW4vYXBpL3VzZXJzIiwibWV0aG9kIjoiR0VUIn0sInJlcyI6eyJzdGF0dXMiOjIwMCwiYm9keSI6eyJwYWdlIjoxLCJwZXJfcGFnZSI6NiwidG90YWwiOjEyLCJ0b3RhbF9wYWdlcyI6MiwiZGF0YSI6W3siaWQiOjEsImVtYWlsIjoiZ2VvcmdlLmJsdXRoQHJlcXJlcy5pbiIsImZpcnN0X25hbWUiOiJHZW9yZ2UiLCJsYXN0X25hbWUiOiJCbHV0aCIsImF2YXRhciI6Imh0dHBzOi8vcmVxcmVzLmluL2ltZy9mYWNlcy8xLWltYWdlLmpwZyJ9LHsiaWQiOjIsImVtYWlsIjoiamFuZXQud2VhdmVyQHJlcXJlcy5pbiIsImZpcnN0X25hbWUiOiJKYW5ldCIsImxhc3RfbmFtZSI6IldlYXZlciIsImF2YXRhciI6Imh0dHBzOi8vcmVxcmVzLmluL2ltZy9mYWNlcy8yLWltYWdlLmpwZyJ9LHsiaWQiOjMsImVtYWlsIjoiZW1tYS53b25nQHJlcXJlcy5pbiIsImZpcnN0X25hbWUiOiJFbW1hIiwibGFzdF9uYW1lIjoiV29uZyIsImF2YXRhciI6Imh0dHBzOi8vcmVxcmVzLmluL2ltZy9mYWNlcy8zLWltYWdlLmpwZyJ9LHsiaWQiOjQsImVtYWlsIjoiZXZlLmhvbHRAcmVxcmVzLmluIiwiZmlyc3RfbmFtZSI6IkV2ZSIsImxhc3RfbmFtZSI6IkhvbHQiLCJhdmF0YXIiOiJodHRwczovL3JlcXJlcy5pbi9pbWcvZmFjZXMvNC1pbWFnZS5qcGcifSx7ImlkIjo1LCJlbWFpbCI6ImNoYXJsZXMubW9ycmlzQHJlcXJlcy5pbiIsImZpcnN0X25hbWUiOiJDaGFybGVzIiwibGFzdF9uYW1lIjoiTW9ycmlzIiwiYXZhdGFyIjoiaHR0cHM6Ly9yZXFyZXMuaW4vaW1nL2ZhY2VzLzUtaW1hZ2UuanBnIn0seyJpZCI6NiwiZW1haWwiOiJ0cmFjZXkucmFtb3NAcmVxcmVzLmluIiwiZmlyc3RfbmFtZSI6IlRyYWNleSIsImxhc3RfbmFtZSI6IlJhbW9zIiwiYXZhdGFyIjoiaHR0cHM6Ly9yZXFyZXMuaW4vaW1nL2ZhY2VzLzYtaW1hZ2UuanBnIn1dLCJzdXBwb3J0Ijp7InVybCI6Imh0dHBzOi8vcmVxcmVzLmluLyNzdXBwb3J0LWhlYWRpbmciLCJ0ZXh0IjoiVG8ga2VlcCBSZXFSZXMgZnJlZSwgY29udHJpYnV0aW9ucyB0b3dhcmRzIHNlcnZlciBjb3N0cyBhcmUgYXBwcmVjaWF0ZWQhIn19LCJoZWFkZXJzIjp7ImRhdGUiOiJTdW4sIDAxIFNlcCAyMDI0IDEzOjA2OjI4IEdNVCIsImNvbnRlbnQtdHlwZSI6ImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9dXRmLTgiLCJjb250ZW50LWxlbmd0aCI6Ijk5NiIsImNvbm5lY3Rpb24iOiJrZWVwLWFsaXZlIiwicmVwb3J0LXRvIjoie1wiZ3JvdXBcIjpcImhlcm9rdS1uZWxcIixcIm1heF9hZ2VcIjozNjAwLFwiZW5kcG9pbnRzXCI6W3tcInVybFwiOlwiaHR0cHM6Ly9uZWwuaGVyb2t1LmNvbS9yZXBvcnRzP3RzPTE3MjQ2ODA2NDImc2lkPWM0Yzk3MjVmLTFhYjAtNDRkOC04MjBmLTQzMGRmMjcxOGUxMSZzPWJIR2RiVXoxc3ZkUUtqaFFHeHpRc2FqZElET0FlR2xGNFlJTUJlQno4JTJGRSUzRFwifV19IiwicmVwb3J0aW5nLWVuZHBvaW50cyI6Imhlcm9rdS1uZWw9aHR0cHM6Ly9uZWwuaGVyb2t1LmNvbS9yZXBvcnRzP3RzPTE3MjQ2ODA2NDImc2lkPWM0Yzk3MjVmLTFhYjAtNDRkOC04MjBmLTQzMGRmMjcxOGUxMSZzPWJIR2RiVXoxc3ZkUUtqaFFHeHpRc2FqZElET0FlR2xGNFlJTUJlQno4JTJGRSUzRCIsIm5lbCI6IntcInJlcG9ydF90b1wiOlwiaGVyb2t1LW5lbFwiLFwibWF4X2FnZVwiOjM2MDAsXCJzdWNjZXNzX2ZyYWN0aW9uXCI6MC4wMDUsXCJmYWlsdXJlX2ZyYWN0aW9uXCI6MC4wNSxcInJlc3BvbnNlX2hlYWRlcnNcIjpbXCJWaWFcIl19IiwieC1wb3dlcmVkLWJ5IjoiRXhwcmVzcyIsImFjY2Vzcy1jb250cm9sLWFsbG93LW9yaWdpbiI6IioiLCJldGFnIjoiVy9cIjNlNC0yUkxYdnI1d1RnOVlRNmFIOTVDa1lvRk51TzhcIiIsInZpYSI6IjEuMSB2ZWd1ciIsImNhY2hlLWNvbnRyb2wiOiJtYXgtYWdlPTE0NDAwIiwiY2YtY2FjaGUtc3RhdHVzIjoiSElUIiwiYWdlIjoiNTAxIiwiYWNjZXB0LXJhbmdlcyI6ImJ5dGVzIiwic2VydmVyIjoiY2xvdWRmbGFyZSIsImNmLXJheSI6IjhiYzU3YTUwOGQ4ZDJlODUtSFlEIn19fQ==",
9393
"mime_type": "application/json"
94+
},
95+
{
96+
"data": "dGVzdC9kYXRhL2N1Y3VtYmVyL2ZhaWxlZC10ZXN0cy13aXRoLWF0dGFjaG1lbnRzLmpzb24=",
97+
"mime_type": "application/json"
9498
}
9599
]
96100
}

0 commit comments

Comments
 (0)