Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(html-report): clean up git metadata display #34713

Merged
merged 6 commits into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/html-reporter/src/copyToClipboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const CopyToClipboard: React.FunctionComponent<CopyToClipboardProps> = ({
});
}, [value]);
const iconElement = icon === 'check' ? icons.check() : icon === 'cross' ? icons.cross() : icons.copy();
return <button className='copy-icon' aria-label='Copy to clipboard' onClick={handleCopy}>{iconElement}</button>;
return <button className='copy-icon' title='Copy to clipboard' aria-label='Copy to clipboard' onClick={handleCopy}>{iconElement}</button>;
};

type CopyToClipboardContainerProps = CopyToClipboardProps & {
Expand Down
39 changes: 35 additions & 4 deletions packages/html-reporter/src/metadataView.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
cursor: pointer;
user-select: none;
margin-left: 5px;
color: var(--color-fg-default);
}

.metadata-view {
Expand All @@ -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;
}
55 changes: 34 additions & 21 deletions packages/html-reporter/src/metadataView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ export const MetadataContext = React.createContext<MetadataEntries>([]);
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]);

Expand Down Expand Up @@ -88,30 +87,43 @@ const InnerMetadataView = () => {
<GitCommitInfoView info={gitCommitInfo}/>
{entries.length > 0 && <div className='metadata-separator' />}
</>}
{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 <div className='m-1 ml-5' key={key}>
<span style={{ fontWeight: 'bold' }} title={key}>{key}</span>
{valueString && <CopyToClipboardContainer value={valueString}>: <span title={trimmedValue}>{linkifyText(trimmedValue)}</span></CopyToClipboardContainer>}
</div>;
})}
<div className='metadata-section metadata-properties'>
{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 (
<div key={propertyName} className='copyable-property'>
<CopyToClipboardContainer value={valueString}>
<span style={{ fontWeight: 'bold' }} title={propertyName}>{propertyName}</span>
: <span title={trimmedValue}>{linkifyText(trimmedValue)}</span>
</CopyToClipboardContainer>
</div>
);
})}
</div>
</div>;
};

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 <div className='hbox pl-4 pr-2 git-commit-info' style={{ alignItems: 'center' }}>
<div className='vbox'>
<a className='m-2' href={info['revision.link']} target='_blank' rel='noopener noreferrer'>
<span title={info['revision.subject'] || ''}>{info['revision.subject'] || ''}</span>
</a>
<div className='hbox m-2 mt-1'>
<div className='mr-1'>{author}</div>
<div title={longTimestamp}> on {shortTimestamp}</div>
return <div className='hbox git-commit-info metadata-section'>
<div className='vbox metadata-properties'>
<div>
{info['revision.link'] ? (
<a href={info['revision.link']} target='_blank' rel='noopener noreferrer' title={subject}>
{subject}
</a>
) : <span title={subject}>
{subject}
</span>}
</div>
<div className='hbox'>
<span className='mr-1'>{author}</span>
<span title={longTimestamp}> on {shortTimestamp}</span>
{info['ci.link'] && (
<>
<span className='mx-2'>·</span>
Expand All @@ -126,9 +138,10 @@ const GitCommitInfoView: React.FC<{ info: GitCommitInfo }> = ({ info }) => {
)}
</div>
</div>
{!!info['revision.link'] && <a href={info['revision.link']} target='_blank' rel='noopener noreferrer'>
<span title='View commit details'>{info['revision.id']?.slice(0, 7) || 'unknown'}</span>
</a>}
{!info['revision.link'] && !!info['revision.id'] && <span>{info['revision.id'].slice(0, 7)}</span>}
{!!info['revision.link'] ? (
<a href={info['revision.link']} target='_blank' rel='noopener noreferrer' title='View commit details'>
{info['revision.id']?.slice(0, 7) || 'unknown'}
</a>
) : !!info['revision.id'] && <span>{info['revision.id'].slice(0, 7)}</span>}
</div>;
};
7 changes: 7 additions & 0 deletions packages/html-reporter/src/testFileView.css
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
14 changes: 8 additions & 6 deletions packages/html-reporter/src/testFilesView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,16 @@ export const TestFilesHeader: React.FC<{
}> = ({ report, filteredStats, metadataVisible, toggleMetadataVisible }) => {
const metadataEntries = useMetadata();
if (!report)
return;
return null;
return <>
<div className='mx-1' style={{ display: 'flex', marginTop: 10 }}>
{metadataEntries.length > 0 && <div className='metadata-toggle' role='button' onClick={toggleMetadataVisible} title={metadataVisible ? 'Hide metadata' : 'Show metadata'}>
{metadataVisible ? icons.downArrow() : icons.rightArrow()}Metadata
</div>}
{report.projectNames.length === 1 && !!report.projectNames[0] && <div data-testid='project-name' style={{ color: 'var(--color-fg-subtle)' }}>Project: {report.projectNames[0]}</div>}
{filteredStats && <div data-testid='filtered-tests-count' style={{ color: 'var(--color-fg-subtle)', padding: '0 10px' }}>Filtered: {filteredStats.total} {!!filteredStats.total && ('(' + msToString(filteredStats.duration) + ')')}</div>}
<div className='test-file-header-info'>
{metadataEntries.length > 0 && <div className='metadata-toggle' role='button' onClick={toggleMetadataVisible} title={metadataVisible ? 'Hide metadata' : 'Show metadata'}>
{metadataVisible ? icons.downArrow() : icons.rightArrow()}Metadata
</div>}
{report.projectNames.length === 1 && !!report.projectNames[0] && <div data-testid='project-name'>Project: {report.projectNames[0]}</div>}
{filteredStats && <div data-testid='filtered-tests-count'>Filtered: {filteredStats.total} {!!filteredStats.total && ('(' + msToString(filteredStats.duration) + ')')}</div>}
</div>
<div style={{ flex: 'auto' }}></div>
<div data-testid='overall-time' style={{ color: 'var(--color-fg-subtle)', marginRight: '10px' }}>{report ? new Date(report.startTime).toLocaleString() : ''}</div>
<div data-testid='overall-duration' style={{ color: 'var(--color-fg-subtle)' }}>Total time: {msToString(report.duration ?? 0)}</div>
Expand Down
2 changes: 1 addition & 1 deletion tests/playwright-test/reporter-html.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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]'
`);
});

Expand Down
Loading