diff --git a/packages/playwright-core/src/web/htmlReport/htmlReport.tsx b/packages/playwright-core/src/web/htmlReport/htmlReport.tsx
index f805368587..30db558b38 100644
--- a/packages/playwright-core/src/web/htmlReport/htmlReport.tsx
+++ b/packages/playwright-core/src/web/htmlReport/htmlReport.tsx
@@ -255,7 +255,7 @@ export const AttachmentLink: React.FunctionComponent<{
{attachment.path && {attachment.name}}
{attachment.body && {attachment.name}}
} loadChildren={attachment.body ? () => {
- return [
${attachment.body}
];
+ return [{attachment.body}
];
} : undefined} depth={0}>;
};
diff --git a/packages/playwright-test/src/reporters/html.ts b/packages/playwright-test/src/reporters/html.ts
index bb27f04e71..c3506ecc1b 100644
--- a/packages/playwright-test/src/reporters/html.ts
+++ b/packages/playwright-test/src/reporters/html.ts
@@ -233,7 +233,7 @@ class HtmlBuilder {
testId: test.testId,
title: test.title,
location: this._relativeLocation(test.location),
- results: test.results.map(r => this._createTestResult(test, r))
+ results: test.results.map(r => this._createTestResult(r))
};
}
@@ -278,7 +278,8 @@ class HtmlBuilder {
};
}
- private _createTestResult(test: JsonTestCase, result: JsonTestResult): TestResult {
+ private _createTestResult(result: JsonTestResult): TestResult {
+ let lastAttachment: TestAttachment | undefined;
return {
duration: result.duration,
startTime: result.startTime,
@@ -303,8 +304,18 @@ class HtmlBuilder {
body: a.body,
};
}
+
+ if ((a.name === 'stdout' || a.name === 'stderr') &&
+ a.contentType === 'text/plain' &&
+ lastAttachment &&
+ lastAttachment.name === a.name &&
+ lastAttachment.contentType === a.contentType) {
+ lastAttachment.body += a.body as string;
+ return null;
+ }
+ lastAttachment = a;
return a;
- })
+ }).filter(Boolean) as TestAttachment[]
};
}
diff --git a/tests/playwright-test/reporter-html.spec.ts b/tests/playwright-test/reporter-html.spec.ts
index 687d9317a6..9ecfaa123c 100644
--- a/tests/playwright-test/reporter-html.spec.ts
+++ b/tests/playwright-test/reporter-html.spec.ts
@@ -228,3 +228,27 @@ test('should include screenshot on failure', async ({ runInlineTest, page, showR
const src = await page.locator('img').getAttribute('src');
expect(src).toBeTruthy();
});
+
+test('should include stdio', async ({ runInlineTest, page, showReport }) => {
+ const result = await runInlineTest({
+ 'a.test.js': `
+ const { test } = pwt;
+ test('fails', async ({ page }) => {
+ console.log('First line');
+ console.log('Second line');
+ console.error('Third line');
+ await expect(true).toBeFalsy();
+ });
+ `,
+ }, { reporter: 'dot,html' });
+ expect(result.exitCode).toBe(1);
+ expect(result.failed).toBe(1);
+
+ await showReport();
+ await page.click('text=a.test.js');
+ await page.click('text=fails');
+ await page.locator('text=stdout').click();
+ await expect(page.locator('.attachment-body')).toHaveText('First line\nSecond line');
+ await page.locator('text=stderr').click();
+ await expect(page.locator('.attachment-body').nth(1)).toHaveText('Third line');
+});