Skip to content

Instantly share code, notes, and snippets.

@ryangoree
Last active January 22, 2025 18:20
Show Gist options
  • Select an option

  • Save ryangoree/f4c7021a130f288799f87c3444a3604a to your computer and use it in GitHub Desktop.

Select an option

Save ryangoree/f4c7021a130f288799f87c3444a3604a to your computer and use it in GitHub Desktop.
A node.js test reporter that formats results as CSV and uploads to S3.
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
const currentPath = [];
const csvRows = ["test_name,duration,passed,error,skipped,skip_message,logs"];
let pendingRow;
let diagnostics = [];
/**
* A test reporter that formats results as CSV and uploads to S3.
* @see https://nodejs.org/api/test.html#custom-reporters
*/
export default async function s3Reporter(source) {
for await (const event of source) {
switch (event.type) {
case "test:start":
currentPath.push(event.data.name);
break;
case "test:pass":
case "test:fail":
// Add the collected diagnostics to the previous test and reset.
if (event.data.details.type !== "suite") {
if (pendingRow) {
pendingRow.push(`"${diagnostics.join("\n")}"`);
diagnostics = [];
csvRows.push(pendingRow.join(","));
}
pendingRow = [
// test_name
`"${currentPath.join(" / ")}"`,
// duration
event.data.details.duration_ms,
// passed
event.type === "test:pass",
// error
event.data.details.error ? `"${event.data.details.error}"` : "",
// skipped
!!event.data.skip,
// skip_message
typeof event.data.skip === "string" ? `"${event.data.skip}"` : "",
];
}
currentPath.pop();
break;
case "test:diagnostic":
if (event.data.file) {
diagnostics.push(event.data.message.trim().replace(/"/g, '""'));
}
break;
}
}
if (pendingRow) {
pendingRow.push(`"${diagnostics.join("\n")}"`);
csvRows.push(pendingRow.join(","));
}
const bucket = process.env.S3_TEST_ARCHIVE_BUCKET;
if (!bucket) {
console.error(
"Missing S3_TEST_ARCHIVE_BUCKET environment variable. Upload skipped.",
);
return;
}
const fileName = `test-results-${new Date().toISOString()}.csv`;
const csv = csvRows.join("\n");
const s3 = new S3Client({
region: process.env.S3_TEST_ARCHIVE_BUCKET_REGION,
});
await s3.send(
new PutObjectCommand({
Bucket: bucket,
Key: fileName,
Body: csv,
}),
);
console.log(`Test results archived to s3://${bucket}/${fileName}`);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment