Skip to content

Commit

Permalink
Merge pull request #29110 from storybookjs/kasper/fix-ansi-chars
Browse files Browse the repository at this point in the history
Addon-Interactions: Use ansi-to-html for colored test errors
  • Loading branch information
kasperpeulen authored Sep 13, 2024
2 parents 8b16feb + e693dcd commit 1d27f37
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 9 deletions.
1 change: 1 addition & 0 deletions code/addons/interactions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"@devtools-ds/object-inspector": "^1.1.2",
"@storybook/icons": "^1.2.5",
"@types/node": "^22.0.0",
"ansi-to-html": "^0.7.2",
"formik": "^2.2.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
5 changes: 3 additions & 2 deletions code/addons/interactions/src/components/Interaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { type Call, CallStates, type ControlStates } from '@storybook/instrument

import { transparentize } from 'polished';

import { isChaiError, isJestError } from '../utils';
import { isChaiError, isJestError, useAnsiToHtmlFilter } from '../utils';
import type { Controls } from './InteractionsPanel';
import { MatcherResult } from './MatcherResult';
import { MethodCall } from './MethodCall';
Expand Down Expand Up @@ -116,6 +116,7 @@ const RowMessage = styled('div')(({ theme }) => ({
}));

export const Exception = ({ exception }: { exception: Call['exception'] }) => {
const filter = useAnsiToHtmlFilter();
if (isJestError(exception)) {
return <MatcherResult {...exception} />;
}
Expand All @@ -135,7 +136,7 @@ export const Exception = ({ exception }: { exception: Call['exception'] }) => {
const more = paragraphs.length > 1;
return (
<RowMessage>
<pre>{paragraphs[0]}</pre>
<pre dangerouslySetInnerHTML={{ __html: filter.toHtml(paragraphs[0]) }}></pre>
{more && <p>See the full stack trace in the browser console.</p>}
</RowMessage>
);
Expand Down
12 changes: 8 additions & 4 deletions code/addons/interactions/src/components/InteractionsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { type Call, CallStates, type ControlStates } from '@storybook/instrument

import { transparentize } from 'polished';

import { isTestAssertionError } from '../utils';
import { isTestAssertionError, useAnsiToHtmlFilter } from '../utils';
import { Empty } from './EmptyState';
import { Interaction } from './Interaction';
import { Subnav } from './Subnav';
Expand Down Expand Up @@ -97,6 +97,7 @@ export const InteractionsPanel: React.FC<InteractionsPanelProps> = React.memo(
onScrollToEnd,
endRef,
}) {
const filter = useAnsiToHtmlFilter();
return (
<Container>
{(interactions.length > 0 || hasException) && (
Expand Down Expand Up @@ -131,9 +132,12 @@ export const InteractionsPanel: React.FC<InteractionsPanelProps> = React.memo(
<CaughtExceptionTitle>
Caught exception in <CaughtExceptionCode>play</CaughtExceptionCode> function
</CaughtExceptionTitle>
<CaughtExceptionStack data-chromatic="ignore">
{printSerializedError(caughtException)}
</CaughtExceptionStack>
<CaughtExceptionStack
data-chromatic="ignore"
dangerouslySetInnerHTML={{
__html: filter.toHtml(printSerializedError(caughtException)),
}}
></CaughtExceptionStack>
</CaughtException>
)}
{unhandledErrors && (
Expand Down
10 changes: 9 additions & 1 deletion code/addons/interactions/src/components/MatcherResult.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';

import { styled, typography } from 'storybook/internal/theming';

import { useAnsiToHtmlFilter } from '../utils';
import { Node } from './MethodCall';

const getParams = (line: string, fromIndex = 0): string => {
Expand Down Expand Up @@ -59,6 +60,7 @@ export const MatcherResult = ({
message: string;
style?: React.CSSProperties;
}) => {
const filter = useAnsiToHtmlFilter();
const lines = message.split('\n');
return (
<pre
Expand Down Expand Up @@ -131,7 +133,13 @@ export const MatcherResult = ({
];
}

return [<span key={line + index}>{line}</span>, <br key={`br${index}`} />];
return [
<span
key={line + index}
dangerouslySetInnerHTML={{ __html: filter.toHtml(line) }}
></span>,
<br key={`br${index}`} />,
];
})}
</pre>
);
Expand Down
16 changes: 16 additions & 0 deletions code/addons/interactions/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { type StorybookTheme, useTheme } from 'storybook/internal/theming';

import Filter from 'ansi-to-html';

export function isTestAssertionError(error: unknown) {
return isChaiError(error) || isJestError(error);
}
Expand All @@ -21,3 +25,15 @@ export function isJestError(error: unknown) {
error.message.startsWith('expect(')
);
}

export function createAnsiToHtmlFilter(theme: StorybookTheme) {
return new Filter({
fg: theme.color.defaultText,
bg: theme.background.content,
});
}

export function useAnsiToHtmlFilter() {
const theme = useTheme();
return createAnsiToHtmlFilter(theme);
}
5 changes: 3 additions & 2 deletions code/renderers/react/src/__test__/portable-stories.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import React from 'react';

import { addons } from 'storybook/internal/preview-api';

import type { Meta } from '@storybook/react';
import type { ProjectAnnotations } from '@storybook/csf';
import type { Meta, ReactRenderer } from '@storybook/react';

import * as addonActionsPreview from '@storybook/addon-actions/preview';

Expand Down Expand Up @@ -124,7 +125,7 @@ describe('projectAnnotations', () => {
const Story = composeStory(
ButtonStories.WithActionArgType,
ButtonStories.default,
addonActionsPreview
addonActionsPreview as ProjectAnnotations<ReactRenderer>
);
expect(Story.args.someActionArg).toHaveProperty('isAction', true);
});
Expand Down
1 change: 1 addition & 0 deletions code/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5492,6 +5492,7 @@ __metadata:
"@storybook/instrumenter": "workspace:*"
"@storybook/test": "workspace:*"
"@types/node": "npm:^22.0.0"
ansi-to-html: "npm:^0.7.2"
formik: "npm:^2.2.9"
polished: "npm:^4.2.2"
react: "npm:^18.2.0"
Expand Down

0 comments on commit 1d27f37

Please sign in to comment.