diff --git a/packages/react-dev-overlay/src/internal/components/CodeFrame/CodeFrame.tsx b/packages/react-dev-overlay/src/internal/components/CodeFrame/CodeFrame.tsx index 69ad556409a2..9d85a4377f91 100644 --- a/packages/react-dev-overlay/src/internal/components/CodeFrame/CodeFrame.tsx +++ b/packages/react-dev-overlay/src/internal/components/CodeFrame/CodeFrame.tsx @@ -14,7 +14,11 @@ export const CodeFrame: React.FC = function CodeFrame({ const formattedFrame = React.useMemo(() => { const lines = codeFrame.split(/\r?\n/g) const prefixLength = lines - .map((line) => /^>? +\d+ +\| ( *)/.exec(stripAnsi(line))) + .map((line) => + /^>? +\d+ +\| [ ]+/.exec(stripAnsi(line)) === null + ? null + : /^>? +\d+ +\| ( *)/.exec(stripAnsi(line)) + ) .filter(Boolean) .map((v) => v!.pop()!) .reduce((c, n) => (isNaN(c) ? n.length : Math.min(c, n.length)), NaN) diff --git a/test/development/acceptance/ReactRefreshLogBox.test.ts b/test/development/acceptance/ReactRefreshLogBox.test.ts index f730ed3b6113..45ed9991c360 100644 --- a/test/development/acceptance/ReactRefreshLogBox.test.ts +++ b/test/development/acceptance/ReactRefreshLogBox.test.ts @@ -15,6 +15,36 @@ describe('ReactRefreshLogBox', () => { }) afterAll(() => next.destroy()) + test('should strip whitespace correctly with newline', async () => { + const { session, cleanup } = await sandbox(next) + + await session.patch( + 'index.js', + ` + export default function Page() { + return ( + <> + +

index page

+ + { + throw new Error('idk') + }}> + click me + + + ) + } + ` + ) + await session.evaluate(() => document.querySelector('a').click()) + + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() + + await cleanup() + }) + test('logbox: can recover from a syntax error without losing state', async () => { const { session, cleanup } = await sandbox(next) diff --git a/test/development/acceptance/__snapshots__/ReactRefreshLogBox.test.ts.snap b/test/development/acceptance/__snapshots__/ReactRefreshLogBox.test.ts.snap index 02f775b461d1..3e7144e1ef08 100644 --- a/test/development/acceptance/__snapshots__/ReactRefreshLogBox.test.ts.snap +++ b/test/development/acceptance/__snapshots__/ReactRefreshLogBox.test.ts.snap @@ -104,6 +104,18 @@ exports[`ReactRefreshLogBox render error not shown right after syntax error 1`] 9 | }" `; +exports[`ReactRefreshLogBox should strip whitespace correctly with newline 1`] = ` +"index.js (9:34) @ onClick + + 7 | + 8 | { +> 9 | throw new Error('idk') + | ^ + 10 | }}> + 11 | click me + 12 | " +`; + exports[`ReactRefreshLogBox stuck error 1`] = ` "Foo.js (4:10) @ Foo diff --git a/test/integration/config-devtool-dev/test/index.test.js b/test/integration/config-devtool-dev/test/index.test.js index 36d2b13c99ec..cdd5094e6263 100644 --- a/test/integration/config-devtool-dev/test/index.test.js +++ b/test/integration/config-devtool-dev/test/index.test.js @@ -37,16 +37,16 @@ describe('devtool set in development mode in next config', () => { // TODO: add win32 snapshot } else { expect(await getRedboxSource(browser)).toMatchInlineSnapshot(` - "pages/index.js (5:10) @ eval - - 3 | export default function Index(props) { - 4 | useEffect(() => { - > 5 | throw new Error('this should render') - | ^ - 6 | }, []) - 7 | return
Index Page
- 8 | }" - `) +"pages/index.js (5:10) @ eval + + 3 | export default function Index(props) { + 4 | useEffect(() => { +> 5 | throw new Error('this should render') + | ^ + 6 | }, []) + 7 | return
Index Page
+ 8 | }" +`) } await browser.close()