diff --git a/packages/html-reporter/src/testCaseView.tsx b/packages/html-reporter/src/testCaseView.tsx
index 089f15a49c..08f1523dc6 100644
--- a/packages/html-reporter/src/testCaseView.tsx
+++ b/packages/html-reporter/src/testCaseView.tsx
@@ -14,7 +14,7 @@
limitations under the License.
*/
-import type { TestCase } from './types';
+import type { TestCase, TestCaseAnnotation } from './types';
import * as React from 'react';
import { TabbedPane } from './tabbedPane';
import { AutoChip } from './chip';
@@ -38,10 +38,7 @@ export const TestCaseView: React.FC<{
{test &&
{test.location.file}:{test.location.line}
}
{test && !!test.projectName && }
{test && !!test.annotations.length &&
- {test.annotations.map(a =>
- {a.type}
- {a.description && : {a.description}}
-
)}
+ {test.annotations.map(annotation => )}
}
{test && ({
@@ -52,6 +49,23 @@ export const TestCaseView: React.FC<{
;
};
+function renderAnnotationDescription(description: string) {
+ try {
+ if (['http:', 'https:'].includes(new URL(description).protocol))
+ return {description};
+ } catch {}
+ return description;
+}
+
+function TestCaseAnnotationView({ annotation: { type, description } }: { annotation: TestCaseAnnotation }) {
+ return (
+
+ {type}
+ {description && : {renderAnnotationDescription(description)}}
+
+ );
+}
+
function retryLabel(index: number) {
if (!index)
return 'Run';
diff --git a/packages/html-reporter/src/types.ts b/packages/html-reporter/src/types.ts
index 5ecbb00086..d7bd68e412 100644
--- a/packages/html-reporter/src/types.ts
+++ b/packages/html-reporter/src/types.ts
@@ -52,13 +52,15 @@ export type TestFileSummary = {
stats: Stats;
};
+export type TestCaseAnnotation = { type: string, description?: string };
+
export type TestCaseSummary = {
testId: string,
title: string;
path: string[];
projectName: string;
location: Location;
- annotations: { type: string, description?: string }[];
+ annotations: TestCaseAnnotation[];
outcome: 'skipped' | 'expected' | 'unexpected' | 'flaky';
duration: number;
ok: boolean;
diff --git a/tests/playwright-test/reporter-html.spec.ts b/tests/playwright-test/reporter-html.spec.ts
index 8b40898398..bf63c86d71 100644
--- a/tests/playwright-test/reporter-html.spec.ts
+++ b/tests/playwright-test/reporter-html.spec.ts
@@ -577,6 +577,30 @@ test('should render annotations', async ({ runInlineTest, page, showReport }) =>
await expect(page.locator('.test-case-annotation')).toHaveText('skip: I am not interested in this test');
});
+test('should render annotations as link if needed', async ({ runInlineTest, page, showReport, server }) => {
+ const result = await runInlineTest({
+ 'playwright.config.js': `
+ module.exports = { timeout: 1500 };
+ `,
+ 'a.test.js': `
+ import { test, expect } from '@playwright/test';
+ test('pass test', async ({ page }) => {
+ test.info().annotations.push({ type: 'issue', description: '${server.EMPTY_PAGE}' });
+ });
+ `,
+ }, { reporter: 'dot,html' }, { PW_TEST_HTML_REPORT_OPEN: 'never' });
+ expect(result.exitCode).toBe(0);
+ expect(result.passed).toBe(1);
+
+ await showReport();
+ await page.getByText('pass test').click();
+ await expect(page.locator('.test-case-annotation')).toHaveText(`issue: ${server.EMPTY_PAGE}`);
+ const popupPromise = page.waitForEvent('popup');
+ await page.getByRole('link', { name: server.EMPTY_PAGE }).click();
+ const popup = await popupPromise;
+ expect(popup.url()).toBe(server.EMPTY_PAGE);
+});
+
test('should render text attachments as text', async ({ runInlineTest, page, showReport }) => {
const result = await runInlineTest({
'a.test.js': `