diff --git a/packages/playwright-test/src/reporters/base.ts b/packages/playwright-test/src/reporters/base.ts index 8ba830a975..cdfda403e9 100644 --- a/packages/playwright-test/src/reporters/base.ts +++ b/packages/playwright-test/src/reporters/base.ts @@ -258,8 +258,8 @@ export function formatFailure(config: FullConfig, test: TestCase, options: {inde resultLines.push(''); } } else { - if (attachment.contentType.startsWith('text/')) { - let text = attachment.body!.toString(); + if (attachment.contentType.startsWith('text/') && attachment.body) { + let text = attachment.body.toString(); if (text.length > 300) text = text.slice(0, 300) + '...'; resultLines.push(colors.cyan(` ${text}`)); diff --git a/tests/playwright-test/reporter-base.spec.ts b/tests/playwright-test/reporter-base.spec.ts index 531ab5eefc..834f327003 100644 --- a/tests/playwright-test/reporter-base.spec.ts +++ b/tests/playwright-test/reporter-base.spec.ts @@ -270,3 +270,22 @@ test('should print "no tests found" error', async ({ runInlineTest }) => { expect(result.exitCode).toBe(1); expect(result.output).toContain('no tests found.'); }); + +test('should not crash on undefined body with manual attachments', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'a.test.js': ` + const { test } = pwt; + test('one', async ({}, testInfo) => { + testInfo.attachments.push({ + name: 'foo.txt', + body: undefined, + contentType: 'text/plain' + }); + expect(1).toBe(2); + }); + `, + }); + expect(stripAnsi(result.output)).not.toContain('Error in reporter'); + expect(result.failed).toBe(1); + expect(result.exitCode).toBe(1); +});