chore(html-reporter): show project name always for the test file (#19905)

Fixes https://github.com/microsoft/playwright/issues/19874
This commit is contained in:
Max Schmitt 2023-01-10 17:11:38 +01:00 committed by GitHub
parent db5087e951
commit e2a2196e6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 14 deletions

View file

@ -28,7 +28,7 @@ test('should render counters', async ({ mount }) => {
skipped: 10,
ok: false,
duration: 100000
}} filterText='' setFilterText={() => {}}></HeaderView>);
}} filterText='' setFilterText={() => {}} projectNames={[]}></HeaderView>);
await expect(component.locator('a', { hasText: 'All' }).locator('.counter')).toHaveText('100');
await expect(component.locator('a', { hasText: 'Passed' }).locator('.counter')).toHaveText('42');
await expect(component.locator('a', { hasText: 'Failed' }).locator('.counter')).toHaveText('31');
@ -36,7 +36,7 @@ test('should render counters', async ({ mount }) => {
await expect(component.locator('a', { hasText: 'Skipped' }).locator('.counter')).toHaveText('10');
});
test('should toggle filters', async ({ page, mount: mount }) => {
test('should toggle filters', async ({ page, mount }) => {
const filters: string[] = [];
const component = await mount(<HeaderView
stats={{
@ -49,7 +49,9 @@ test('should toggle filters', async ({ page, mount: mount }) => {
duration: 100000
}}
filterText=''
setFilterText={(filterText: string) => filters.push(filterText)}>
setFilterText={(filterText: string) => filters.push(filterText)}
projectNames={[]}
>
</HeaderView>);
await component.locator('a', { hasText: 'All' }).click();
await component.locator('a', { hasText: 'Passed' }).click();
@ -62,3 +64,36 @@ test('should toggle filters', async ({ page, mount: mount }) => {
await expect(page).toHaveURL(/#\?q=s:skipped/);
expect(filters).toEqual(['', 's:passed', 's:failed', 's:flaky', 's:skipped']);
});
test('should show the project names', async ({ mount }) => {
const stats = {
total: 100,
expected: 42,
unexpected: 31,
flaky: 17,
skipped: 10,
ok: false,
duration: 100000
};
await test.step('with 1 project', async () => {
const component = await mount(<HeaderView
stats={stats}
filterText=''
setFilterText={() => {}}
projectNames={['my-project']}
>
</HeaderView>);
await expect(component.getByText('Project: my-project')).toBeVisible();
});
await test.step('with more than 1 project', async () => {
const component = await mount(<HeaderView
stats={stats}
filterText=''
setFilterText={() => {}}
projectNames={['great-project', 'my-project']}
>
</HeaderView>);
await expect(component.getByText('my-project')).toBeHidden();
await expect(component.getByText('great-project')).toBeHidden();
});
});

View file

@ -28,7 +28,8 @@ export const HeaderView: React.FC<React.PropsWithChildren<{
stats: Stats,
filterText: string,
setFilterText: (filterText: string) => void,
}>> = ({ stats, filterText, setFilterText }) => {
projectNames: string[],
}>> = ({ stats, filterText, setFilterText, projectNames }) => {
React.useEffect(() => {
(async () => {
window.addEventListener('popstate', () => {
@ -56,7 +57,10 @@ export const HeaderView: React.FC<React.PropsWithChildren<{
}}></input>
</form>
</div>
<div className='pt-2'><span data-testid="overall-duration" style={{ color: 'var(--color-fg-subtle)', paddingRight: '10px', float: 'right' }}>Total time: {msToString(stats.duration)}</span></div>
<div className='pt-2'>
{projectNames.length === 1 && <span data-testid="project-name" style={{ color: 'var(--color-fg-subtle)', float: 'left' }}>Project: {projectNames[0]}</span>}
<span data-testid="overall-duration" style={{ color: 'var(--color-fg-subtle)', paddingRight: '10px', float: 'right' }}>Total time: {msToString(stats.duration)}</span>
</div>
</>);
};

View file

@ -74,13 +74,13 @@ const InnerMetadataView: React.FC<Metainfo> = metadata => {
{metadata['revision.subject'] || 'Commit Metainfo'}
</span>} initialExpanded={false} dataTestId='metadata-chip'>
{metadata['revision.subject'] &&
<MetadatViewItem
<MetadataViewItem
testId='revision.subject'
content={<span>{metadata['revision.subject']}</span>}
/>
}
{metadata['revision.id'] &&
<MetadatViewItem
<MetadataViewItem
testId='revision.id'
content={<span>{metadata['revision.id']}</span>}
href={metadata['revision.link']}
@ -88,13 +88,13 @@ const InnerMetadataView: React.FC<Metainfo> = metadata => {
/>
}
{(metadata['revision.author'] || metadata['revision.email']) &&
<MetadatViewItem
<MetadataViewItem
content={`${metadata['revision.author']} ${metadata['revision.email']}`}
icon='person'
/>
}
{metadata['revision.timestamp'] &&
<MetadatViewItem
<MetadataViewItem
testId='revision.timestamp'
content={
<>
@ -107,23 +107,23 @@ const InnerMetadataView: React.FC<Metainfo> = metadata => {
/>
}
{metadata['ci.link'] &&
<MetadatViewItem
<MetadataViewItem
content='CI/CD Logs'
href={metadata['ci.link']}
icon='externalLink'
/>
}
{metadata['timestamp'] &&
<MetadatViewItem
<MetadataViewItem
content={<span style={{ color: 'var(--color-fg-subtle)' }}>
Report generated on {Intl.DateTimeFormat(undefined, { dateStyle: 'full', timeStyle: 'long' }).format(metadata['timestamp'])}
</span>}></MetadatViewItem>
</span>}></MetadataViewItem>
}
</AutoChip>
);
};
const MetadatViewItem: React.FC<{ content: JSX.Element | string; icon?: keyof typeof icons, href?: string, testId?: string }> = ({ content, icon, href, testId }) => {
const MetadataViewItem: React.FC<{ content: JSX.Element | string; icon?: keyof typeof icons, href?: string, testId?: string }> = ({ content, icon, href, testId }) => {
return (
<div className='my-1 hbox' data-test-id={testId} >
<div className='mr-2'>

View file

@ -50,7 +50,7 @@ export const ReportView: React.FC<{
return <div className='htmlreport vbox px-4 pb-4'>
<main>
{report?.json() && <HeaderView stats={report.json().stats} filterText={filterText} setFilterText={setFilterText}></HeaderView>}
{report?.json() && <HeaderView stats={report.json().stats} filterText={filterText} setFilterText={setFilterText} projectNames={report.json().projectNames}></HeaderView>}
{report?.json().metadata && <MetadataView {...report?.json().metadata as Metainfo} />}
<Route predicate={testFilesRoutePredicate}>
<TestFilesView report={report?.json()} filter={filter} expandedFiles={expandedFiles} setExpandedFiles={setExpandedFiles}></TestFilesView>

View file

@ -71,6 +71,7 @@ test('should generate report', async ({ runInlineTest, showReport, page }) => {
await expect(page.locator('.test-file-test-outcome-skipped >> text=skipped')).toBeVisible();
await expect(page.getByTestId('overall-duration'), 'should contain humanized total time with at most 1 decimal place').toContainText(/^Total time: \d+(\.\d)?(ms|s|m)$/);
await expect(page.getByTestId('project-name'), 'should contain project name').toContainText('project-name');
await expect(page.locator('.metadata-view')).not.toBeVisible();
});