diff --git a/test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts b/test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts index 26c403611a4e1..936488394b58a 100644 --- a/test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts +++ b/test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts @@ -2,74 +2,78 @@ import { sandbox } from './helpers' import { createNext, FileRef } from 'e2e-utils' import { NextInstance } from 'test/lib/next-modes/base' import path from 'path' +import { getSnapshotTestDescribe } from 'next-test-utils' // TODO-APP: Investigate snapshot mismatch -describe('ReactRefreshLogBox app', () => { - if (process.env.NEXT_TEST_REACT_VERSION === '^17') { - it('should skip for react v17', () => {}) - return - } - - let next: NextInstance - - beforeAll(async () => { - next = await createNext({ - files: new FileRef(path.join(__dirname, 'fixtures', 'default-template')), - dependencies: { - react: 'latest', - 'react-dom': 'latest', - }, - skipStart: true, +for (const variant of ['default', 'turbo']) { + getSnapshotTestDescribe(variant)(`ReactRefreshLogBox app ${variant}`, () => { + if (process.env.NEXT_TEST_REACT_VERSION === '^17') { + it('should skip for react v17', () => {}) + return + } + + let next: NextInstance + + beforeAll(async () => { + next = await createNext({ + files: new FileRef( + path.join(__dirname, 'fixtures', 'default-template') + ), + dependencies: { + react: 'latest', + 'react-dom': 'latest', + }, + skipStart: true, + }) }) - }) - afterAll(() => next.destroy()) - - // Module trace is only available with webpack 5 - test('Node.js builtins', async () => { - const { session, cleanup } = await sandbox( - next, - new Map([ - [ - 'node_modules/my-package/index.js', - ` + afterAll(() => next.destroy()) + + // Module trace is only available with webpack 5 + test('Node.js builtins', async () => { + const { session, cleanup } = await sandbox( + next, + new Map([ + [ + 'node_modules/my-package/index.js', + ` const dns = require('dns') module.exports = dns `, - ], - [ - 'node_modules/my-package/package.json', - ` + ], + [ + 'node_modules/my-package/package.json', + ` { "name": "my-package", "version": "0.0.1" } `, - ], - ]) - ) + ], + ]) + ) - await session.patch( - 'index.js', - ` + await session.patch( + 'index.js', + ` import pkg from 'my-package' export default function Hello() { return (pkg ?
index page
} `, - ], - ]) - ) - expect(await session.hasRedbox(true)).toBe(true) + ], + ]) + ) + expect(await session.hasRedbox(true)).toBe(true) - const source = await session.getRedboxSource() - expect(source).toMatchSnapshot() + const source = await session.getRedboxSource() + expect(source).toMatchSnapshot() - await session.patch( - 'app/page.js', - `'use client' + await session.patch( + 'app/page.js', + `'use client' export default function Page(props) { returnindex page
} ` - ) - expect(await session.hasRedbox(false)).toBe(false) - expect( - await session.evaluate(() => document.documentElement.innerHTML) - ).toContain('index page') + ) + expect(await session.hasRedbox(false)).toBe(false) + expect( + await session.evaluate(() => document.documentElement.innerHTML) + ).toContain('index page') - await cleanup() + await cleanup() + }) }) -}) +} diff --git a/test/development/acceptance-app/ReactRefreshLogBox.test.ts b/test/development/acceptance-app/ReactRefreshLogBox.test.ts index b11f6b5fa285a..466191000a5b0 100644 --- a/test/development/acceptance-app/ReactRefreshLogBox.test.ts +++ b/test/development/acceptance-app/ReactRefreshLogBox.test.ts @@ -2,35 +2,38 @@ import { sandbox } from './helpers' import { createNext, FileRef } from 'e2e-utils' import { NextInstance } from 'test/lib/next-modes/base' -import { check } from 'next-test-utils' +import { check, getSnapshotTestDescribe } from 'next-test-utils' import path from 'path' -describe('ReactRefreshLogBox app', () => { - if (process.env.NEXT_TEST_REACT_VERSION === '^17') { - it('should skip for react v17', () => {}) - return - } - - let next: NextInstance - - beforeAll(async () => { - next = await createNext({ - files: new FileRef(path.join(__dirname, 'fixtures', 'default-template')), - dependencies: { - react: 'latest', - 'react-dom': 'latest', - }, - skipStart: true, +for (const variant of ['default', 'turbo']) { + getSnapshotTestDescribe(variant)(`ReactRefreshLogBox app ${variant}`, () => { + if (process.env.NEXT_TEST_REACT_VERSION === '^17') { + it('should skip for react v17', () => {}) + return + } + + let next: NextInstance + + beforeAll(async () => { + next = await createNext({ + files: new FileRef( + path.join(__dirname, 'fixtures', 'default-template') + ), + dependencies: { + react: 'latest', + 'react-dom': 'latest', + }, + skipStart: true, + }) }) - }) - afterAll(() => next.destroy()) + afterAll(() => next.destroy()) - test('should strip whitespace correctly with newline', async () => { - const { session, cleanup } = await sandbox(next) + test('should strip whitespace correctly with newline', async () => { + const { session, cleanup } = await sandbox(next) - await session.patch( - 'index.js', - ` + await session.patch( + 'index.js', + ` export default function Page() { return ( <> @@ -46,21 +49,21 @@ describe('ReactRefreshLogBox app', () => { ) } ` - ) - await session.evaluate(() => document.querySelector('a').click()) + ) + await session.evaluate(() => document.querySelector('a').click()) - await session.waitForAndOpenRuntimeError() - expect(await session.getRedboxSource()).toMatchSnapshot() + await session.waitForAndOpenRuntimeError() + expect(await session.getRedboxSource()).toMatchSnapshot() - await cleanup() - }) + await cleanup() + }) - test('logbox: can recover from a syntax error without losing state', async () => { - const { session, cleanup } = await sandbox(next) + test('logbox: can recover from a syntax error without losing state', async () => { + const { session, cleanup } = await sandbox(next) - await session.patch( - 'index.js', - ` + await session.patch( + 'index.js', + ` import { useCallback, useState } from 'react' export default function Index() { @@ -74,21 +77,21 @@ describe('ReactRefreshLogBox app', () => { ) } ` - ) + ) - await session.evaluate(() => document.querySelector('button').click()) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('1') + await session.evaluate(() => document.querySelector('button').click()) + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('1') - await session.patch('index.js', `export default () =>Hello
; } ` - ) + ) - await session.patch( - 'index.js', - ` + await session.patch( + 'index.js', + ` import Child from './child' export default function Index() { @@ -213,53 +216,53 @@ describe('ReactRefreshLogBox app', () => { ) } ` - ) + ) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('Hello') + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('Hello') - await session.patch( - 'child.js', - ` + 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()).toMatchSnapshot() + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() - // TODO-APP: re-enable when error recovery doesn't reload the page. - /* const didNotReload = */ await session.patch( - 'child.js', - ` + // TODO-APP: re-enable when error recovery doesn't reload the page. + /* const didNotReload = */ await session.patch( + 'child.js', + ` export default function Child() { returnHello
; } ` - ) + ) - // TODO-APP: re-enable when error recovery doesn't reload the page. - // expect(didNotReload).toBe(true) - expect(await session.hasRedbox()).toBe(false) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('Hello') + // TODO-APP: re-enable when error recovery doesn't reload the page. + // expect(didNotReload).toBe(true) + expect(await session.hasRedbox()).toBe(false) + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('Hello') - await cleanup() - }) + await cleanup() + }) - // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554137262 - test('render error not shown right after syntax error', async () => { - const { session, cleanup } = await sandbox(next) + // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554137262 + test('render error not shown right after syntax error', async () => { + const { session, cleanup } = await sandbox(next) - // Starting here: - await session.patch( - 'index.js', - ` + // Starting here: + await session.patch( + 'index.js', + ` import * as React from 'react'; class ClassDefault extends React.Component { render() { @@ -269,16 +272,16 @@ describe('ReactRefreshLogBox app', () => { export default ClassDefault; ` - ) + ) - expect( - await session.evaluate(() => document.querySelector('h1').textContent) - ).toBe('Default Export') + expect( + await session.evaluate(() => document.querySelector('h1').textContent) + ).toBe('Default Export') - // Break it with a syntax error: - await session.patch( - 'index.js', - ` + // Break it with a syntax error: + await session.patch( + 'index.js', + ` import * as React from 'react'; class ClassDefault extends React.Component { @@ -289,13 +292,13 @@ describe('ReactRefreshLogBox app', () => { export default ClassDefault; ` - ) - expect(await session.hasRedbox(true)).toBe(true) + ) + expect(await session.hasRedbox(true)).toBe(true) - // Now change the code to introduce a runtime error without fixing the syntax error: - await session.patch( - 'index.js', - ` + // Now change the code to introduce a runtime error without fixing the syntax error: + await session.patch( + 'index.js', + ` import * as React from 'react'; class ClassDefault extends React.Component { @@ -307,13 +310,13 @@ describe('ReactRefreshLogBox app', () => { export default ClassDefault; ` - ) - expect(await session.hasRedbox(true)).toBe(true) + ) + expect(await session.hasRedbox(true)).toBe(true) - // Now fix the syntax error: - await session.patch( - 'index.js', - ` + // Now fix the syntax error: + await session.patch( + 'index.js', + ` import * as React from 'react'; class ClassDefault extends React.Component { @@ -325,28 +328,28 @@ describe('ReactRefreshLogBox app', () => { export default ClassDefault; ` - ) - expect(await session.hasRedbox(true)).toBe(true) + ) + expect(await session.hasRedbox(true)).toBe(true) - await check(async () => { - const source = await session.getRedboxSource() - return source?.length > 1 ? 'success' : source - }, 'success') + await check(async () => { + const source = await session.getRedboxSource() + return source?.length > 1 ? 'success' : source + }, 'success') - expect(await session.getRedboxSource()).toMatchSnapshot() + expect(await session.getRedboxSource()).toMatchSnapshot() - await cleanup() - }) + await cleanup() + }) - // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554137807 - test('module init error not shown', async () => { - // Start here: - const { session, cleanup } = await sandbox(next) + // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554137807 + test('module init error not shown', async () => { + // Start here: + const { session, cleanup } = await sandbox(next) - // We start here. - await session.patch( - 'index.js', - ` + // We start here. + await session.patch( + 'index.js', + ` import * as React from 'react'; class ClassDefault extends React.Component { render() { @@ -355,16 +358,16 @@ describe('ReactRefreshLogBox app', () => { } export default ClassDefault; ` - ) + ) - expect( - await session.evaluate(() => document.querySelector('h1').textContent) - ).toBe('Default Export') + expect( + await session.evaluate(() => document.querySelector('h1').textContent) + ).toBe('Default Export') - // Add a throw in module init phase: - await session.patch( - 'index.js', - ` + // Add a throw in module init phase: + await session.patch( + 'index.js', + ` // top offset for snapshot import * as React from 'react'; throw new Error('no') @@ -375,26 +378,26 @@ describe('ReactRefreshLogBox app', () => { } export default ClassDefault; ` - ) + ) - expect(await session.hasRedbox(true)).toBe(true) - if (process.platform === 'win32') { - expect(await session.getRedboxSource()).toMatchSnapshot() - } else { - expect(await session.getRedboxSource()).toMatchSnapshot() - } + expect(await session.hasRedbox(true)).toBe(true) + if (process.platform === 'win32') { + expect(await session.getRedboxSource()).toMatchSnapshot() + } else { + expect(await session.getRedboxSource()).toMatchSnapshot() + } - await cleanup() - }) + await cleanup() + }) - // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554144016 - test('stuck error', async () => { - const { session, cleanup } = await sandbox(next) + // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554144016 + test('stuck error', async () => { + const { session, cleanup } = await sandbox(next) - // We start here. - await session.patch( - 'index.js', - ` + // We start here. + await session.patch( + 'index.js', + ` import * as React from 'react'; function FunctionDefault() { @@ -403,23 +406,23 @@ describe('ReactRefreshLogBox app', () => { export default FunctionDefault; ` - ) + ) - // We add a new file. Let's call it Foo.js. - await session.write( - 'Foo.js', - ` + // We add a new file. Let's call it Foo.js. + await session.write( + 'Foo.js', + ` // intentionally skips export export default function Foo() { return React.createElement('h1', null, 'Foo'); } ` - ) + ) - // We edit our first file to use it. - await session.patch( - 'index.js', - ` + // We edit our first file to use it. + await session.patch( + 'index.js', + ` import * as React from 'react'; import Foo from './Foo'; function FunctionDefault() { @@ -427,48 +430,48 @@ describe('ReactRefreshLogBox app', () => { } export default FunctionDefault; ` - ) + ) - // We get an error because Foo didn't import React. Fair. - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxSource()).toMatchSnapshot() + // We get an error because Foo didn't import React. Fair. + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() - // Let's add that to Foo. - await session.patch( - 'Foo.js', - ` + // Let's add that to Foo. + await session.patch( + 'Foo.js', + ` import * as React from 'react'; export default function Foo() { return React.createElement('h1', null, 'Foo'); } ` - ) + ) - // Expected: this fixes the problem - expect(await session.hasRedbox()).toBe(false) + // Expected: this fixes the problem + expect(await session.hasRedbox()).toBe(false) - await cleanup() - }) + await cleanup() + }) - // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554150098 - test('syntax > runtime error', async () => { - const { session, cleanup } = await sandbox(next) + // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554150098 + test('syntax > runtime error', async () => { + const { session, cleanup } = await sandbox(next) - // Start here. - await session.patch( - 'index.js', - ` + // Start here. + await session.patch( + 'index.js', + ` import * as React from 'react'; export default function FunctionNamed() { return } ` - ) - // TODO: this acts weird without above step - await session.patch( - 'index.js', - ` + ) + // TODO: this acts weird without above step + await session.patch( + 'index.js', + ` import * as React from 'react'; let i = 0 setInterval(() => { @@ -479,20 +482,20 @@ describe('ReactRefreshLogBox app', () => { return } ` - ) + ) - await new Promise((resolve) => setTimeout(resolve, 1000)) - await session.waitForAndOpenRuntimeError() - if (process.platform === 'win32') { - expect(await session.getRedboxSource()).toMatchSnapshot() - } else { - expect(await session.getRedboxSource()).toMatchSnapshot() - } + await new Promise((resolve) => setTimeout(resolve, 1000)) + await session.waitForAndOpenRuntimeError() + if (process.platform === 'win32') { + expect(await session.getRedboxSource()).toMatchSnapshot() + } else { + expect(await session.getRedboxSource()).toMatchSnapshot() + } - // Make a syntax error. - await session.patch( - 'index.js', - ` + // Make a syntax error. + await session.patch( + 'index.js', + ` import * as React from 'react'; let i = 0 setInterval(() => { @@ -500,35 +503,35 @@ describe('ReactRefreshLogBox app', () => { throw Error('no ' + i) }, 1000) export default function FunctionNamed() {` - ) + ) - await new Promise((resolve) => setTimeout(resolve, 1000)) - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxSource()).toMatchSnapshot() + await new Promise((resolve) => setTimeout(resolve, 1000)) + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() - // Test that runtime error does not take over: - await new Promise((resolve) => setTimeout(resolve, 2000)) - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxSource()).toMatchSnapshot() + // Test that runtime error does not take over: + await new Promise((resolve) => setTimeout(resolve, 2000)) + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() - await cleanup() - }) + await cleanup() + }) - // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554152127 - test('boundaries', async () => { - const { session, cleanup } = await sandbox(next) + // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554152127 + test('boundaries', async () => { + const { session, cleanup } = await sandbox(next) - await session.write( - 'FunctionDefault.js', - ` + await session.write( + 'FunctionDefault.js', + ` export default function FunctionDefault() { returnhello
} ` - ) + ) - await session.patch( - 'index.js', - ` + await session.patch( + 'index.js', + ` import Child from './Child'; export default function Home() { @@ -669,16 +672,16 @@ describe('ReactRefreshLogBox app', () => { ) } ` - ) + ) - expect(await session.hasRedbox()).toBe(false) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('hello') + expect(await session.hasRedbox()).toBe(false) + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('hello') - await session.patch( - 'Child.js', - ` + await session.patch( + 'Child.js', + ` import { Component } from 'react'; export default class ClickCount extends Component { render() { @@ -686,14 +689,14 @@ describe('ReactRefreshLogBox app', () => { } } ` - ) + ) - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxSource()).toMatchSnapshot() + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() - await session.patch( - 'Child.js', - ` + await session.patch( + 'Child.js', + ` import { Component } from 'react'; export default class ClickCount extends Component { render() { @@ -701,23 +704,23 @@ describe('ReactRefreshLogBox app', () => { } } ` - ) + ) - expect(await session.hasRedbox()).toBe(false) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('hello new') + expect(await session.hasRedbox()).toBe(false) + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('hello new') - await cleanup() - }) + await cleanup() + }) - test('css syntax errors', async () => { - const { session, cleanup } = await sandbox(next) + test('css syntax errors', async () => { + const { session, cleanup } = await sandbox(next) - await session.write('index.module.css', `.button {}`) - await session.patch( - 'index.js', - ` + await session.write('index.module.css', `.button {}`) + await session.patch( + 'index.js', + ` import './index.module.css'; export default () => { return ( @@ -727,35 +730,35 @@ describe('ReactRefreshLogBox app', () => { ) } ` - ) - - expect(await session.hasRedbox()).toBe(false) - - // Syntax error - await session.patch('index.module.css', `.button {`) - expect(await session.hasRedbox(true)).toBe(true) - const source = await session.getRedboxSource() - expect(source).toMatch('./index.module.css:1:1') - expect(source).toMatch('Syntax error: ') - expect(source).toMatch('Unclosed block') - expect(source).toMatch('> 1 | .button {') - expect(source).toMatch(' | ^') - - // Not local error - await session.patch('index.module.css', `button {}`) - expect(await session.hasRedbox(true)).toBe(true) - const source2 = await session.getRedboxSource() - expect(source2).toMatchSnapshot() - - await cleanup() - }) + ) - test('logbox: anchors links in error messages', async () => { - const { session, cleanup } = await sandbox(next) + expect(await session.hasRedbox()).toBe(false) - await session.patch( - 'index.js', - ` + // Syntax error + await session.patch('index.module.css', `.button {`) + expect(await session.hasRedbox(true)).toBe(true) + const source = await session.getRedboxSource() + expect(source).toMatch('./index.module.css:1:1') + expect(source).toMatch('Syntax error: ') + expect(source).toMatch('Unclosed block') + expect(source).toMatch('> 1 | .button {') + expect(source).toMatch(' | ^') + + // Not local error + await session.patch('index.module.css', `button {}`) + expect(await session.hasRedbox(true)).toBe(true) + const source2 = await session.getRedboxSource() + expect(source2).toMatchSnapshot() + + await cleanup() + }) + + test('logbox: anchors links in error messages', async () => { + const { session, cleanup } = await sandbox(next) + + await session.patch( + 'index.js', + ` import { useCallback } from 'react' export default function Index() { @@ -769,38 +772,38 @@ describe('ReactRefreshLogBox app', () => { ) } ` - ) - - await session.evaluate(() => document.querySelector('button').click()) - await session.waitForAndOpenRuntimeError() - - const header = await session.getRedboxDescription() - expect(header).toMatchSnapshot() - expect( - await session.evaluate( - () => - document - .querySelector('body > nextjs-portal') - .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') - .length ) - ).toBe(1) - expect( - await session.evaluate( - () => - ( + + await session.evaluate(() => document.querySelector('button').click()) + await session.waitForAndOpenRuntimeError() + + const header = await session.getRedboxDescription() + expect(header).toMatchSnapshot() + expect( + await session.evaluate( + () => document .querySelector('body > nextjs-portal') - .shadowRoot.querySelector( - '#nextjs__container_errors_desc a:nth-of-type(1)' - ) as any - ).href - ) - ).toMatchSnapshot() - - await session.patch( - 'index.js', - ` + .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') + .length + ) + ).toBe(1) + expect( + await session.evaluate( + () => + ( + document + .querySelector('body > nextjs-portal') + .shadowRoot.querySelector( + '#nextjs__container_errors_desc a:nth-of-type(1)' + ) as any + ).href + ) + ).toMatchSnapshot() + + await session.patch( + 'index.js', + ` import { useCallback } from 'react' export default function Index() { @@ -814,38 +817,38 @@ describe('ReactRefreshLogBox app', () => { ) } ` - ) - - await session.evaluate(() => document.querySelector('button').click()) - await session.waitForAndOpenRuntimeError() - - const header2 = await session.getRedboxDescription() - expect(header2).toMatchSnapshot() - expect( - await session.evaluate( - () => - document - .querySelector('body > nextjs-portal') - .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') - .length ) - ).toBe(1) - expect( - await session.evaluate( - () => - ( + + await session.evaluate(() => document.querySelector('button').click()) + await session.waitForAndOpenRuntimeError() + + const header2 = await session.getRedboxDescription() + expect(header2).toMatchSnapshot() + expect( + await session.evaluate( + () => document .querySelector('body > nextjs-portal') - .shadowRoot.querySelector( - '#nextjs__container_errors_desc a:nth-of-type(1)' - ) as any - ).href - ) - ).toMatchSnapshot() - - await session.patch( - 'index.js', - ` + .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') + .length + ) + ).toBe(1) + expect( + await session.evaluate( + () => + ( + document + .querySelector('body > nextjs-portal') + .shadowRoot.querySelector( + '#nextjs__container_errors_desc a:nth-of-type(1)' + ) as any + ).href + ) + ).toMatchSnapshot() + + await session.patch( + 'index.js', + ` import { useCallback } from 'react' export default function Index() { @@ -859,38 +862,38 @@ describe('ReactRefreshLogBox app', () => { ) } ` - ) - - await session.evaluate(() => document.querySelector('button').click()) - await session.waitForAndOpenRuntimeError() - - const header3 = await session.getRedboxDescription() - expect(header3).toMatchSnapshot() - expect( - await session.evaluate( - () => - document - .querySelector('body > nextjs-portal') - .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') - .length ) - ).toBe(1) - expect( - await session.evaluate( - () => - ( + + await session.evaluate(() => document.querySelector('button').click()) + await session.waitForAndOpenRuntimeError() + + const header3 = await session.getRedboxDescription() + expect(header3).toMatchSnapshot() + expect( + await session.evaluate( + () => document .querySelector('body > nextjs-portal') - .shadowRoot.querySelector( - '#nextjs__container_errors_desc a:nth-of-type(1)' - ) as any - ).href - ) - ).toMatchSnapshot() - - await session.patch( - 'index.js', - ` + .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') + .length + ) + ).toBe(1) + expect( + await session.evaluate( + () => + ( + document + .querySelector('body > nextjs-portal') + .shadowRoot.querySelector( + '#nextjs__container_errors_desc a:nth-of-type(1)' + ) as any + ).href + ) + ).toMatchSnapshot() + + await session.patch( + 'index.js', + ` import { useCallback } from 'react' export default function Index() { @@ -904,59 +907,59 @@ describe('ReactRefreshLogBox app', () => { ) } ` - ) - - await session.evaluate(() => document.querySelector('button').click()) - await session.waitForAndOpenRuntimeError() - - const header4 = await session.getRedboxDescription() - expect(header4).toMatchInlineSnapshot( - `"Error: multiple http://nextjs.org links http://example.com"` - ) - expect( - await session.evaluate( - () => - document - .querySelector('body > nextjs-portal') - .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') - .length ) - ).toBe(2) - expect( - await session.evaluate( - () => - ( - document - .querySelector('body > nextjs-portal') - .shadowRoot.querySelector( - '#nextjs__container_errors_desc a:nth-of-type(1)' - ) as any - ).href + + await session.evaluate(() => document.querySelector('button').click()) + await session.waitForAndOpenRuntimeError() + + const header4 = await session.getRedboxDescription() + expect(header4).toMatchInlineSnapshot( + `"Error: multiple http://nextjs.org links http://example.com"` ) - ).toMatchSnapshot() - expect( - await session.evaluate( - () => - ( + expect( + await session.evaluate( + () => document .querySelector('body > nextjs-portal') - .shadowRoot.querySelector( - '#nextjs__container_errors_desc a:nth-of-type(2)' - ) as any - ).href - ) - ).toMatchSnapshot() - - await cleanup() - }) + .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') + .length + ) + ).toBe(2) + expect( + await session.evaluate( + () => + ( + document + .querySelector('body > nextjs-portal') + .shadowRoot.querySelector( + '#nextjs__container_errors_desc a:nth-of-type(1)' + ) as any + ).href + ) + ).toMatchSnapshot() + expect( + await session.evaluate( + () => + ( + document + .querySelector('body > nextjs-portal') + .shadowRoot.querySelector( + '#nextjs__container_errors_desc a:nth-of-type(2)' + ) as any + ).href + ) + ).toMatchSnapshot() + + await cleanup() + }) - // TODO-APP: Catch errors that happen before useEffect - test.skip('non-Error errors are handled properly', async () => { - const { session, cleanup } = await sandbox(next) + // TODO-APP: Catch errors that happen before useEffect + test.skip('non-Error errors are handled properly', async () => { + const { session, cleanup } = await sandbox(next) - await session.patch( - 'index.js', - ` + await session.patch( + 'index.js', + ` export default () => { throw {'a': 1, 'b': 'x'}; return ( @@ -964,28 +967,28 @@ describe('ReactRefreshLogBox app', () => { ) } ` - ) + ) - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxDescription()).toMatchInlineSnapshot( - `"Error: {\\"a\\":1,\\"b\\":\\"x\\"}"` - ) + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxDescription()).toMatchInlineSnapshot( + `"Error: {\\"a\\":1,\\"b\\":\\"x\\"}"` + ) - // fix previous error - await session.patch( - 'index.js', - ` + // fix previous error + await session.patch( + 'index.js', + ` export default () => { return (Hello world
} `, - ], - ]) - ) - expect(await session.hasRedbox(true)).toBe(true) - - // Remove error - await session.patch( - 'app/page.js', - ` + ], + ]) + ) + expect(await session.hasRedbox(true)).toBe(true) + + // Remove error + await session.patch( + 'app/page.js', + ` export default function Page() { returnHello world
} ` - ) - expect(await browser.waitForElementByCss('#text').text()).toBe( - 'Hello world' - ) - expect(await session.hasRedbox()).toBe(false) - - // Re-add error - await session.patch( - 'app/page.js', - ` + ) + expect(await browser.waitForElementByCss('#text').text()).toBe( + 'Hello world' + ) + expect(await session.hasRedbox()).toBe(false) + + // Re-add error + await session.patch( + 'app/page.js', + ` export default function Page() { throw new Error('Server component error!') returnHello world
} ` - ) + ) - expect(await session.hasRedbox(true)).toBe(true) + expect(await session.hasRedbox(true)).toBe(true) - await cleanup() + await cleanup() + }) }) -}) +} diff --git a/test/development/acceptance/ReactRefreshLogBox-app-doc.test.ts b/test/development/acceptance/ReactRefreshLogBox-app-doc.test.ts index 755ecdb416d2f..b58f06b0308b1 100644 --- a/test/development/acceptance/ReactRefreshLogBox-app-doc.test.ts +++ b/test/development/acceptance/ReactRefreshLogBox-app-doc.test.ts @@ -1,191 +1,194 @@ import { sandbox } from './helpers' import { createNext } from 'e2e-utils' import { NextInstance } from 'test/lib/next-modes/base' +import { getSnapshotTestDescribe } from 'next-test-utils' -describe('ReactRefreshLogBox', () => { - let next: NextInstance +for (const variant of ['default', 'turbo']) { + getSnapshotTestDescribe(variant)(`ReactRefreshLogBox ${variant}`, () => { + let next: NextInstance - beforeAll(async () => { - next = await createNext({ - files: {}, - skipStart: true, + beforeAll(async () => { + next = await createNext({ + files: {}, + skipStart: true, + }) }) - }) - afterAll(() => next.destroy()) - - test('empty _app shows logbox', async () => { - const { session, cleanup } = await sandbox( - next, - new Map([ - [ - 'pages/_app.js', - ` - - `, - ], - ]) - ) - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxDescription()).toMatchInlineSnapshot( - `"Error: The default export is not a React Component in page: \\"/_app\\""` - ) - - await session.patch( - 'pages/_app.js', - ` - function MyApp({ Component, pageProps }) { - returnindex page
+ } + `, + ], + ]) + ) + expect(await session.hasRedbox(true)).toBe(true) - await cleanup() - }) + const source = await session.getRedboxSource() + expect(source).toMatchSnapshot() - test('Module not found (missing global CSS)', async () => { - const { session, cleanup } = await sandbox( - next, - new Map([ - [ - 'pages/_app.js', - ` - import './non-existent.css' - + await session.patch( + 'pages/_app.js', + ` export default function App({ Component, pageProps }) { returnindex page
- } - `, - ], - ]) - ) - expect(await session.hasRedbox(true)).toBe(true) - - const source = await session.getRedboxSource() - expect(source).toMatchSnapshot() - - await session.patch( - 'pages/_app.js', ` - export default function App({ Component, pageProps }) { - returnindex page
{ @@ -36,21 +37,21 @@ describe('ReactRefreshLogBox', () => { ) } ` - ) - await session.evaluate(() => document.querySelector('a').click()) + ) + await session.evaluate(() => document.querySelector('a').click()) - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxSource()).toMatchSnapshot() + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() - await cleanup() - }) + await cleanup() + }) - test('logbox: can recover from a syntax error without losing state', async () => { - const { session, cleanup } = await sandbox(next) + test('logbox: can recover from a syntax error without losing state', async () => { + const { session, cleanup } = await sandbox(next) - await session.patch( - 'index.js', - ` + await session.patch( + 'index.js', + ` import { useCallback, useState } from 'react' export default function Index() { @@ -64,21 +65,21 @@ describe('ReactRefreshLogBox', () => { ) } ` - ) + ) - await session.evaluate(() => document.querySelector('button').click()) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('1') + await session.evaluate(() => document.querySelector('button').click()) + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('1') - await session.patch('index.js', `export default () =>Hello
; } ` - ) + ) - await session.patch( - 'index.js', - ` + await session.patch( + 'index.js', + ` import Child from './child' export default function Index() { @@ -201,51 +202,51 @@ describe('ReactRefreshLogBox', () => { ) } ` - ) + ) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('Hello') + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('Hello') - await session.patch( - 'child.js', - ` + 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()).toMatchSnapshot() + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() - const didNotReload = await session.patch( - 'child.js', - ` + const didNotReload = await session.patch( + 'child.js', + ` export default function Child() { returnHello
; } ` - ) + ) - expect(didNotReload).toBe(true) - expect(await session.hasRedbox()).toBe(false) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('Hello') + expect(didNotReload).toBe(true) + expect(await session.hasRedbox()).toBe(false) + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('Hello') - await cleanup() - }) + await cleanup() + }) - // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554137262 - test('render error not shown right after syntax error', async () => { - const { session, cleanup } = await sandbox(next) + // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554137262 + test('render error not shown right after syntax error', async () => { + const { session, cleanup } = await sandbox(next) - // Starting here: - await session.patch( - 'index.js', - ` + // Starting here: + await session.patch( + 'index.js', + ` import * as React from 'react'; class ClassDefault extends React.Component { render() { @@ -255,16 +256,16 @@ describe('ReactRefreshLogBox', () => { export default ClassDefault; ` - ) + ) - expect( - await session.evaluate(() => document.querySelector('h1').textContent) - ).toBe('Default Export') + expect( + await session.evaluate(() => document.querySelector('h1').textContent) + ).toBe('Default Export') - // Break it with a syntax error: - await session.patch( - 'index.js', - ` + // Break it with a syntax error: + await session.patch( + 'index.js', + ` import * as React from 'react'; class ClassDefault extends React.Component { @@ -275,13 +276,13 @@ describe('ReactRefreshLogBox', () => { export default ClassDefault; ` - ) - expect(await session.hasRedbox(true)).toBe(true) + ) + expect(await session.hasRedbox(true)).toBe(true) - // Now change the code to introduce a runtime error without fixing the syntax error: - await session.patch( - 'index.js', - ` + // Now change the code to introduce a runtime error without fixing the syntax error: + await session.patch( + 'index.js', + ` import * as React from 'react'; class ClassDefault extends React.Component { @@ -293,13 +294,13 @@ describe('ReactRefreshLogBox', () => { export default ClassDefault; ` - ) - expect(await session.hasRedbox(true)).toBe(true) + ) + expect(await session.hasRedbox(true)).toBe(true) - // Now fix the syntax error: - await session.patch( - 'index.js', - ` + // Now fix the syntax error: + await session.patch( + 'index.js', + ` import * as React from 'react'; class ClassDefault extends React.Component { @@ -311,22 +312,22 @@ describe('ReactRefreshLogBox', () => { export default ClassDefault; ` - ) - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxSource()).toMatchSnapshot() + ) + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() - await cleanup() - }) + await cleanup() + }) - // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554137807 - test('module init error not shown', async () => { - // Start here: - const { session, cleanup } = await sandbox(next) + // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554137807 + test('module init error not shown', async () => { + // Start here: + const { session, cleanup } = await sandbox(next) - // We start here. - await session.patch( - 'index.js', - ` + // We start here. + await session.patch( + 'index.js', + ` import * as React from 'react'; class ClassDefault extends React.Component { render() { @@ -335,16 +336,16 @@ describe('ReactRefreshLogBox', () => { } export default ClassDefault; ` - ) + ) - expect( - await session.evaluate(() => document.querySelector('h1').textContent) - ).toBe('Default Export') + expect( + await session.evaluate(() => document.querySelector('h1').textContent) + ).toBe('Default Export') - // Add a throw in module init phase: - await session.patch( - 'index.js', - ` + // Add a throw in module init phase: + await session.patch( + 'index.js', + ` // top offset for snapshot import * as React from 'react'; throw new Error('no') @@ -355,22 +356,22 @@ describe('ReactRefreshLogBox', () => { } export default ClassDefault; ` - ) + ) - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxSource()).toMatchSnapshot() + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() - await cleanup() - }) + await cleanup() + }) - // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554144016 - test('stuck error', async () => { - const { session, cleanup } = await sandbox(next) + // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554144016 + test('stuck error', async () => { + const { session, cleanup } = await sandbox(next) - // We start here. - await session.patch( - 'index.js', - ` + // We start here. + await session.patch( + 'index.js', + ` import * as React from 'react'; function FunctionDefault() { @@ -379,23 +380,23 @@ describe('ReactRefreshLogBox', () => { export default FunctionDefault; ` - ) + ) - // We add a new file. Let's call it Foo.js. - await session.write( - 'Foo.js', - ` + // We add a new file. Let's call it Foo.js. + await session.write( + 'Foo.js', + ` // intentionally skips export export default function Foo() { return React.createElement('h1', null, 'Foo'); } ` - ) + ) - // We edit our first file to use it. - await session.patch( - 'index.js', - ` + // We edit our first file to use it. + await session.patch( + 'index.js', + ` import * as React from 'react'; import Foo from './Foo'; function FunctionDefault() { @@ -403,48 +404,48 @@ describe('ReactRefreshLogBox', () => { } export default FunctionDefault; ` - ) + ) - // We get an error because Foo didn't import React. Fair. - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxSource()).toMatchSnapshot() + // We get an error because Foo didn't import React. Fair. + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() - // Let's add that to Foo. - await session.patch( - 'Foo.js', - ` + // Let's add that to Foo. + await session.patch( + 'Foo.js', + ` import * as React from 'react'; export default function Foo() { return React.createElement('h1', null, 'Foo'); } ` - ) + ) - // Expected: this fixes the problem - expect(await session.hasRedbox()).toBe(false) + // Expected: this fixes the problem + expect(await session.hasRedbox()).toBe(false) - await cleanup() - }) + await cleanup() + }) - // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554150098 - test('syntax > runtime error', async () => { - const { session, cleanup } = await sandbox(next) + // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554150098 + test('syntax > runtime error', async () => { + const { session, cleanup } = await sandbox(next) - // Start here. - await session.patch( - 'index.js', - ` + // Start here. + await session.patch( + 'index.js', + ` import * as React from 'react'; export default function FunctionNamed() { return } ` - ) - // TODO: this acts weird without above step - await session.patch( - 'index.js', - ` + ) + // TODO: this acts weird without above step + await session.patch( + 'index.js', + ` import * as React from 'react'; let i = 0 setInterval(() => { @@ -455,20 +456,20 @@ describe('ReactRefreshLogBox', () => { return } ` - ) - - await new Promise((resolve) => setTimeout(resolve, 1000)) - expect(await session.hasRedbox(true)).toBe(true) - if (process.platform === 'win32') { - expect(await session.getRedboxSource()).toMatchSnapshot() - } else { - expect(await session.getRedboxSource()).toMatchSnapshot() - } + ) - // Make a syntax error. - await session.patch( - 'index.js', - ` + await new Promise((resolve) => setTimeout(resolve, 1000)) + expect(await session.hasRedbox(true)).toBe(true) + if (process.platform === 'win32') { + expect(await session.getRedboxSource()).toMatchSnapshot() + } else { + expect(await session.getRedboxSource()).toMatchSnapshot() + } + + // Make a syntax error. + await session.patch( + 'index.js', + ` import * as React from 'react'; let i = 0 setInterval(() => { @@ -476,35 +477,35 @@ describe('ReactRefreshLogBox', () => { throw Error('no ' + i) }, 1000) export default function FunctionNamed() {` - ) + ) - await new Promise((resolve) => setTimeout(resolve, 1000)) - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxSource()).toMatchSnapshot() + await new Promise((resolve) => setTimeout(resolve, 1000)) + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() - // Test that runtime error does not take over: - await new Promise((resolve) => setTimeout(resolve, 2000)) - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxSource()).toMatchSnapshot() + // Test that runtime error does not take over: + await new Promise((resolve) => setTimeout(resolve, 2000)) + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() - await cleanup() - }) + await cleanup() + }) - // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554152127 - test('boundaries', async () => { - const { session, cleanup } = await sandbox(next) + // https://github.com/pmmmwh/react-refresh-webpack-plugin/pull/3#issuecomment-554152127 + test('boundaries', async () => { + const { session, cleanup } = await sandbox(next) - await session.write( - 'FunctionDefault.js', - ` + await session.write( + 'FunctionDefault.js', + ` export default function FunctionDefault() { returnhello
} ` - ) + ) - await session.patch( - 'index.js', - ` + await session.patch( + 'index.js', + ` import Child from './Child'; export default function Home() { @@ -645,16 +646,16 @@ describe('ReactRefreshLogBox', () => { ) } ` - ) + ) - expect(await session.hasRedbox()).toBe(false) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('hello') + expect(await session.hasRedbox()).toBe(false) + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('hello') - await session.patch( - 'Child.js', - ` + await session.patch( + 'Child.js', + ` import { Component } from 'react'; export default class ClickCount extends Component { render() { @@ -662,14 +663,14 @@ describe('ReactRefreshLogBox', () => { } } ` - ) + ) - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxSource()).toMatchSnapshot() + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxSource()).toMatchSnapshot() - await session.patch( - 'Child.js', - ` + await session.patch( + 'Child.js', + ` import { Component } from 'react'; export default class ClickCount extends Component { render() { @@ -677,23 +678,23 @@ describe('ReactRefreshLogBox', () => { } } ` - ) + ) - expect(await session.hasRedbox()).toBe(false) - expect( - await session.evaluate(() => document.querySelector('p').textContent) - ).toBe('hello new') + expect(await session.hasRedbox()).toBe(false) + expect( + await session.evaluate(() => document.querySelector('p').textContent) + ).toBe('hello new') - await cleanup() - }) + await cleanup() + }) - test('css syntax errors', async () => { - const { session, cleanup } = await sandbox(next) + test('css syntax errors', async () => { + const { session, cleanup } = await sandbox(next) - await session.write('index.module.css', `.button {}`) - await session.patch( - 'index.js', - ` + await session.write('index.module.css', `.button {}`) + await session.patch( + 'index.js', + ` import './index.module.css'; export default () => { return ( @@ -703,35 +704,35 @@ describe('ReactRefreshLogBox', () => { ) } ` - ) - - expect(await session.hasRedbox()).toBe(false) - - // Syntax error - await session.patch('index.module.css', `.button {`) - expect(await session.hasRedbox(true)).toBe(true) - const source = await session.getRedboxSource() - expect(source).toMatch('./index.module.css:1:1') - expect(source).toMatch('Syntax error: ') - expect(source).toMatch('Unclosed block') - expect(source).toMatch('> 1 | .button {') - expect(source).toMatch(' | ^') - - // Not local error - await session.patch('index.module.css', `button {}`) - expect(await session.hasRedbox(true)).toBe(true) - const source2 = await session.getRedboxSource() - expect(source2).toMatchSnapshot() - - await cleanup() - }) + ) - test('logbox: anchors links in error messages', async () => { - const { session, cleanup } = await sandbox(next) + expect(await session.hasRedbox()).toBe(false) + + // Syntax error + await session.patch('index.module.css', `.button {`) + expect(await session.hasRedbox(true)).toBe(true) + const source = await session.getRedboxSource() + expect(source).toMatch('./index.module.css:1:1') + expect(source).toMatch('Syntax error: ') + expect(source).toMatch('Unclosed block') + expect(source).toMatch('> 1 | .button {') + expect(source).toMatch(' | ^') + + // Not local error + await session.patch('index.module.css', `button {}`) + expect(await session.hasRedbox(true)).toBe(true) + const source2 = await session.getRedboxSource() + expect(source2).toMatchSnapshot() + + await cleanup() + }) - await session.patch( - 'index.js', - ` + test('logbox: anchors links in error messages', async () => { + const { session, cleanup } = await sandbox(next) + + await session.patch( + 'index.js', + ` import { useCallback } from 'react' export default function Index() { @@ -745,39 +746,39 @@ describe('ReactRefreshLogBox', () => { ) } ` - ) - - expect(await session.hasRedbox()).toBe(false) - await session.evaluate(() => document.querySelector('button').click()) - expect(await session.hasRedbox(true)).toBe(true) - - const header = await session.getRedboxDescription() - expect(header).toMatchSnapshot() - expect( - await session.evaluate( - () => - document - .querySelector('body > nextjs-portal') - .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') - .length ) - ).toBe(1) - expect( - await session.evaluate( - () => - ( + + expect(await session.hasRedbox()).toBe(false) + await session.evaluate(() => document.querySelector('button').click()) + expect(await session.hasRedbox(true)).toBe(true) + + const header = await session.getRedboxDescription() + expect(header).toMatchSnapshot() + expect( + await session.evaluate( + () => document .querySelector('body > nextjs-portal') - .shadowRoot.querySelector( - '#nextjs__container_errors_desc a:nth-of-type(1)' - ) as any - ).href - ) - ).toMatchSnapshot() - - await session.patch( - 'index.js', - ` + .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') + .length + ) + ).toBe(1) + expect( + await session.evaluate( + () => + ( + document + .querySelector('body > nextjs-portal') + .shadowRoot.querySelector( + '#nextjs__container_errors_desc a:nth-of-type(1)' + ) as any + ).href + ) + ).toMatchSnapshot() + + await session.patch( + 'index.js', + ` import { useCallback } from 'react' export default function Index() { @@ -791,39 +792,39 @@ describe('ReactRefreshLogBox', () => { ) } ` - ) - - expect(await session.hasRedbox()).toBe(false) - await session.evaluate(() => document.querySelector('button').click()) - expect(await session.hasRedbox(true)).toBe(true) - - const header2 = await session.getRedboxDescription() - expect(header2).toMatchSnapshot() - expect( - await session.evaluate( - () => - document - .querySelector('body > nextjs-portal') - .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') - .length ) - ).toBe(1) - expect( - await session.evaluate( - () => - ( + + expect(await session.hasRedbox()).toBe(false) + await session.evaluate(() => document.querySelector('button').click()) + expect(await session.hasRedbox(true)).toBe(true) + + const header2 = await session.getRedboxDescription() + expect(header2).toMatchSnapshot() + expect( + await session.evaluate( + () => document .querySelector('body > nextjs-portal') - .shadowRoot.querySelector( - '#nextjs__container_errors_desc a:nth-of-type(1)' - ) as any - ).href - ) - ).toMatchSnapshot() - - await session.patch( - 'index.js', - ` + .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') + .length + ) + ).toBe(1) + expect( + await session.evaluate( + () => + ( + document + .querySelector('body > nextjs-portal') + .shadowRoot.querySelector( + '#nextjs__container_errors_desc a:nth-of-type(1)' + ) as any + ).href + ) + ).toMatchSnapshot() + + await session.patch( + 'index.js', + ` import { useCallback } from 'react' export default function Index() { @@ -837,39 +838,39 @@ describe('ReactRefreshLogBox', () => { ) } ` - ) - - expect(await session.hasRedbox()).toBe(false) - await session.evaluate(() => document.querySelector('button').click()) - expect(await session.hasRedbox(true)).toBe(true) - - const header3 = await session.getRedboxDescription() - expect(header3).toMatchSnapshot() - expect( - await session.evaluate( - () => - document - .querySelector('body > nextjs-portal') - .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') - .length ) - ).toBe(1) - expect( - await session.evaluate( - () => - ( + + expect(await session.hasRedbox()).toBe(false) + await session.evaluate(() => document.querySelector('button').click()) + expect(await session.hasRedbox(true)).toBe(true) + + const header3 = await session.getRedboxDescription() + expect(header3).toMatchSnapshot() + expect( + await session.evaluate( + () => document .querySelector('body > nextjs-portal') - .shadowRoot.querySelector( - '#nextjs__container_errors_desc a:nth-of-type(1)' - ) as any - ).href - ) - ).toMatchSnapshot() - - await session.patch( - 'index.js', - ` + .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') + .length + ) + ).toBe(1) + expect( + await session.evaluate( + () => + ( + document + .querySelector('body > nextjs-portal') + .shadowRoot.querySelector( + '#nextjs__container_errors_desc a:nth-of-type(1)' + ) as any + ).href + ) + ).toMatchSnapshot() + + await session.patch( + 'index.js', + ` import { useCallback } from 'react' export default function Index() { @@ -883,59 +884,59 @@ describe('ReactRefreshLogBox', () => { ) } ` - ) - - expect(await session.hasRedbox()).toBe(false) - await session.evaluate(() => document.querySelector('button').click()) - expect(await session.hasRedbox(true)).toBe(true) - - const header4 = await session.getRedboxDescription() - expect(header4).toMatchInlineSnapshot( - `"Error: multiple http://nextjs.org links http://example.com"` - ) - expect( - await session.evaluate( - () => - document - .querySelector('body > nextjs-portal') - .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') - .length ) - ).toBe(2) - expect( - await session.evaluate( - () => - ( - document - .querySelector('body > nextjs-portal') - .shadowRoot.querySelector( - '#nextjs__container_errors_desc a:nth-of-type(1)' - ) as any - ).href + + expect(await session.hasRedbox()).toBe(false) + await session.evaluate(() => document.querySelector('button').click()) + expect(await session.hasRedbox(true)).toBe(true) + + const header4 = await session.getRedboxDescription() + expect(header4).toMatchInlineSnapshot( + `"Error: multiple http://nextjs.org links http://example.com"` ) - ).toMatchSnapshot() - expect( - await session.evaluate( - () => - ( + expect( + await session.evaluate( + () => document .querySelector('body > nextjs-portal') - .shadowRoot.querySelector( - '#nextjs__container_errors_desc a:nth-of-type(2)' - ) as any - ).href - ) - ).toMatchSnapshot() - - await cleanup() - }) + .shadowRoot.querySelectorAll('#nextjs__container_errors_desc a') + .length + ) + ).toBe(2) + expect( + await session.evaluate( + () => + ( + document + .querySelector('body > nextjs-portal') + .shadowRoot.querySelector( + '#nextjs__container_errors_desc a:nth-of-type(1)' + ) as any + ).href + ) + ).toMatchSnapshot() + expect( + await session.evaluate( + () => + ( + document + .querySelector('body > nextjs-portal') + .shadowRoot.querySelector( + '#nextjs__container_errors_desc a:nth-of-type(2)' + ) as any + ).href + ) + ).toMatchSnapshot() + + await cleanup() + }) - test('non-Error errors are handled properly', async () => { - const { session, cleanup } = await sandbox(next) + test('non-Error errors are handled properly', async () => { + const { session, cleanup } = await sandbox(next) - await session.patch( - 'index.js', - ` + await session.patch( + 'index.js', + ` export default () => { throw {'a': 1, 'b': 'x'}; return ( @@ -943,30 +944,30 @@ describe('ReactRefreshLogBox', () => { ) } ` - ) + ) - expect(await session.hasRedbox(true)).toBe(true) - expect(await session.getRedboxDescription()).toMatchInlineSnapshot( - `"Error: {\\"a\\":1,\\"b\\":\\"x\\"}"` - ) + expect(await session.hasRedbox(true)).toBe(true) + expect(await session.getRedboxDescription()).toMatchInlineSnapshot( + `"Error: {\\"a\\":1,\\"b\\":\\"x\\"}"` + ) - // fix previous error - await session.patch( - 'index.js', - ` + // fix previous error + await session.patch( + 'index.js', + ` export default () => { return (