forked from vercel/next.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add additional pageProps check (vercel#15667)
`pageProps` should always be defined to ensure everything is working as expected although to prevent a breaking change this adds an additional check before attempting to access `pageProps` before hydration. It also adds tests to prevent regressing on this Closes: vercel#15647
- Loading branch information
1 parent
47661ad
commit 85038cf
Showing
6 changed files
with
172 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
function App({ Component, pageProps }) { | ||
return <Component {...pageProps} /> | ||
} | ||
|
||
if (typeof window !== 'undefined') { | ||
window.uncaughtErrors = [] | ||
window.addEventListener('error', (err) => { | ||
window.uncaughtErrors.push(err) | ||
}) | ||
window.addEventListener('unhandledrejection', (err) => { | ||
window.uncaughtErrors.push(err) | ||
}) | ||
} | ||
|
||
App.getInitialProps = async ({ Component, ctx }) => { | ||
const props = {} | ||
|
||
if (Component.getInitialProps) { | ||
props.initialProps = await Component.getInitialProps(ctx) | ||
} | ||
return props | ||
} | ||
|
||
export default App |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export default function Gsp() { | ||
return <p id="gsp">getStaticProps</p> | ||
} | ||
|
||
export const getStaticProps = () => { | ||
return { | ||
props: { | ||
hello: 'world', | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export default function Gssp() { | ||
return <p id="gssp">getServerSideProps</p> | ||
} | ||
|
||
export const getServerSideProps = () => { | ||
return { | ||
props: { | ||
hello: 'world', | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import Link from 'next/link' | ||
|
||
export default function Index() { | ||
return ( | ||
<> | ||
<p id="index">index</p> | ||
<Link href="/gsp"> | ||
<a id="to-gsp">to gsp</a> | ||
</Link> | ||
<br /> | ||
<Link href="/gssp"> | ||
<a id="to-gssp">to gssp</a> | ||
</Link> | ||
<br /> | ||
<Link href="/non-existent"> | ||
<a id="to-404">to non-existent</a> | ||
</Link> | ||
<br /> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* eslint-env jest */ | ||
|
||
import { join } from 'path' | ||
import webdriver from 'next-webdriver' | ||
import { | ||
nextBuild, | ||
nextStart, | ||
findPort, | ||
killApp, | ||
launchApp, | ||
} from 'next-test-utils' | ||
|
||
jest.setTimeout(1000 * 60 * 1) | ||
const appDir = join(__dirname, '..') | ||
let app | ||
let appPort | ||
|
||
const runTests = () => { | ||
it('should load auto-export page correctly', async () => { | ||
const browser = await webdriver(appPort, '/') | ||
expect(await browser.elementByCss('#index').text()).toBe('index') | ||
expect(await browser.eval('window.uncaughtErrors')).toEqual([]) | ||
}) | ||
|
||
it('should load getStaticProps page correctly', async () => { | ||
const browser = await webdriver(appPort, '/gsp') | ||
expect(await browser.elementByCss('#gsp').text()).toBe('getStaticProps') | ||
expect(await browser.eval('window.uncaughtErrors')).toEqual([]) | ||
}) | ||
|
||
it('should load getServerSideProps page correctly', async () => { | ||
const browser = await webdriver(appPort, '/gssp') | ||
expect(await browser.elementByCss('#gssp').text()).toBe( | ||
'getServerSideProps' | ||
) | ||
expect(await browser.eval('window.uncaughtErrors')).toEqual([]) | ||
}) | ||
|
||
it('should load 404 page correctly', async () => { | ||
const browser = await webdriver(appPort, '/non-existent') | ||
expect(await browser.elementByCss('h2').text()).toBe( | ||
'An unexpected error has occurred.' | ||
) | ||
expect(await browser.eval('window.uncaughtErrors')).toEqual([]) | ||
}) | ||
|
||
it('should navigate between pages correctly', async () => { | ||
const browser = await webdriver(appPort, '/') | ||
|
||
await browser.eval('window.beforeNav = "hi"') | ||
await browser.elementByCss('#to-gsp').click() | ||
await browser.waitForElementByCss('#gsp') | ||
|
||
expect(await browser.elementByCss('#gsp').text()).toBe('getStaticProps') | ||
expect(await browser.eval('window.beforeNav')).toBe('hi') | ||
|
||
await browser.back() | ||
await browser.waitForElementByCss('#index') | ||
expect(await browser.eval('window.beforeNav')).toBe('hi') | ||
|
||
await browser.elementByCss('#to-gssp').click() | ||
await browser.waitForElementByCss('#gssp') | ||
|
||
expect(await browser.elementByCss('#gssp').text()).toBe( | ||
'getServerSideProps' | ||
) | ||
expect(await browser.eval('window.beforeNav')).toBe('hi') | ||
|
||
await browser.back() | ||
await browser.waitForElementByCss('#index') | ||
expect(await browser.eval('window.beforeNav')).toBe('hi') | ||
|
||
await browser.elementByCss('#to-404').click() | ||
await browser.waitForElementByCss('h2') | ||
expect(await browser.eval('window.beforeNav')).toBe(null) | ||
expect(await browser.elementByCss('h2').text()).toBe( | ||
'An unexpected error has occurred.' | ||
) | ||
expect(await browser.eval('window.uncaughtErrors')).toEqual([]) | ||
}) | ||
} | ||
|
||
describe('Error no pageProps', () => { | ||
describe('dev mode', () => { | ||
beforeAll(async () => { | ||
appPort = await findPort() | ||
app = await launchApp(appDir, appPort) | ||
}) | ||
afterAll(() => killApp(app)) | ||
|
||
runTests() | ||
}) | ||
|
||
describe('production mode', () => { | ||
beforeAll(async () => { | ||
await nextBuild(appDir) | ||
appPort = await findPort() | ||
app = await nextStart(appDir, appPort) | ||
}) | ||
afterAll(() => killApp(app)) | ||
|
||
runTests() | ||
}) | ||
}) |