diff --git a/packages/html-reporter/src/copyToClipboard.tsx b/packages/html-reporter/src/copyToClipboard.tsx index 17b1dfbf95..8171cdd6c3 100644 --- a/packages/html-reporter/src/copyToClipboard.tsx +++ b/packages/html-reporter/src/copyToClipboard.tsx @@ -39,7 +39,7 @@ export const CopyToClipboard: React.FunctionComponent = ({ }); }, [value]); const iconElement = icon === 'check' ? icons.check() : icon === 'cross' ? icons.cross() : icons.copy(); - return ; + return ; }; type CopyToClipboardContainerProps = CopyToClipboardProps & { diff --git a/packages/html-reporter/src/metadataView.css b/packages/html-reporter/src/metadataView.css index 70d6ba78ab..0cbced5250 100644 --- a/packages/html-reporter/src/metadataView.css +++ b/packages/html-reporter/src/metadataView.css @@ -18,6 +18,7 @@ cursor: pointer; user-select: none; margin-left: 5px; + color: var(--color-fg-default); } .metadata-view { @@ -26,16 +27,46 @@ margin-top: 8px; } +.metadata-view .metadata-section { + margin: 8px 10px 8px 32px; +} + +.metadata-view span:not(.copy-button-container), +.metadata-view a { + display: inline-block; + line-height: 24px; +} + +.metadata-section { + align-items: center; +} + +.metadata-properties { + display: flex; + flex-direction: column; + align-items: normal; + gap: 8px; +} + +.metadata-properties > div { + height: 24px; +} + .metadata-separator { height: 1px; border-bottom: 1px solid var(--color-border-default); } -.metadata-view .copy-value-container { - margin-top: -2px; -} - .git-commit-info a { color: var(--color-fg-default); font-weight: 600; } + +.copyable-property { + white-space: pre; +} + +.copyable-property > span { + display: flex; + align-items: center; +} diff --git a/packages/html-reporter/src/metadataView.tsx b/packages/html-reporter/src/metadataView.tsx index ed050f4480..03a5ed06f4 100644 --- a/packages/html-reporter/src/metadataView.tsx +++ b/packages/html-reporter/src/metadataView.tsx @@ -31,7 +31,6 @@ export const MetadataContext = React.createContext([]); export function MetadataProvider({ metadata, children }: React.PropsWithChildren<{ metadata: Metadata }>) { const entries = React.useMemo(() => { // TODO: do not plumb actualWorkers through metadata. - return Object.entries(metadata).filter(([key]) => key !== 'actualWorkers'); }, [metadata]); @@ -88,30 +87,43 @@ const InnerMetadataView = () => { {entries.length > 0 &&
} } - {entries.map(([key, value]) => { - const valueString = typeof value !== 'object' || value === null || value === undefined ? String(value) : JSON.stringify(value); - const trimmedValue = valueString.length > 1000 ? valueString.slice(0, 1000) + '\u2026' : valueString; - return
- {key} - {valueString && : {linkifyText(trimmedValue)}} -
; - })} +
+ {entries.map(([propertyName, value]) => { + const valueString = typeof value !== 'object' || value === null || value === undefined ? String(value) : JSON.stringify(value); + const trimmedValue = valueString.length > 1000 ? valueString.slice(0, 1000) + '\u2026' : valueString; + return ( +
+ + {propertyName} + : {linkifyText(trimmedValue)} + +
+ ); + })} +
; }; const GitCommitInfoView: React.FC<{ info: GitCommitInfo }> = ({ info }) => { const email = info['revision.email'] ? ` <${info['revision.email']}>` : ''; const author = `${info['revision.author'] || ''}${email}`; + const subject = info['revision.subject'] || ''; const shortTimestamp = Intl.DateTimeFormat(undefined, { dateStyle: 'medium' }).format(info['revision.timestamp']); const longTimestamp = Intl.DateTimeFormat(undefined, { dateStyle: 'full', timeStyle: 'long' }).format(info['revision.timestamp']); - return
-
- - {info['revision.subject'] || ''} - -
-
{author}
-
on {shortTimestamp}
+ return
+
+
+ {info['revision.link'] ? ( + + {subject} + + ) : + {subject} + } +
+
+ {author} + on {shortTimestamp} {info['ci.link'] && ( <> ยท @@ -126,9 +138,10 @@ const GitCommitInfoView: React.FC<{ info: GitCommitInfo }> = ({ info }) => { )}
- {!!info['revision.link'] && - {info['revision.id']?.slice(0, 7) || 'unknown'} - } - {!info['revision.link'] && !!info['revision.id'] && {info['revision.id'].slice(0, 7)}} + {!!info['revision.link'] ? ( + + {info['revision.id']?.slice(0, 7) || 'unknown'} + + ) : !!info['revision.id'] && {info['revision.id'].slice(0, 7)}}
; }; diff --git a/packages/html-reporter/src/testFileView.css b/packages/html-reporter/src/testFileView.css index 72858846bb..37bf428490 100644 --- a/packages/html-reporter/src/testFileView.css +++ b/packages/html-reporter/src/testFileView.css @@ -69,4 +69,11 @@ .test-file-test-status-icon { flex: none; +} + +.test-file-header-info { + display: flex; + align-items: center; + gap: 8px; + color: var(--color-fg-subtle); } \ No newline at end of file diff --git a/packages/html-reporter/src/testFilesView.tsx b/packages/html-reporter/src/testFilesView.tsx index dcac5e8cea..49e2233669 100644 --- a/packages/html-reporter/src/testFilesView.tsx +++ b/packages/html-reporter/src/testFilesView.tsx @@ -69,14 +69,16 @@ export const TestFilesHeader: React.FC<{ }> = ({ report, filteredStats, metadataVisible, toggleMetadataVisible }) => { const metadataEntries = useMetadata(); if (!report) - return; + return null; return <>
- {metadataEntries.length > 0 &&
- {metadataVisible ? icons.downArrow() : icons.rightArrow()}Metadata -
} - {report.projectNames.length === 1 && !!report.projectNames[0] &&
Project: {report.projectNames[0]}
} - {filteredStats &&
Filtered: {filteredStats.total} {!!filteredStats.total && ('(' + msToString(filteredStats.duration) + ')')}
} +
+ {metadataEntries.length > 0 &&
+ {metadataVisible ? icons.downArrow() : icons.rightArrow()}Metadata +
} + {report.projectNames.length === 1 && !!report.projectNames[0] &&
Project: {report.projectNames[0]}
} + {filteredStats &&
Filtered: {filteredStats.total} {!!filteredStats.total && ('(' + msToString(filteredStats.duration) + ')')}
} +
{report ? new Date(report.startTime).toLocaleString() : ''}
Total time: {msToString(report.duration ?? 0)}
diff --git a/tests/playwright-test/reporter-html.spec.ts b/tests/playwright-test/reporter-html.spec.ts index acb54f3b31..2c7915a357 100644 --- a/tests/playwright-test/reporter-html.spec.ts +++ b/tests/playwright-test/reporter-html.spec.ts @@ -1238,7 +1238,7 @@ for (const useIntermediateMergeReport of [true, false] as const) { - link "Logs" - link "Pull Request" - link /^[a-f0-9]{7}$/ - - text: 'foo: value1 bar: {"prop":"value2"} baz: ["value3",123]' + - text: 'foo : value1 bar : {"prop":"value2"} baz : ["value3",123]' `); });