Make sure to handle // during hydration (#11788)
* Make sure to handle // during hydration * Add test for navigating from // URL
This commit is contained in:
parent
ec26b1bba3
commit
eb367db9d1
3 changed files with 68 additions and 18 deletions
|
@ -226,13 +226,17 @@ export default class Router implements BaseRouter {
|
|||
this.isFallback = isFallback
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
// in order for `e.state` to work on the `onpopstate` event
|
||||
// we have to register the initial route upon initialization
|
||||
this.changeState(
|
||||
'replaceState',
|
||||
formatWithValidation({ pathname, query }),
|
||||
as
|
||||
)
|
||||
// make sure "as" doesn't start with double slashes or else it can
|
||||
// throw an error as it's considered invalid
|
||||
if (as.substr(0, 2) !== '//') {
|
||||
// in order for `e.state` to work on the `onpopstate` event
|
||||
// we have to register the initial route upon initialization
|
||||
this.changeState(
|
||||
'replaceState',
|
||||
formatWithValidation({ pathname, query }),
|
||||
as
|
||||
)
|
||||
}
|
||||
|
||||
window.addEventListener('popstate', this.onPopState)
|
||||
}
|
||||
|
|
6
test/integration/hydration/pages/404.js
Normal file
6
test/integration/hydration/pages/404.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
export default () => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.didHydrate = true
|
||||
}
|
||||
return 'oops thats a 404'
|
||||
}
|
|
@ -3,24 +3,64 @@
|
|||
import path from 'path'
|
||||
import fs from 'fs-extra'
|
||||
import webdriver from 'next-webdriver'
|
||||
import { nextBuild, nextStart, findPort, killApp } from 'next-test-utils'
|
||||
import {
|
||||
nextBuild,
|
||||
nextStart,
|
||||
findPort,
|
||||
killApp,
|
||||
launchApp,
|
||||
check,
|
||||
} from 'next-test-utils'
|
||||
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 1
|
||||
const appDir = path.join(__dirname, '..')
|
||||
let app
|
||||
let appPort
|
||||
|
||||
describe('Hydration', () => {
|
||||
beforeAll(async () => {
|
||||
await fs.remove(path.join(appDir, '.next'))
|
||||
await nextBuild(appDir)
|
||||
appPort = await findPort()
|
||||
app = await nextStart(appDir, appPort)
|
||||
})
|
||||
afterAll(() => killApp(app))
|
||||
|
||||
it('Hydrates correctly', async () => {
|
||||
const runTests = () => {
|
||||
it('hydrates correctly for normal page', async () => {
|
||||
const browser = await webdriver(appPort, '/')
|
||||
expect(await browser.eval('window.didHydrate')).toBe(true)
|
||||
})
|
||||
|
||||
it('hydrates correctly for //', async () => {
|
||||
const browser = await webdriver(appPort, '//')
|
||||
expect(await browser.eval('window.didHydrate')).toBe(true)
|
||||
})
|
||||
|
||||
it('should be able to navigate after loading //', async () => {
|
||||
const browser = await webdriver(appPort, '//')
|
||||
await browser.eval('window.beforeNav = true')
|
||||
await browser.eval('window.next.router.push("/details")')
|
||||
await check(
|
||||
() => browser.eval('document.documentElement.innerHTML'),
|
||||
/details/
|
||||
)
|
||||
expect(await browser.eval('window.beforeNav')).toBe(true)
|
||||
})
|
||||
}
|
||||
|
||||
describe('Hydration', () => {
|
||||
describe('dev mode', () => {
|
||||
beforeAll(async () => {
|
||||
await fs.remove(path.join(appDir, '.next'))
|
||||
appPort = await findPort()
|
||||
app = await launchApp(appDir, appPort)
|
||||
})
|
||||
afterAll(() => killApp(app))
|
||||
|
||||
runTests()
|
||||
})
|
||||
|
||||
describe('production mode', () => {
|
||||
beforeAll(async () => {
|
||||
await fs.remove(path.join(appDir, '.next'))
|
||||
await nextBuild(appDir)
|
||||
appPort = await findPort()
|
||||
app = await nextStart(appDir, appPort)
|
||||
})
|
||||
afterAll(() => killApp(app))
|
||||
|
||||
runTests()
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue