From ff41876522b2a6aa1450ac62997140a4f86ff7bf Mon Sep 17 00:00:00 2001 From: Steve Dodier-Lazaro Date: Fri, 31 Oct 2025 17:01:08 +0100 Subject: [PATCH] Backport a11y branch changes to the new repo --- package.json | 2 +- src/components/Panel.tsx | 274 +++++++++++++++++++--------------- src/hoc/provideJestResult.tsx | 2 +- 3 files changed, 154 insertions(+), 124 deletions(-) diff --git a/package.json b/package.json index 86a2096..2912a2e 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "publishConfig": { "access": "public" }, - "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae16", + "gitHead": "a8e7fd8a655c69780bc20b9749d2699e45beae17", "storybook": { "displayName": "Jest", "icon": "https://pbs.twimg.com/profile_images/821713465245102080/mMtKIMax_400x400.jpg", diff --git a/src/components/Panel.tsx b/src/components/Panel.tsx index bf28ef6..9691b77 100644 --- a/src/components/Panel.tsx +++ b/src/components/Panel.tsx @@ -1,12 +1,12 @@ import type { FC } from 'react'; -import React, { Fragment } from 'react'; +import React, { Fragment, useMemo } from 'react'; -import { Link, Placeholder, ScrollArea, TabsState } from 'storybook/internal/components'; +import { Badge, Link, Placeholder, ScrollArea, TabsView } from 'storybook/internal/components'; import { useResizeDetector } from 'react-resize-detector'; import { convert, styled, themes } from 'storybook/theming'; -import type { Test } from '../hoc/provideJestResult'; +import type { AssertionResult, Test } from '../hoc/provideJestResult'; import { provideTests as provideJestResult } from '../hoc/provideJestResult'; import { Result } from './Result'; @@ -30,20 +30,15 @@ const Item = styled.li({ }); const ProgressWrapper = styled.div({ - position: 'relative', - height: 10, width: 30, display: 'flex', - top: -2, }); const SuiteHead = styled.div({ display: 'flex', - alignItems: 'baseline', - position: 'absolute', - zIndex: 2, - right: 20, - marginTop: 15, + alignItems: 'center', + marginInlineEnd: 5, + gap: 15, }); const UnstyledSuiteTotals: FC<{ @@ -72,30 +67,31 @@ const SuiteTotals = styled(UnstyledSuiteTotals)(({ theme }) => ({ alignItems: 'center', color: theme.color.dark, fontSize: '14px', - marginTop: -5, - '& > *': { - marginRight: 10, - }, + flexShrink: 0, })); -const SuiteProgressPortion = styled.div<{ color?: string; progressPercent: number }>(({ color, progressPercent }) => ({ - height: 6, - top: 3, - width: `${progressPercent}%`, - backgroundColor: color, -})); +const SuiteProgressPortion = styled.div<{ color?: string; progressPercent: number }>( + ({ color, progressPercent }) => ({ + height: 6, + top: 3, + width: `${progressPercent}%`, + backgroundColor: color, + }) +); interface ContentProps { tests: Test[]; className?: string; } -const getTestsByTypeMap = (result: any) => { - const testsByType: Map = new Map(); - result.assertionResults.forEach((assertion: any) => { +const getTestsByTypeMap = (result: Test['result']) => { + const testsByType: Map = new Map(); + result.assertionResults.forEach((assertion) => { + const existingTestsForType = testsByType.get(assertion.status); + testsByType.set( assertion.status, - testsByType.get(assertion.status) ? testsByType.get(assertion.status).concat(assertion) : [assertion] + existingTestsForType ? existingTestsForType.concat(assertion) : [assertion] ); }); return testsByType; @@ -117,6 +113,38 @@ const getColorByType = (type: string) => { } }; +const TabItemWrapper = styled.div({ + display: 'flex', + alignItems: 'center', + gap: 6, +}); + +const TabItem: FC<{ count: number; title: string }> = ({ count, title }) => ( + + {title} + + {count} + + +); + +const TabPanel: FC<{ + emptyMessage: string; + tests: AssertionResult[]; +}> = ({ emptyMessage, tests }) => ( + + {tests.length ? ( + tests?.map((res: AssertionResult) => ( + + + + )) + ) : ( + {emptyMessage} + )} + +); + const TestPanel: FC<{ test: Test }> = ({ test }) => { const { ref, width } = useResizeDetector(); const { result } = test; @@ -124,104 +152,94 @@ const TestPanel: FC<{ test: Test }> = ({ test }) => { return This story has tests configured, but no file was found; } - const testsByType: Map = getTestsByTypeMap(result); - const entries: any = testsByType.entries(); + const testsByType: Map = useMemo( + () => getTestsByTypeMap(result), + [result] + ); + const tabs = useMemo( + () => [ + { + id: 'failing-tests', + title: ( + + ), + children: () => ( + + ), + }, + { + id: 'passing-tests', + title: ( + + ), + children: () => ( + + ), + }, + { + id: 'pending-tests', + title: ( + + ), + children: () => ( + + ), + }, + { + id: 'todo-tests', + title: ( + + ), + children: () => ( + + ), + }, + ], + [testsByType] + ); + + const entries = testsByType.entries(); const sortedTestsByCount = [...entries].sort((a, b) => a[1].length - b[1].length); return (
- - - {width != null && width > 240 ? ( - - {sortedTestsByCount.map((entry: any) => { - return ( - - ); - })} - - ) : null} - - -
- - {testsByType.get(StatusTypes.FAILED_TYPE) ? ( - testsByType.get(StatusTypes.FAILED_TYPE).map((res: any) => ( - - - - )) - ) : ( - This story has no failing tests. - )} - -
-
- - {testsByType.get(StatusTypes.PASSED_TYPE) ? ( - testsByType.get(StatusTypes.PASSED_TYPE).map((res: any) => ( - - - - )) - ) : ( - This story has no passing tests. - )} - -
-
- - {testsByType.get(StatusTypes.PENDING_TYPE) ? ( - testsByType.get(StatusTypes.PENDING_TYPE).map((res: any) => ( - - - - )) - ) : ( - This story has no pending tests. - )} - -
-
- - {testsByType.get(StatusTypes.TODO_TYPE) ? ( - testsByType.get(StatusTypes.TODO_TYPE).map((res: any) => ( - - - - )) - ) : ( - This story has no tests todo. - )} - -
-
+ + + {width != null && width > 240 ? ( + + {sortedTestsByCount.map((entry) => { + return ( + + ); + })} + + ) : null} + + } + />
); }; @@ -240,20 +258,32 @@ interface PanelProps { tests?: Test[]; } +const TallPlaceholder = styled(Placeholder)({ + height: '100%', + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', +}); + const Panel = ({ tests }: PanelProps) => ( {tests ? ( ) : ( - + No tests found Learn how to  - + add Jest test results to your story - + )} ); diff --git a/src/hoc/provideJestResult.tsx b/src/hoc/provideJestResult.tsx index 1e2b61b..62acbe8 100644 --- a/src/hoc/provideJestResult.tsx +++ b/src/hoc/provideJestResult.tsx @@ -8,7 +8,7 @@ import type { API } from 'storybook/manager-api'; import { ADD_TESTS } from '../shared'; // TODO: import type from @types/jest -interface AssertionResult { +export interface AssertionResult { status: string; fullName: string; title: string;