diff --git a/test/acceptance/ReactRefresh.test.js b/test/acceptance/ReactRefresh.test.js index 8de1b0b4bd44ab32baeb4f0ce7bc11adaad9ecb9..53725b5f75a1cd976de3527d945f487744f3927c 100644 --- a/test/acceptance/ReactRefresh.test.js +++ b/test/acceptance/ReactRefresh.test.js @@ -4,7 +4,7 @@ import { sandbox } from './helpers' jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5 -test('basic: can edit a component without losing state', async () => { +test('can edit a component without losing state', async () => { const [session, cleanup] = await sandbox() await session.patch( @@ -59,62 +59,6 @@ test('basic: can edit a component without losing state', async () => { await cleanup() }) -test('can recover from a syntax error without losing state', async () => { - const [session, cleanup] = await sandbox() - - await session.patch( - 'index.js', - ` - import { useCallback, useState } from 'react' - - export default function Index() { - const [count, setCount] = useState(0) - const increment = useCallback(() => setCount(c => c + 1), [setCount]) - return ( -
-

{count}

- -
- ) - } - ` - ) - - await session.evaluate(() => document.querySelector('button').click()) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('1') - - await session.patch('index.js', `export default () =>
setCount(c => c + 1), [setCount]) - return ( -
-

Count: {count}

- -
- ) - } - ` - ) - - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('Count: 1') - - await cleanup() -}) - test('cyclic dependencies', async () => { const [session, cleanup] = await sandbox() @@ -273,152 +217,3 @@ test('cyclic dependencies', async () => { await cleanup() }) - -test('logbox: can recover from a event handler error', async () => { - const [session, cleanup] = await sandbox() - - await session.patch( - 'index.js', - ` - import { useCallback, useState } from 'react' - - export default function Index() { - const [count, setCount] = useState(0) - const increment = useCallback(() => { - setCount(c => c + 1) - throw new Error('oops') - }, [setCount]) - return ( -
-

{count}

- -
- ) - } - ` - ) - - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('0') - await session.evaluate(() => document.querySelector('button').click()) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('1') - - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxSource()).toMatchInlineSnapshot(` - "index.js (8:16) @ eval - - 6 | const increment = useCallback(() => { - 7 | setCount(c => c + 1) - > 8 | throw new Error('oops') - | ^ - 9 | }, [setCount]) - 10 | return ( - 11 |
" - `) - - await session.patch( - 'index.js', - ` - import { useCallback, useState } from 'react' - - export default function Index() { - const [count, setCount] = useState(0) - const increment = useCallback(() => setCount(c => c + 1), [setCount]) - return ( -
-

Count: {count}

- -
- ) - } - ` - ) - - expect(await session.hasRedbox()).toBe(false) - - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('Count: 1') - await session.evaluate(() => document.querySelector('button').click()) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('Count: 2') - - expect(await session.hasRedbox()).toBe(false) - - await cleanup() -}) - -test('logbox: can recover from a component error', async () => { - const [session, cleanup] = await sandbox() - - await session.write( - 'child.js', - ` - export default function Child() { - return

Hello

; - } - ` - ) - - await session.patch( - 'index.js', - ` - import Child from './child' - - export default function Index() { - return ( -
- -
- ) - } - ` - ) - - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('Hello') - - await session.patch( - 'child.js', - ` - // hello - export default function Child() { - throw new Error('oops') - } - ` - ) - - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxSource()).toMatchInlineSnapshot(` - "child.js (4:14) @ Child - - 2 | // hello - 3 | export default function Child() { - > 4 | throw new Error('oops') - | ^ - 5 | } - 6 | " - `) - - const didNotReload = await session.patch( - 'child.js', - ` - export default function Child() { - return

Hello

; - } - ` - ) - - expect(didNotReload).toBe(true) - expect(await session.hasRedbox()).toBe(false) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('Hello') - - await cleanup() -}) diff --git a/test/acceptance/ReactRefreshLogBox.test.js b/test/acceptance/ReactRefreshLogBox.test.js new file mode 100644 index 0000000000000000000000000000000000000000..fdc55a44d981ab669b0c0565c967bd83bf1af070 --- /dev/null +++ b/test/acceptance/ReactRefreshLogBox.test.js @@ -0,0 +1,212 @@ +/* global jasmine */ +/* eslint-env jest */ +import { sandbox } from './helpers' + +jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5 + +test('logbox: can recover from a syntax error without losing state', async () => { + const [session, cleanup] = await sandbox() + + await session.patch( + 'index.js', + ` + import { useCallback, useState } from 'react' + + export default function Index() { + const [count, setCount] = useState(0) + const increment = useCallback(() => setCount(c => c + 1), [setCount]) + return ( +
+

{count}

+ +
+ ) + } + ` + ) + + await session.evaluate(() => document.querySelector('button').click()) + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('1') + + await session.patch('index.js', `export default () =>
setCount(c => c + 1), [setCount]) + return ( +
+

Count: {count}

+ +
+ ) + } + ` + ) + + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('Count: 1') + + expect(await session.hasRedbox()).toBe(false) + + await cleanup() +}) + +test('logbox: can recover from a event handler error', async () => { + const [session, cleanup] = await sandbox() + + await session.patch( + 'index.js', + ` + import { useCallback, useState } from 'react' + + export default function Index() { + const [count, setCount] = useState(0) + const increment = useCallback(() => { + setCount(c => c + 1) + throw new Error('oops') + }, [setCount]) + return ( +
+

{count}

+ +
+ ) + } + ` + ) + + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('0') + await session.evaluate(() => document.querySelector('button').click()) + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('1') + + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchInlineSnapshot(` + "index.js (8:16) @ eval + + 6 | const increment = useCallback(() => { + 7 | setCount(c => c + 1) + > 8 | throw new Error('oops') + | ^ + 9 | }, [setCount]) + 10 | return ( + 11 |
" + `) + + await session.patch( + 'index.js', + ` + import { useCallback, useState } from 'react' + + export default function Index() { + const [count, setCount] = useState(0) + const increment = useCallback(() => setCount(c => c + 1), [setCount]) + return ( +
+

Count: {count}

+ +
+ ) + } + ` + ) + + expect(await session.hasRedbox()).toBe(false) + + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('Count: 1') + await session.evaluate(() => document.querySelector('button').click()) + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('Count: 2') + + expect(await session.hasRedbox()).toBe(false) + + await cleanup() +}) + +test('logbox: can recover from a component error', async () => { + const [session, cleanup] = await sandbox() + + await session.write( + 'child.js', + ` + export default function Child() { + return

Hello

; + } + ` + ) + + await session.patch( + 'index.js', + ` + import Child from './child' + + export default function Index() { + return ( +
+ +
+ ) + } + ` + ) + + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('Hello') + + await session.patch( + 'child.js', + ` + // hello + export default function Child() { + throw new Error('oops') + } + ` + ) + + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchInlineSnapshot(` + "child.js (4:14) @ Child + + 2 | // hello + 3 | export default function Child() { + > 4 | throw new Error('oops') + | ^ + 5 | } + 6 | " + `) + + const didNotReload = await session.patch( + 'child.js', + ` + export default function Child() { + return

Hello

; + } + ` + ) + + expect(didNotReload).toBe(true) + expect(await session.hasRedbox()).toBe(false) + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('Hello') + + await cleanup() +})