diff --git a/static/app/components/seer/markdown/embeds/components/log/log.spec.tsx b/static/app/components/seer/markdown/embeds/components/log/log.spec.tsx index 4c269d22a92c..38702ebdec16 100644 --- a/static/app/components/seer/markdown/embeds/components/log/log.spec.tsx +++ b/static/app/components/seer/markdown/embeds/components/log/log.spec.tsx @@ -128,6 +128,23 @@ describe('Seer log embed', () => { ); }); + it('renders an ANSI-colored message without escape codes', async () => { + mockLogDetails([ + { + name: OurLogKnownFieldKey.MESSAGE, + type: 'str', + value: '\x1B[31mPayment\x1B[0m provider timed out', + }, + ...ATTRIBUTES.slice(1), + ]); + + renderLog(); + + const colored = await screen.findByText('Payment'); + expect(colored.style.color).toContain('color-mix(in srgb,'); + expect(colored.parentElement).toHaveTextContent(/^Payment provider timed out$/); + }); + it('renders on a page that never initialized page filters', async () => { // Seer renders from the organization layout, so it appears on plenty of // pages that mount no PageFiltersContainer -- the stories page among them. diff --git a/static/app/components/seer/markdown/embeds/components/log/logBlock.tsx b/static/app/components/seer/markdown/embeds/components/log/logBlock.tsx index abc820a50d94..24efe6186ba9 100644 --- a/static/app/components/seer/markdown/embeds/components/log/logBlock.tsx +++ b/static/app/components/seer/markdown/embeds/components/log/logBlock.tsx @@ -5,6 +5,7 @@ import {useQuery} from '@tanstack/react-query'; import {Flex, Stack} from '@sentry/scraps/layout'; import {Text} from '@sentry/scraps/text'; +import {AnsiText} from 'sentry/components/ansiText'; import {LoadingIndicator} from 'sentry/components/loadingIndicator'; import {ALL_ACCESS_PROJECTS} from 'sentry/components/pageFilters/constants'; import {LogAttributesView} from 'sentry/components/seer/markdown/embeds/components/log/logAttributesView'; @@ -336,7 +337,7 @@ export default function LogBlock(props: LogData) { - {String(message ?? '')} + {String(message ?? '')}