diff --git a/packages/html-reporter/src/reportView.tsx b/packages/html-reporter/src/reportView.tsx index e48064201c26f..aa3a219a25877 100644 --- a/packages/html-reporter/src/reportView.tsx +++ b/packages/html-reporter/src/reportView.tsx @@ -97,7 +97,7 @@ const TestCaseViewLoader: React.FC<{ testIdToFileIdMap: Map, }> = ({ report, testIdToFileIdMap, tests }) => { const searchParams = React.useContext(SearchParamsContext); - const [test, setTest] = React.useState(); + const [test, setTest] = React.useState('loading'); const testId = searchParams.get('testId'); const run = +(searchParams.get('run') || '0'); @@ -110,28 +110,37 @@ const TestCaseViewLoader: React.FC<{ React.useEffect(() => { (async () => { - if (!testId || testId === test?.testId) + if (!testId || (typeof test === 'object' && testId === test.testId)) return; const fileId = testIdToFileIdMap.get(testId); - if (!fileId) + if (!fileId) { + setTest('not-found'); return; - const file = await report.entry(`${fileId}.json`) as TestFile; - for (const t of file.tests) { - if (t.testId === testId) { - setTest(t); - break; - } } + const file = await report.entry(`${fileId}.json`) as TestFile; + setTest(file?.tests.find(t => t.testId === testId) || 'not-found'); })(); }, [test, report, testId, testIdToFileIdMap]); - return ; + if (test === 'loading') + return
; + + if (test === 'not-found') { + return
+
Test not found
+
Test ID: {testId}
+
; + } + + return
+ ; +
; }; function computeStats(files: TestFileSummary[], filter: Filter): FilteredStats { diff --git a/packages/html-reporter/src/testCaseView.tsx b/packages/html-reporter/src/testCaseView.tsx index 0ccbb8b6f6bd4..16d4900725a11 100644 --- a/packages/html-reporter/src/testCaseView.tsx +++ b/packages/html-reporter/src/testCaseView.tsx @@ -30,49 +30,44 @@ import { CopyToClipboardContainer } from './copyToClipboard'; export const TestCaseView: React.FC<{ projectNames: string[], - test: TestCase | undefined, + test: TestCase, next: TestCaseSummary | undefined, prev: TestCaseSummary | undefined, run: number, }> = ({ projectNames, test, run, next, prev }) => { const [selectedResultIndex, setSelectedResultIndex] = React.useState(run); const searchParams = React.useContext(SearchParamsContext); - const filterParam = searchParams.has('q') ? '&q=' + searchParams.get('q') : ''; - - const labels = React.useMemo(() => { - if (!test) - return undefined; - return test.tags; - }, [test]); - const visibleTestAnnotations = test?.annotations.filter(a => !a.type.startsWith('_')) ?? []; + const filterParam = searchParams.has('q') ? '&q=' + searchParams.get('q') : ''; + const labels = React.useMemo(() => test.tags, [test]); + const visibleTestAnnotations = test.annotations.filter(a => !a.type.startsWith('_')) ?? []; - return
- {test &&
+ return <> +
{test.path.join(' › ')}
« previous
next »
-
} - {test &&
{test?.title}
} - {test &&
+
+
{test.title}
+
- + {test.location.file}:{test.location.line}
{msToString(test.duration)}
-
} - {test && (!!test.projectName || labels) &&
- {test && !!test.projectName && } +
+ {(!!test.projectName || labels) &&
+ {!!test.projectName && } {labels && }
} - {test?.results.length === 0 && visibleTestAnnotations.length !== 0 && + {test.results.length === 0 && visibleTestAnnotations.length !== 0 && {visibleTestAnnotations.map((annotation, index) => )} } - {test && ({ id: String(index), title:
@@ -88,8 +83,8 @@ export const TestCaseView: React.FC<{ ; }, - })) || []} selectedTab={String(selectedResultIndex)} setSelectedTab={id => setSelectedResultIndex(+id)} />} -
; + })) || []} selectedTab={String(selectedResultIndex)} setSelectedTab={id => setSelectedResultIndex(+id)} /> + ; }; function TestCaseAnnotationView({ annotation: { type, description } }: { annotation: TestAnnotation }) {