1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00
next.js/test/integration/basic/test/error-recovery.js
Tim Neutkens 9ffd23eeef
Replace pages-plugin with loader (#5994)
* Remove unused argument

* Replace pages-plugin with loader

* Add loader-utils types

* Remove logs

* Bring back previous deposal behavior

* Remove console.log

* Remove webpack/utils as it’s no longer in use

* Remove hot-self-accept-loader

* Error Recovery tests

* Make hotSelfAccept a noop default loader

* Fix windows deleted/added

* Remove logging

* Remove unused variables

* Remove log

* Simplify entrypoint generation

* Don’t return the function

* Fix _app test

* Remove code that’s always true

* Move aliases to constants

* Use alias

* Join pages alias in reduce

* Default pages differently

* Loop over pages instead of manually defining

* Move entry generation into common function

* Update packages/next/build/webpack/loaders/next-client-pages-loader.ts

Co-Authored-By: timneutkens <tim@timneutkens.nl>

* Update packages/next/build/webpack/loaders/next-client-pages-loader.ts
2019-01-08 23:10:32 +01:00

369 lines
10 KiB
JavaScript

/* eslint-env jest */
import webdriver from 'next-webdriver'
import { join } from 'path'
import { check, File, waitFor, getReactErrorOverlayContent, getBrowserBodyText } from 'next-test-utils'
export default (context, renderViaHTTP) => {
describe('Error Recovery', () => {
it('should recover from 404 after a page has been added', async () => {
let browser
const newPage = new File(join(__dirname, '../', 'pages', 'hmr', 'new-page.js'))
try {
browser = await webdriver(context.appPort, '/hmr/new-page')
expect(await browser.elementByCss('body').text()).toMatch(/This page could not be found/)
// Add the page
newPage.write('export default () => (<div id="new-page">the-new-page</div>)')
await check(
() => getBrowserBodyText(browser),
/the-new-page/
)
newPage.delete()
await check(
() => getBrowserBodyText(browser),
/This page could not be found/
)
} catch (err) {
newPage.delete()
throw err
} finally {
if (browser) {
browser.close()
}
}
})
it('should have installed the react-overlay-editor editor handler', async () => {
let browser
const aboutPage = new File(join(__dirname, '../', 'pages', 'hmr', 'about.js'))
aboutPage.replace('</div>', 'div')
try {
browser = await webdriver(context.appPort, '/hmr/about')
// react-error-overlay uses the following inline style if an editorHandler is installed
expect(await getReactErrorOverlayContent(browser)).toMatch(/style="cursor: pointer;"/)
aboutPage.restore()
await check(
() => getBrowserBodyText(browser),
/This is the about page/
)
} catch (err) {
aboutPage.restore()
if (browser) {
await check(
() => getBrowserBodyText(browser),
/This is the about page/
)
}
throw err
} finally {
if (browser) {
browser.close()
}
}
})
it('should detect syntax errors and recover', async () => {
let browser
const aboutPage = new File(join(__dirname, '../', 'pages', 'hmr', 'about.js'))
try {
browser = await webdriver(context.appPort, '/hmr/about')
const text = await browser.elementByCss('p').text()
expect(text).toBe('This is the about page.')
aboutPage.replace('</div>', 'div')
expect(await getReactErrorOverlayContent(browser)).toMatch(/Unterminated JSX contents/)
aboutPage.restore()
await check(
() => getBrowserBodyText(browser),
/This is the about page/
)
} catch (err) {
aboutPage.restore()
if (browser) {
await check(
() => getBrowserBodyText(browser),
/This is the about page/
)
}
throw err
} finally {
if (browser) {
browser.close()
}
}
})
it('should show the error on all pages', async () => {
const aboutPage = new File(join(__dirname, '../', 'pages', 'hmr', 'about.js'))
let browser
try {
await renderViaHTTP('/hmr/about')
aboutPage.replace('</div>', 'div')
browser = await webdriver(context.appPort, '/hmr/contact')
expect(await getReactErrorOverlayContent(browser)).toMatch(/Unterminated JSX contents/)
aboutPage.restore()
await check(
() => getBrowserBodyText(browser),
/This is the contact page/
)
} catch (err) {
aboutPage.restore()
if (browser) {
await check(
() => getBrowserBodyText(browser),
/This is the contact page/
)
}
throw err
} finally {
aboutPage.restore()
if (browser) {
browser.close()
}
}
})
it('should detect runtime errors on the module scope', async () => {
let browser
const aboutPage = new File(join(__dirname, '../', 'pages', 'hmr', 'about.js'))
try {
browser = await webdriver(context.appPort, '/hmr/about')
const text = await browser
.elementByCss('p').text()
expect(text).toBe('This is the about page.')
aboutPage.replace('export', 'aa=20;\nexport')
expect(await getReactErrorOverlayContent(browser)).toMatch(/aa is not defined/)
aboutPage.restore()
await check(
() => getBrowserBodyText(browser),
/This is the about page/
)
} finally {
aboutPage.restore()
if (browser) {
browser.close()
}
}
})
it('should recover from errors in the render function', async () => {
let browser
const aboutPage = new File(join(__dirname, '../', 'pages', 'hmr', 'about.js'))
try {
browser = await webdriver(context.appPort, '/hmr/about')
const text = await browser.elementByCss('p').text()
expect(text).toBe('This is the about page.')
aboutPage.replace('return', 'throw new Error("an-expected-error");\nreturn')
expect(await getReactErrorOverlayContent(browser)).toMatch(/an-expected-error/)
aboutPage.restore()
await check(
() => getBrowserBodyText(browser),
/This is the about page/
)
} catch (err) {
aboutPage.restore()
if (browser) {
await check(
() => getBrowserBodyText(browser),
/This is the about page/
)
}
throw err
} finally {
if (browser) {
browser.close()
}
}
})
it('should recover after exporting an invalid page', async () => {
let browser
const aboutPage = new File(join(__dirname, '../', 'pages', 'hmr', 'about.js'))
try {
browser = await webdriver(context.appPort, '/hmr/about')
const text = await browser.elementByCss('p').text()
expect(text).toBe('This is the about page.')
aboutPage.replace('export default', 'export default {};\nexport const fn =')
await check(
() => getBrowserBodyText(browser),
/The default export is not a React Component/
)
aboutPage.restore()
await check(
() => getBrowserBodyText(browser),
/This is the about page/
)
} catch (err) {
aboutPage.restore()
if (browser) {
await check(
() => getBrowserBodyText(browser),
/This is the about page/
)
}
throw err
} finally {
if (browser) {
browser.close()
}
}
})
it('should recover after a bad return from the render function', async () => {
let browser
const aboutPage = new File(join(__dirname, '../', 'pages', 'hmr', 'about.js'))
try {
browser = await webdriver(context.appPort, '/hmr/about')
const text = await browser.elementByCss('p').text()
expect(text).toBe('This is the about page.')
aboutPage.replace('export default', 'export default () => /search/;\nexport const fn =')
await check(
() => getBrowserBodyText(browser),
/Objects are not valid as a React child/
)
aboutPage.restore()
await check(
() => getBrowserBodyText(browser),
/This is the about page/
)
} catch (err) {
aboutPage.restore()
if (browser) {
await check(
() => getBrowserBodyText(browser),
/This is the about page/
)
}
throw err
} finally {
if (browser) {
browser.close()
}
}
})
it('should recover from errors in getInitialProps in client', async () => {
let browser
const erroredPage = new File(join(__dirname, '../', 'pages', 'hmr', 'error-in-gip.js'))
try {
browser = await webdriver(context.appPort, '/hmr')
await browser.elementByCss('#error-in-gip-link').click()
expect(await getReactErrorOverlayContent(browser)).toMatch(/an-expected-error-in-gip/)
erroredPage.replace('throw error', 'return {}')
await check(
() => getBrowserBodyText(browser),
/Hello/
)
erroredPage.restore()
await check(
async () => {
await browser.refresh()
const text = await browser.elementByCss('body').text()
if (text.includes('Hello')) {
await waitFor(2000)
throw new Error('waiting')
}
return getReactErrorOverlayContent(browser)
},
/an-expected-error-in-gip/
)
} catch (err) {
erroredPage.restore()
throw err
} finally {
if (browser) {
browser.close()
}
}
})
it('should recover after an error reported via SSR', async () => {
let browser
const erroredPage = new File(join(__dirname, '../', 'pages', 'hmr', 'error-in-gip.js'))
try {
browser = await webdriver(context.appPort, '/hmr/error-in-gip')
expect(await getReactErrorOverlayContent(browser)).toMatch(/an-expected-error-in-gip/)
const erroredPage = new File(join(__dirname, '../', 'pages', 'hmr', 'error-in-gip.js'))
erroredPage.replace('throw error', 'return {}')
await check(
() => getBrowserBodyText(browser),
/Hello/
)
erroredPage.restore()
await check(
async () => {
await browser.refresh()
const text = await getBrowserBodyText(browser)
if (text.includes('Hello')) {
await waitFor(2000)
throw new Error('waiting')
}
return getReactErrorOverlayContent(browser)
},
/an-expected-error-in-gip/
)
} catch (err) {
erroredPage.restore()
throw err
} finally {
if (browser) {
browser.close()
}
}
})
})
}