From 1c89452b0a2216e889c375f2258b7e908e6453d0 Mon Sep 17 00:00:00 2001 From: Andrey Lushnikov Date: Sat, 11 Apr 2026 15:00:49 +0300 Subject: [PATCH] feat: support step-level attachments --- package.json | 2 +- pnpm-lock.yaml | 13 +++++++++++-- src/normalizeReport.ts | 1 + src/readReport.ts | 36 +++++++++++++++++++++++------------- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 741d83f..47f8f73 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "node": "^20.17.0 || >=22.9.0" }, "devDependencies": { - "@flakiness/flakiness-report": "^0.28.0", + "@flakiness/flakiness-report": "^0.31.0", "@flakiness/playwright": "^1.3.3", "@playwright/test": "^1.58.2", "@types/debug": "^4.1.12", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3d22608..b59f96f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,8 +25,8 @@ importers: version: 4.3.5 devDependencies: '@flakiness/flakiness-report': - specifier: ^0.28.0 - version: 0.28.0(zod@4.3.5) + specifier: ^0.31.0 + version: 0.31.0(zod@4.3.5) '@flakiness/playwright': specifier: ^1.3.3 version: 1.3.3(zod@4.3.5) @@ -222,6 +222,11 @@ packages: peerDependencies: zod: ^4.1.12 + '@flakiness/flakiness-report@0.31.0': + resolution: {integrity: sha512-on2B5Hzf2v5jqcnK1aL6G52bU2AhIIOm+qq0kX9inLflDGm4FzRDAjFsdnv0QsmUtukvK89VLlpNndNZ6q7+Bw==} + peerDependencies: + zod: ^4.1.12 + '@flakiness/playwright@1.3.3': resolution: {integrity: sha512-UKdDkF+f5TSYewoJkT5CacWvzlJPUyF5KjKzpZyjOqIpljyMEmEZhzNT+o8jsyC5n6aCAMl9oXHShYciDf8OQA==} @@ -734,6 +739,10 @@ snapshots: dependencies: zod: 4.3.5 + '@flakiness/flakiness-report@0.31.0(zod@4.3.5)': + dependencies: + zod: 4.3.5 + '@flakiness/playwright@1.3.3(zod@4.3.5)': dependencies: '@flakiness/flakiness-report': 0.28.0(zod@4.3.5) diff --git a/src/normalizeReport.ts b/src/normalizeReport.ts index 86ce078..65fbd72 100644 --- a/src/normalizeReport.ts +++ b/src/normalizeReport.ts @@ -54,6 +54,7 @@ export function normalizeReport(report: FlakinessReport.Report): FlakinessReport return { ...step, duration: step.duration === 0 ? undefined : step.duration, + attachments: step.attachments && step.attachments.length ? step.attachments : undefined, steps: step.steps && step.steps.length ? step.steps.map(cleanupTestStep) : undefined, } } diff --git a/src/readReport.ts b/src/readReport.ts index 44dcf12..199e8de 100644 --- a/src/readReport.ts +++ b/src/readReport.ts @@ -69,21 +69,31 @@ export async function readReport(reportFolder: string): Promise<{ const filenameToPath = new Map(attachmentFiles.map(file => [path.basename(file), file])); const attachmentIdToPath = new Map(); const missingAttachments = new Map(); + const visitAttachment = (attachment: FlakinessReport.Attachment) => { + const attachmentPath = filenameToPath.get(attachment.id); + if (!attachmentPath) { + missingAttachments.set(attachment.id, attachment); + } else { + attachmentIdToPath.set(attachment.id, { + contentType: attachment.contentType, + id: attachment.id, + path: attachmentPath, + type: 'file', + }); + } + }; + const visitStep = (step: FlakinessReport.TestStep) => { + for (const attachment of step.attachments ?? []) + visitAttachment(attachment); + for (const childStep of step.steps ?? []) + visitStep(childStep); + }; visitTests(report, (test) => { for (const attempt of test.attempts) { - for (const attachment of attempt.attachments ?? []) { - const attachmentPath = filenameToPath.get(attachment.id); - if (!attachmentPath) { - missingAttachments.set(attachment.id, attachment); - } else { - attachmentIdToPath.set(attachment.id, { - contentType: attachment.contentType, - id: attachment.id, - path: attachmentPath, - type: 'file', - }); - } - } + for (const attachment of attempt.attachments ?? []) + visitAttachment(attachment); + for (const step of attempt.steps ?? []) + visitStep(step); } }); return {