From 68c6defbc312da0357d9c568c8410a0d8185f308 Mon Sep 17 00:00:00 2001 From: osohyun0224 <53892427+osohyun0224@users.noreply.github.com> Date: Sun, 9 Jun 2024 16:56:48 +0900 Subject: [PATCH] feat(html-report): add url fields for rendered. --- docs/src/test-annotations-js.md | 3 ++- packages/html-reporter/src/filter.ts | 5 ++++- packages/playwright/src/common/ipc.ts | 2 +- packages/playwright/src/common/testType.ts | 5 +++-- packages/playwright/src/isomorphic/teleReceiver.ts | 4 ++-- packages/playwright/src/reporters/html.ts | 12 ++++++++++-- packages/playwright/src/reporters/versions/blobV1.ts | 2 +- packages/playwright/src/worker/testInfo.ts | 10 +++++----- packages/playwright/types/test.d.ts | 6 ++++++ packages/playwright/types/testReporter.d.ts | 7 ++++++- tests/playwright-test/reporter-html.spec.ts | 5 ++--- utils/generate_types/overrides-test.d.ts | 1 + utils/generate_types/overrides-testReporter.d.ts | 2 +- 13 files changed, 44 insertions(+), 20 deletions(-) diff --git a/docs/src/test-annotations-js.md b/docs/src/test-annotations-js.md index 68bdd79848..6b6d5f0d9e 100644 --- a/docs/src/test-annotations-js.md +++ b/docs/src/test-annotations-js.md @@ -182,7 +182,7 @@ You can also annotate all tests in a group or provide multiple annotations: import { test, expect } from '@playwright/test'; test.describe('report tests', { - annotation: { type: 'category', description: 'report' }, + annotation: { type: 'category', description: 'report', url: 'https://github.com/microsoft/playwright/issues/23180'}, }, () => { test('test report header', async ({ page }) => { // ... @@ -192,6 +192,7 @@ test.describe('report tests', { annotation: [ { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/23180' }, { type: 'performance', description: 'very slow test!' }, + { type: 'performance', description: 'very slow test!', url: 'https://github.com/microsoft/playwright/issues/23180'}, ], }, async ({ page }) => { // ... diff --git a/packages/html-reporter/src/filter.ts b/packages/html-reporter/src/filter.ts index 9ec4ea7e59..effea7b9b1 100644 --- a/packages/html-reporter/src/filter.ts +++ b/packages/html-reporter/src/filter.ts @@ -176,7 +176,10 @@ function cacheSearchValues(test: TestCaseSummary): SearchValues { line: String(test.location.line), column: String(test.location.column), labels: test.tags.map(tag => tag.toLowerCase()), - annotations: test.annotations.map(a => a.type.toLowerCase() + '=' + a.description?.toLocaleLowerCase()) + annotations: test.annotations.map(a => { + const value = a.description?.toLocaleLowerCase() || a.url?.toLocaleLowerCase() || ''; + return a.type.toLowerCase() + '=' + value; + }), }; (test as any)[searchValuesSymbol] = searchValues; return searchValues; diff --git a/packages/playwright/src/common/ipc.ts b/packages/playwright/src/common/ipc.ts index f5e3ec0858..437909569e 100644 --- a/packages/playwright/src/common/ipc.ts +++ b/packages/playwright/src/common/ipc.ts @@ -80,7 +80,7 @@ export type TestEndPayload = { errors: TestInfoError[]; hasNonRetriableError: boolean; expectedStatus: TestStatus; - annotations: { type: string, description?: string }[]; + annotations: { type: string, description?: string, url?: string }[]; timeout: number; }; diff --git a/packages/playwright/src/common/testType.ts b/packages/playwright/src/common/testType.ts index 5c7850a3df..4f1443f431 100644 --- a/packages/playwright/src/common/testType.ts +++ b/packages/playwright/src/common/testType.ts @@ -221,12 +221,13 @@ export class TestTypeImpl { } if (typeof modifierArgs[0] === 'function') { - suite._modifiers.push({ type, fn: modifierArgs[0], location, description: modifierArgs[1] }); + suite._modifiers.push({ type, fn: modifierArgs[0], location, description: modifierArgs[1], url: modifierArgs[1] }); } else { if (modifierArgs.length >= 1 && !modifierArgs[0]) return; const description = modifierArgs[1]; - suite._staticAnnotations.push({ type, description }); + const url = modifierArgs[1]; + suite._staticAnnotations.push({ type, description, url }); } return; } diff --git a/packages/playwright/src/isomorphic/teleReceiver.ts b/packages/playwright/src/isomorphic/teleReceiver.ts index da377b099f..fa308b3405 100644 --- a/packages/playwright/src/isomorphic/teleReceiver.ts +++ b/packages/playwright/src/isomorphic/teleReceiver.ts @@ -69,14 +69,14 @@ export type JsonTestCase = { retries: number; tags?: string[]; repeatEachIndex: number; - annotations?: { type: string, description?: string }[]; + annotations?: { type: string, description?: string, url?: string }[]; }; export type JsonTestEnd = { testId: string; expectedStatus: reporterTypes.TestStatus; timeout: number; - annotations: { type: string, description?: string }[]; + annotations: { type: string, description?: string, url?: string }[]; }; export type JsonTestResultStart = { diff --git a/packages/playwright/src/reporters/html.ts b/packages/playwright/src/reporters/html.ts index 2a5bbc94d4..d17977cc89 100644 --- a/packages/playwright/src/reporters/html.ts +++ b/packages/playwright/src/reporters/html.ts @@ -380,7 +380,11 @@ class HtmlBuilder { location, duration, // Annotations can be pushed directly, with a wrong type. - annotations: test.annotations.map(a => ({ type: a.type, description: a.description ? String(a.description) : a.description })), + annotations: test.annotations.map(a => ({ + type: a.type, + description: a.description ? String(a.description) : a.description, + url: a.url ? String(a.url) : a.url + })), tags: test.tags, outcome: test.outcome(), path, @@ -394,7 +398,11 @@ class HtmlBuilder { location, duration, // Annotations can be pushed directly, with a wrong type. - annotations: test.annotations.map(a => ({ type: a.type, description: a.description ? String(a.description) : a.description })), + annotations: test.annotations.map(a => ({ + type: a.type, + description: a.description ? String(a.description) : a.description, + url: a.url ? String(a.url) : a.url + })), tags: test.tags, outcome: test.outcome(), path, diff --git a/packages/playwright/src/reporters/versions/blobV1.ts b/packages/playwright/src/reporters/versions/blobV1.ts index 5ea9350285..4bc3591f5f 100644 --- a/packages/playwright/src/reporters/versions/blobV1.ts +++ b/packages/playwright/src/reporters/versions/blobV1.ts @@ -71,7 +71,7 @@ export type JsonTestEnd = { testId: string; expectedStatus: reporterTypes.TestStatus; timeout: number; - annotations: { type: string, description?: string }[]; + annotations: { type: string, description?: string, url?: string }[]; }; export type JsonTestResultStart = { diff --git a/packages/playwright/src/worker/testInfo.ts b/packages/playwright/src/worker/testInfo.ts index 1e9e1f9c46..fb10a8fe5f 100644 --- a/packages/playwright/src/worker/testInfo.ts +++ b/packages/playwright/src/worker/testInfo.ts @@ -198,7 +198,7 @@ export class TestInfoImpl implements TestInfo { this._tracing = new TestTracing(this, workerParams.artifactsDir); } - private _modifier(type: 'skip' | 'fail' | 'fixme' | 'slow', modifierArgs: [arg?: any, description?: string]) { + private _modifier(type: 'skip' | 'fail' | 'fixme' | 'slow', modifierArgs: [arg?: any, description?: string, url?: string]) { if (typeof modifierArgs[1] === 'function') { throw new Error([ 'It looks like you are calling test.skip() inside the test and pass a callback.', @@ -473,19 +473,19 @@ export class TestInfoImpl implements TestInfo { return path.normalize(path.resolve(this._configInternal.configDir, snapshotPath)); } - skip(...args: [arg?: any, description?: string]) { + skip(...args: [arg?: any, description?: string, url?: string]) { this._modifier('skip', args); } - fixme(...args: [arg?: any, description?: string]) { + fixme(...args: [arg?: any, description?: string, url?: string]) { this._modifier('fixme', args); } - fail(...args: [arg?: any, description?: string]) { + fail(...args: [arg?: any, description?: string, url?: string]) { this._modifier('fail', args); } - slow(...args: [arg?: any, description?: string]) { + slow(...args: [arg?: any, description?: string, url?: string]) { this._modifier('slow', args); } diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index e1299272a8..1c7e419cb4 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -1845,6 +1845,7 @@ export type TestStatus = 'passed' | 'failed' | 'timedOut' | 'skipped' | 'interru type TestDetailsAnnotation = { type: string; description?: string; + url?: string; }; export type TestDetails = { @@ -8175,6 +8176,11 @@ export interface TestInfo { * Optional description. */ description?: string; + + /** + * Optional url. + */ + url?: string; }>; /** diff --git a/packages/playwright/types/testReporter.d.ts b/packages/playwright/types/testReporter.d.ts index 52073066f0..b71ae4daa0 100644 --- a/packages/playwright/types/testReporter.d.ts +++ b/packages/playwright/types/testReporter.d.ts @@ -273,7 +273,7 @@ export interface JSONReportSpec { export interface JSONReportTest { timeout: number; - annotations: { type: string, description?: string }[], + annotations: { type: string, description?: string, url?: string }[], expectedStatus: TestStatus; projectName: string; projectId: string; @@ -481,6 +481,11 @@ export interface TestCase { * Optional description. */ description?: string; + + /** + * Optional url. + */ + url?: string; }>; /** diff --git a/tests/playwright-test/reporter-html.spec.ts b/tests/playwright-test/reporter-html.spec.ts index 10da0abbc3..e31921be89 100644 --- a/tests/playwright-test/reporter-html.spec.ts +++ b/tests/playwright-test/reporter-html.spec.ts @@ -744,16 +744,15 @@ test.info().annotations.push({ type: 'issue', description: 'I am not interested 'a.test.js': ` import { test, expect } from '@playwright/test'; test('annotated test', async ({ page }) => { - test.info().annotations.push({ type: 'issue', description: 'I add URL field to annotations for hyperlink display', url: 'https://github.com/microsoft/playwright/pull/31014' }); + test.info().annotations.push({ type: 'url', url: 'https://github.com/microsoft/playwright/pull/31014' }); }); `, }, { reporter: 'dot,html' }, { PLAYWRIGHT_HTML_OPEN: 'never' }); expect(result.exitCode).toBe(0); expect(result.passed).toBe(1); - await showReport(); await page.click('text=annotated test'); - await expect(page.locator('.test-case-annotation')).toHaveText('issue: I am not interested in this test'); + await expect(page.locator('.test-case-annotation')).toHaveText(`url: https://github.com/microsoft/playwright/pull/31014`); }); test('should render annotations as link if needed', async ({ runInlineTest, page, showReport, server }) => { diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 0367f3259c..77ac80e6ec 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -68,6 +68,7 @@ export type TestStatus = 'passed' | 'failed' | 'timedOut' | 'skipped' | 'interru type TestDetailsAnnotation = { type: string; description?: string; + url?: string; }; export type TestDetails = { diff --git a/utils/generate_types/overrides-testReporter.d.ts b/utils/generate_types/overrides-testReporter.d.ts index 51eab7e370..a69d27651b 100644 --- a/utils/generate_types/overrides-testReporter.d.ts +++ b/utils/generate_types/overrides-testReporter.d.ts @@ -94,7 +94,7 @@ export interface JSONReportSpec { export interface JSONReportTest { timeout: number; - annotations: { type: string, description?: string }[], + annotations: { type: string, description?: string, url?: string }[], expectedStatus: TestStatus; projectName: string; projectId: string;