Skip to content

Commit

Permalink
reporter-attachments: dont mutate messages
Browse files Browse the repository at this point in the history
  • Loading branch information
vitalets committed Oct 2, 2024
1 parent 0cc9d7b commit 990a21e
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 24 deletions.
21 changes: 10 additions & 11 deletions src/reporter/cucumber/attachments/external.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,25 @@ import path from 'node:path';
import mime from 'mime-types';
import { calculateSha1 } from '../../../utils';
import { sanitizeForFilePath } from '../../../utils/paths';
import { getAttachmentBodyAsBuffer } from './helpers';

export function toEmbeddedAttachment(attachment: messages.Attachment) {
export function toEmbeddedAttachment(attachment: messages.Attachment): messages.Attachment {
if (attachment.body) return attachment;

const attachmentPath = attachment.url;
if (!attachmentPath) throw new Error('Attachment without body and url');

// add cache for file reading

attachment.body = fs.readFileSync(attachmentPath).toString('base64');
attachment.contentEncoding = messages.AttachmentContentEncoding.BASE64;
delete attachment.url;
const body = fs.readFileSync(attachmentPath).toString('base64');
const contentEncoding = messages.AttachmentContentEncoding.BASE64;

return attachment;
return {
...attachment,
body,
contentEncoding,
url: undefined,
};
}

/**
Expand Down Expand Up @@ -52,12 +57,6 @@ export function toExternalAttachment(
};
}

function getAttachmentBodyAsBuffer(attachment: messages.Attachment) {
const encoding =
attachment.contentEncoding === messages.AttachmentContentEncoding.BASE64 ? 'base64' : 'utf-8';
return Buffer.from(attachment.body, encoding);
}

/**
* Returns extension for the attachment (without dot).
*/
Expand Down
12 changes: 12 additions & 0 deletions src/reporter/cucumber/attachments/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,15 @@ import { AttachmentEnvelope } from '../messagesBuilder/types';
export function isAttachmentEnvelope(envelope: messages.Envelope): envelope is AttachmentEnvelope {
return Boolean(envelope.attachment);
}

export function getAttachmentBodyAsBuffer(attachment: messages.Attachment) {
const encoding =
attachment.contentEncoding === messages.AttachmentContentEncoding.BASE64 ? 'base64' : 'utf-8';
return Buffer.from(attachment.body, encoding);
}

export function getAttachmentBodyAsBase64(attachment: messages.Attachment) {
return attachment.contentEncoding === messages.AttachmentContentEncoding.BASE64
? attachment.body
: Buffer.from(attachment.body).toString('base64');
}
15 changes: 10 additions & 5 deletions src/reporter/cucumber/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,17 @@ export default class HtmlReporter extends BaseReporter {
// See: https://github.com/cucumber/cucumber-js/issues/2430
// See: https://github.com/cucumber/react-components/blob/main/src/components/gherkin/attachment/Attachment.tsx#L32

envelope.attachment =
this.userOptions.externalAttachments && !isTextAttachment(envelope.attachment)
? toExternalAttachment(envelope.attachment, this.attachmentsDir, this.attachmentsBaseURL)
: toEmbeddedAttachment(envelope.attachment);
const useExternalAttachment =
this.userOptions.externalAttachments && !isTextAttachment(envelope.attachment);

this.writeEnvelope(envelope);
const newAttachment = useExternalAttachment
? toExternalAttachment(envelope.attachment, this.attachmentsDir, this.attachmentsBaseURL)
: toEmbeddedAttachment(envelope.attachment);

this.writeEnvelope({
...envelope,
attachment: newAttachment,
});
}

protected writeEnvelope(envelope: messages.Envelope) {
Expand Down
10 changes: 4 additions & 6 deletions src/reporter/cucumber/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { GherkinDocumentMessage } from './messagesBuilder/GherkinDocument';
import { getFeatureNameWithProject } from './messagesBuilder/Projects';
import { shouldSkipAttachment, SkipAttachments } from './attachments/skip';
import { toEmbeddedAttachment } from './attachments/external';
import { getAttachmentBodyAsBase64 } from './attachments/helpers';

const {
getGherkinExampleRuleMap,
Expand Down Expand Up @@ -338,12 +339,9 @@ export default class JsonReporter extends BaseReporter {
const allowedAttachments = this.getAllowedAttachments(testStepAttachments);
if (allowedAttachments && allowedAttachments.length > 0) {
data.embeddings = allowedAttachments.map((attachment) => {
attachment = toEmbeddedAttachment(attachment);
const data =
attachment.contentEncoding === messages.AttachmentContentEncoding.IDENTITY
? Buffer.from(attachment.body).toString('base64')
: attachment.body;
const mime_type = attachment.mediaType;
const embeddedAttachment = toEmbeddedAttachment(attachment);
const data = getAttachmentBodyAsBase64(embeddedAttachment);
const mime_type = embeddedAttachment.mediaType;
return { data, mime_type };
});
}
Expand Down
7 changes: 5 additions & 2 deletions src/reporter/cucumber/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ export default class MessageReporter extends BaseReporter {

protected handleAttachment(envelope: AttachmentEnvelope) {
if (shouldSkipAttachment(envelope, this.userOptions.skipAttachments)) return;
envelope.attachment = toEmbeddedAttachment(envelope.attachment);
this.writeEnvelope(envelope);

this.writeEnvelope({
...envelope,
attachment: toEmbeddedAttachment(envelope.attachment),
});
}

protected writeEnvelope(envelope: messages.Envelope) {
Expand Down

0 comments on commit 990a21e

Please sign in to comment.