diff --git a/packages/playwright-test/src/reporters/base.ts b/packages/playwright-test/src/reporters/base.ts index 3b3f3cc619..7f7be29ed4 100644 --- a/packages/playwright-test/src/reporters/base.ts +++ b/packages/playwright-test/src/reporters/base.ts @@ -285,7 +285,8 @@ export function formatFailure(config: FullConfig, test: TestCase, options: {inde let text = attachment.body.toString(); if (text.length > 300) text = text.slice(0, 300) + '...'; - resultLines.push(colors.cyan(` ${text}`)); + for (const line of text.split('\n')) + resultLines.push(colors.cyan(` ${line}`)); } } resultLines.push(colors.cyan(separator(' '))); diff --git a/tests/playwright-test/reporter-attachment.spec.ts b/tests/playwright-test/reporter-attachment.spec.ts index 48fc59aaa6..3b35ed1d36 100644 --- a/tests/playwright-test/reporter-attachment.spec.ts +++ b/tests/playwright-test/reporter-attachment.spec.ts @@ -278,3 +278,26 @@ test(`testInfo.attach throw if name is not string`, async ({ runInlineTest }) => expect(result.output).toContain('"name" should be string.'); }); + +test('render text attachment with multiple lines', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'a.test.js': ` + const { test } = pwt; + test('one', async ({}, testInfo) => { + testInfo.attachments.push({ + name: 'attachment', + body: Buffer.from('First line\\nSecond line\\nThird line'), + contentType: 'text/plain' + }); + expect(1).toBe(0); + }); + `, + }, { reporter: 'line' }); + const text = result.output; + expect(text).toContain(' attachment #1: attachment (text/plain) ─────────────────────────────────────────────────────────'); + expect(text).toContain(' First line'); + expect(text).toContain(' Second line'); + expect(text).toContain(' Third line'); + expect(text).toContain(' ────────────────────────────────────────────────────────────────────────────────────────────────'); + expect(result.exitCode).toBe(1); +});