chore(html-reporter) rework setting favicon and page title
This commit is contained in:
parent
863ae531fd
commit
fefea60857
|
|
@ -21,7 +21,6 @@
|
|||
<meta name='color-scheme' content='dark light'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
||||
<title>Playwright Test Report | Summary</title>
|
||||
<link rel="icon" href="/logo_default.svg">
|
||||
</head>
|
||||
<body>
|
||||
<div id='root'></div>
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import * as icons from './icons';
|
|||
import { Link, navigate } from './links';
|
||||
import { statusIcon } from './statusIcon';
|
||||
import { filterWithToken } from './filter';
|
||||
import { setDefaultFavIconAndTitle } from './uiUtils';
|
||||
|
||||
export const HeaderView: React.FC<React.PropsWithChildren<{
|
||||
stats: Stats,
|
||||
|
|
@ -33,6 +34,7 @@ export const HeaderView: React.FC<React.PropsWithChildren<{
|
|||
const popstateFn = () => {
|
||||
const params = new URLSearchParams(window.location.hash.slice(1));
|
||||
setFilterText(params.get('q') || '');
|
||||
setDefaultFavIconAndTitle();
|
||||
};
|
||||
window.addEventListener('popstate', popstateFn);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import * as ReactDOM from 'react-dom';
|
|||
import './colors.css';
|
||||
import type { LoadedReport } from './loadedReport';
|
||||
import { ReportView } from './reportView';
|
||||
import { setDefaultFavIconAndTitle } from './uiUtils';
|
||||
// @ts-ignore
|
||||
const zipjs = zipImport as typeof zip;
|
||||
|
||||
|
|
@ -34,6 +35,10 @@ const ReportLoader: React.FC = () => {
|
|||
const zipReport = new ZipReport();
|
||||
zipReport.load().then(() => setReport(zipReport));
|
||||
}, [report]);
|
||||
|
||||
React.useEffect(() => {
|
||||
setDefaultFavIconAndTitle();
|
||||
}, []);
|
||||
return <ReportView report={report}></ReportView>;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -79,14 +79,14 @@ test('should render test case', async ({ mount }) => {
|
|||
|
||||
test('should correctly set the page title and favicon', async ({ mount, page }) => {
|
||||
await mount(<TestCaseView projectNames={['chromium', 'webkit']} test={testCase} run={0} anchor=''></TestCaseView>);
|
||||
expect(await page.locator('link[rel="icon"]').getAttribute('href')).toEqual('../logo_expected.svg');
|
||||
expect(await page.locator('link[rel="icon"]').getAttribute('href')).toMatch(/\/assets\/logo_expected-[A-Za-z0-9]+\.svg/);
|
||||
expect(await page.title()).toEqual(`| ${testCase.title}`);
|
||||
});
|
||||
|
||||
test('should fallback to default title and favicon', async ({ mount, page }) => {
|
||||
await mount(<TestCaseView projectNames={['chromium', 'webkit']} test={undefined} run={0} anchor=''></TestCaseView>);
|
||||
expect(await page.locator('link[rel="icon"]').getAttribute('href')).toEqual('../logo_default.svg');
|
||||
expect(await page.title()).toEqual('Playwright Test Report');
|
||||
expect(await page.locator('link[rel="icon"]').getAttribute('href')).toMatch(/\/assets\/logo_default-[A-Za-z0-9]+\.svg/);
|
||||
expect(await page.title()).toEqual('Playwright Test Report | Summary');
|
||||
});
|
||||
|
||||
const linkRenderingTestCase: TestCase = {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import type { TestCase, TestCaseAnnotation, TestCaseSummary } from './types';
|
||||
import type { TestCase, TestCaseAnnotation } from './types';
|
||||
import * as React from 'react';
|
||||
import { TabbedPane } from './tabbedPane';
|
||||
import { AutoChip } from './chip';
|
||||
|
|
@ -24,7 +24,7 @@ import { statusIcon } from './statusIcon';
|
|||
import './testCaseView.css';
|
||||
import { TestResultView } from './testResultView';
|
||||
import { hashStringToInt } from './labelUtils';
|
||||
import { msToString } from './uiUtils';
|
||||
import { msToString, setDefaultFavIconAndTitle, setFavIcon } from './uiUtils';
|
||||
|
||||
export const TestCaseView: React.FC<{
|
||||
projectNames: string[],
|
||||
|
|
@ -46,9 +46,9 @@ export const TestCaseView: React.FC<{
|
|||
|
||||
React.useEffect(() => {
|
||||
document.title = test?.title ? `| ${test.title}` : 'Playwright Test Report';
|
||||
test?.outcome ? setFavicon({ outcome: test.outcome }) : setFavicon('default');
|
||||
test?.outcome ? setFavIcon({ outcome: test.outcome }) : setDefaultFavIconAndTitle();
|
||||
const resetFaviconOnBack = () => {
|
||||
setFavicon('default');
|
||||
setDefaultFavIconAndTitle();
|
||||
};
|
||||
|
||||
window.addEventListener('popstate', resetFaviconOnBack);
|
||||
|
|
@ -144,13 +144,3 @@ const LabelsLinkView: React.FC<React.PropsWithChildren<{
|
|||
) : null;
|
||||
};
|
||||
|
||||
function setFavicon(outcome: Pick<TestCaseSummary, 'outcome'> | 'default') {
|
||||
let link: HTMLLinkElement | null = document.querySelector("link[rel*='icon']");
|
||||
if (!link) {
|
||||
link = document.createElement('link');
|
||||
link.rel = 'icon';
|
||||
document.getElementsByTagName('head')[0].appendChild(link);
|
||||
}
|
||||
const outcomeValue = outcome instanceof Object ? outcome.outcome : outcome;
|
||||
link.href = `../logo_${outcomeValue}.svg`;
|
||||
}
|
||||
|
|
@ -13,6 +13,12 @@
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
import favIconExpected from '../logo_expected.svg';
|
||||
import favIconDefault from '../logo_default.svg';
|
||||
import favIconUnExpected from '../logo_unexpected.svg';
|
||||
import favIconSkipped from '../logo_skipped.svg';
|
||||
import favIconFlaky from '../logo_flaky.svg';
|
||||
import type { TestCaseSummary } from './types';
|
||||
|
||||
export function msToString(ms: number): string {
|
||||
if (!isFinite(ms))
|
||||
|
|
@ -39,3 +45,37 @@ export function msToString(ms: number): string {
|
|||
const days = hours / 24;
|
||||
return days.toFixed(1) + 'd';
|
||||
}
|
||||
|
||||
export function setFavIcon(outcome: Pick<TestCaseSummary, 'outcome'>) {
|
||||
const link: HTMLLinkElement | null = getLinkIconElement();
|
||||
const outcomeValue = outcome.outcome;
|
||||
|
||||
if (outcomeValue === 'expected') {
|
||||
link.href = favIconExpected;
|
||||
} else if (outcomeValue === 'unexpected') {
|
||||
link.href = favIconUnExpected;
|
||||
} else if (outcomeValue === 'skipped') {
|
||||
link.href = favIconSkipped;
|
||||
} else if (outcomeValue === 'flaky') {
|
||||
link.href = favIconFlaky;
|
||||
} else {
|
||||
link.href = favIconDefault;
|
||||
document.title = 'Playwright Test Report | Summary';
|
||||
}
|
||||
}
|
||||
|
||||
export function setDefaultFavIconAndTitle() {
|
||||
const link: HTMLLinkElement | null = getLinkIconElement();
|
||||
link.href = favIconDefault;
|
||||
document.title = 'Playwright Test Report | Summary';
|
||||
}
|
||||
|
||||
function getLinkIconElement() {
|
||||
let link: HTMLLinkElement | null = document.querySelector("link[rel*='icon']");
|
||||
if (!link) {
|
||||
link = document.createElement('link');
|
||||
link.rel = 'icon';
|
||||
document.getElementsByTagName('head')[0].appendChild(link);
|
||||
}
|
||||
return link;
|
||||
}
|
||||
Loading…
Reference in a new issue