diff --git a/packages/html-reporter/src/chip.tsx b/packages/html-reporter/src/chip.tsx index bbddcf7a05..f6de923464 100644 --- a/packages/html-reporter/src/chip.tsx +++ b/packages/html-reporter/src/chip.tsx @@ -20,7 +20,7 @@ import './colors.css'; import './common.css'; import * as icons from './icons'; import { clsx } from '@web/uiUtils'; -import { Reveal } from './links'; +import { Anchor } from './links'; export const Chip: React.FC<{ header: JSX.Element | string, @@ -53,15 +53,15 @@ export const AutoChip: React.FC<{ noInsets?: boolean, children?: any, dataTestId?: string, - revealId?: string, -}> = ({ header, initialExpanded, noInsets, children, dataTestId, revealId }) => { + anchorId?: string, +}> = ({ header, initialExpanded, noInsets, children, dataTestId, anchorId }) => { const [expanded, setExpanded] = React.useState(initialExpanded ?? true); const onChangeReveal = React.useCallback((isRevealed: boolean) => { if (isRevealed) setExpanded(true); }, [setExpanded]); - return {children} - ; + ; }; diff --git a/packages/html-reporter/src/links.tsx b/packages/html-reporter/src/links.tsx index 1db8bd9b2d..397530382e 100644 --- a/packages/html-reporter/src/links.tsx +++ b/packages/html-reporter/src/links.tsx @@ -114,19 +114,20 @@ export function generateTraceUrl(traces: TestAttachment[]) { const kMissingContentType = 'x-playwright/missing'; - -export function useRevealed(revealId?: string) { - const searchParams = React.useContext(SearchParamsContext); - if (revealId === undefined) - return false; - return searchParams.get('reveal') === revealId; +export function useAnchor(id: string | undefined, onChange: (isRevealed: boolean) => void) { + React.useEffect(() => { + const listener = () => { + const params = new URLSearchParams(window.location.hash.slice(1)); + onChange(params.get('anchor') === id); + }; + window.addEventListener('popstate', listener); + return () => window.removeEventListener('popstate', listener); + }, [id, onChange]); } -export function Reveal({ revealId, onChange, children }: React.PropsWithChildren<{ revealId?: string, onChange?(isRevealed: boolean, ref: HTMLDivElement): void }>) { - const isRevealed = useRevealed(revealId); - +export function Anchor({ id, onChange, children }: React.PropsWithChildren<{ id?: string, onChange?(isRevealed: boolean, ref: HTMLDivElement): void }>) { const ref = React.useRef(null); - React.useEffect(() => { + const onAnchorChange = React.useCallback((isRevealed: boolean) => { if (!ref.current) return; @@ -135,8 +136,9 @@ export function Reveal({ revealId, onChange, children }: React.PropsWithChildren return; if (isRevealed) - ref.current?.scrollIntoView({ block: 'start', inline: 'start' }); - }, [isRevealed, onChange]); + requestAnimationFrame(() => ref.current?.scrollIntoView({ block: 'start', inline: 'start' })); + }, [onChange]); + useAnchor(id, onAnchorChange); return
{children}
; } diff --git a/packages/html-reporter/src/testFileView.tsx b/packages/html-reporter/src/testFileView.tsx index 52a79ab7b4..6b31d2ebe2 100644 --- a/packages/html-reporter/src/testFileView.tsx +++ b/packages/html-reporter/src/testFileView.tsx @@ -75,12 +75,12 @@ function imageDiffBadge(test: TestCaseSummary): JSX.Element | undefined { const resultWithImageDiff = test.results.find(result => result.attachments.some(attachment => { return attachment.contentType.startsWith('image/') && !!attachment.name.match(/-(expected|actual|diff)/); })); - return resultWithImageDiff ? {image()} : undefined; + return resultWithImageDiff ? {image()} : undefined; } function videoBadge(test: TestCaseSummary): JSX.Element | undefined { const resultWithVideo = test.results.find(result => result.attachments.some(attachment => attachment.name === 'video')); - return resultWithVideo ? {video()} : undefined; + return resultWithVideo ? {video()} : undefined; } function traceBadge(test: TestCaseSummary): JSX.Element | undefined { diff --git a/packages/html-reporter/src/testResultView.tsx b/packages/html-reporter/src/testResultView.tsx index 79a4331ac7..1b02d27bba 100644 --- a/packages/html-reporter/src/testResultView.tsx +++ b/packages/html-reporter/src/testResultView.tsx @@ -20,7 +20,7 @@ import { TreeItem } from './treeItem'; import { msToString } from './utils'; import { AutoChip } from './chip'; import { traceImage } from './images'; -import { AttachmentLink, generateTraceUrl } from './links'; +import { AttachmentLink, generateTraceUrl, Link } from './links'; import { statusIcon } from './statusIcon'; import type { ImageDiff } from '@web/shared/imageDiffView'; import { ImageDiffView } from '@web/shared/imageDiffView'; @@ -91,7 +91,7 @@ export const TestResultView: React.FC<{ } {diffs.map((diff, index) => - + )} @@ -107,7 +107,7 @@ export const TestResultView: React.FC<{ })} } - {!!traces.length && + {!!traces.length && {
@@ -116,7 +116,7 @@ export const TestResultView: React.FC<{
}
} - {!!videos.length && + {!!videos.length && {videos.map((a, i) =>