diff --git a/docs/src/test-reporters-js.md b/docs/src/test-reporters-js.md index 184527e930003..169ba7fae0192 100644 --- a/docs/src/test-reporters-js.md +++ b/docs/src/test-reporters-js.md @@ -275,6 +275,7 @@ HTML report supports the following configuration options and environment variabl | `PLAYWRIGHT_HTML_NO_COPY_PROMPT` | `noCopyPrompt` | If true, disable rendering of the Copy prompt for errors. Supports `true`, `1`, `false`, and `0`. | `false` | `PLAYWRIGHT_HTML_NO_SNIPPETS` | `noSnippets` | If true, disable rendering code snippets in the action log. If there is a top level error, that report section with code snippet will still render. Supports `true`, `1`, `false`, and `0`. | `false` | `PLAYWRIGHT_HTML_DO_NOT_INLINE_ASSETS` | `doNotInlineAssets` | If true, JavaScript, CSS and report data are written as separate files alongside `index.html` instead of being embedded inline. Use this when serving the report under a strict [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) that disallows inline scripts and styles. Supports `true`, `1`, `false`, and `0`. | `false` +| `PLAYWRIGHT_HTML_MERGE_FILES` | `mergeFiles` | If true, tests are grouped by their top-level `test.describe()` title instead of the file they belong to. Supports `true`, `1`, `false`, and `0`. | `false` ### Blob reporter diff --git a/packages/html-reporter/src/headerView.tsx b/packages/html-reporter/src/headerView.tsx index ab456e86ca75e..86e8db01492bf 100644 --- a/packages/html-reporter/src/headerView.tsx +++ b/packages/html-reporter/src/headerView.tsx @@ -26,7 +26,6 @@ import { filterWithQuery } from './filter'; import { linkifyText } from '@web/renderUtils'; import { Dialog } from '@web/shared/dialog'; import { kThemeOptions, type Theme, useThemeSetting } from '@web/theme'; -import { useSetting } from '@web/uiUtils'; export const HeaderView: React.FC<{ title: string | undefined, @@ -132,7 +131,6 @@ const SettingsButton: React.FC = () => { const settingsRef = React.useRef(null); const [settingsOpen, setSettingsOpen] = React.useState(false); const [theme, setTheme] = useThemeSetting(); - const [mergeFiles, setMergeFiles] = useSetting('mergeFiles', false); return <>
{ ))} - - ; }; diff --git a/packages/html-reporter/src/reportView.tsx b/packages/html-reporter/src/reportView.tsx index 2eda20a72c78c..c2f3d2fd8ba2d 100644 --- a/packages/html-reporter/src/reportView.tsx +++ b/packages/html-reporter/src/reportView.tsx @@ -26,7 +26,6 @@ import './reportView.css'; import { TestCaseView } from './testCaseView'; import { TestFilesHeader, TestFilesView } from './testFilesView'; import './theme.css'; -import { useSetting } from '@web/uiUtils'; import { Speedboard } from './speedboard'; declare global { @@ -54,7 +53,7 @@ export const ReportView: React.FC<{ const [metadataVisible, setMetadataVisible] = React.useState(false); const [errorsVisible, setErrorsVisible] = React.useState(true); const speedboard = searchParams.has('speedboard'); - const [mergeFiles] = useSetting('mergeFiles', false); + const mergeFiles = !!report?.json()?.options.mergeFiles; const testId = searchParams.get('testId'); const q = searchParams.get('q')?.toString() || ''; const filterParam = q ? '&q=' + q : ''; diff --git a/packages/html-reporter/src/types.d.ts b/packages/html-reporter/src/types.d.ts index ca2ecec64dd3b..62bab6c0e3a4c 100644 --- a/packages/html-reporter/src/types.d.ts +++ b/packages/html-reporter/src/types.d.ts @@ -40,6 +40,7 @@ export type HTMLReportOptions = { title?: string; noCopyPrompt?: boolean; noSnippets?: boolean; + mergeFiles?: boolean; }; export type HTMLReport = { diff --git a/packages/playwright/src/reporters/html.ts b/packages/playwright/src/reporters/html.ts index 8bc5cdc8586df..8fe90bcbbf822 100644 --- a/packages/playwright/src/reporters/html.ts +++ b/packages/playwright/src/reporters/html.ts @@ -157,11 +157,13 @@ class HtmlReporter implements ReporterV2 { const noSnippets = parseBooleanEnvVar('PLAYWRIGHT_HTML_NO_SNIPPETS') ?? this._options.noSnippets; const noCopyPrompt = parseBooleanEnvVar('PLAYWRIGHT_HTML_NO_COPY_PROMPT') ?? this._options.noCopyPrompt; const doNotInlineAssets = parseBooleanEnvVar('PLAYWRIGHT_HTML_DO_NOT_INLINE_ASSETS') ?? this._options.doNotInlineAssets ?? false; + const mergeFiles = parseBooleanEnvVar('PLAYWRIGHT_HTML_MERGE_FILES') ?? this._options.mergeFiles; const builder = new HtmlBuilder(yazl, this.config, this._outputFolder, this._attachmentsBaseURL, doNotInlineAssets, { title: process.env.PLAYWRIGHT_HTML_TITLE || this._options.title, noSnippets, noCopyPrompt, + mergeFiles, }); this._buildResult = await builder.build(this.config.metadata, projectSuites, result, this._topLevelErrors, this._machines); } diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index d30c7f240de59..690b8c8f62a46 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -32,6 +32,7 @@ export type HtmlReporterOptions = { noSnippets?: boolean; noCopyPrompt?: boolean; doNotInlineAssets?: boolean; + mergeFiles?: boolean; }; export type ReporterDescription = Readonly< diff --git a/tests/playwright-test/reporter-html.spec.ts b/tests/playwright-test/reporter-html.spec.ts index 5f84bdaabe10f..707c4c04b25e1 100644 --- a/tests/playwright-test/reporter-html.spec.ts +++ b/tests/playwright-test/reporter-html.spec.ts @@ -3508,6 +3508,9 @@ for (const useIntermediateMergeReport of [true, false] as const) { test('should support merge files option', async ({ runInlineTest, showReport, page }) => { await runInlineTest({ + 'playwright.config.ts': ` + export default { reporter: [['html', { mergeFiles: true }], ['line']] }; + `, 'a.test.js': ` import { test, expect } from '@playwright/test'; test.describe('describe', () => { @@ -3521,13 +3524,10 @@ test('should support merge files option', async ({ runInlineTest, showReport, pa test('test 3', async ({}) => {}); }); `, - }, { reporter: 'dot,html' }, { PLAYWRIGHT_HTML_OPEN: 'never' }); + }, {}, { PLAYWRIGHT_HTML_OPEN: 'never' }); await showReport(); - await page.getByRole('button', { name: 'Settings' }).click(); - await page.getByRole('checkbox', { name: 'Merge files' }).click(); - await expect(page).toMatchAriaSnapshot(` - button "" [expanded] - region: diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 7087c2dea2299..f06954a448433 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -31,6 +31,7 @@ export type HtmlReporterOptions = { noSnippets?: boolean; noCopyPrompt?: boolean; doNotInlineAssets?: boolean; + mergeFiles?: boolean; }; export type ReporterDescription = Readonly<