Set cancelled
property on routeChangeError error (#7790)
* Set `cancelled` property on routeChangeError error * Add route cancellation tests
This commit is contained in:
parent
a7171db2ca
commit
6a35b1d302
5 changed files with 111 additions and 1 deletions
|
@ -587,7 +587,9 @@ export default class Router implements BaseRouter {
|
|||
|
||||
abortComponentLoad(as: string): void {
|
||||
if (this.clc) {
|
||||
Router.events.emit('routeChangeError', new Error('Route Cancelled'), as)
|
||||
const e = new Error('Route Cancelled')
|
||||
;(e as any).cancelled = true
|
||||
Router.events.emit('routeChangeError', e, as)
|
||||
this.clc()
|
||||
this.clc = null
|
||||
}
|
||||
|
|
26
test/integration/route-load-cancel/pages/index.js
Normal file
26
test/integration/route-load-cancel/pages/index.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import React, { useEffect } from 'react'
|
||||
|
||||
export default () => {
|
||||
const router = useRouter()
|
||||
useEffect(() => {
|
||||
router.events.on('routeChangeError', err => {
|
||||
if (err.cancelled) {
|
||||
window.routeCancelled = 'yes'
|
||||
}
|
||||
})
|
||||
|
||||
// Intentionally is not cleaned up
|
||||
}, [])
|
||||
return (
|
||||
<>
|
||||
<Link href='/page1'>
|
||||
<a id='link-1'>Page 1</a>
|
||||
</Link>{' '}
|
||||
<Link href='/page2'>
|
||||
<a id='link-2'>Page 2</a>
|
||||
</Link>
|
||||
</>
|
||||
)
|
||||
}
|
10
test/integration/route-load-cancel/pages/page1.js
Normal file
10
test/integration/route-load-cancel/pages/page1.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
function Page1 () {
|
||||
return <p id='page-text'>1</p>
|
||||
}
|
||||
|
||||
Page1.getInitialProps = async function getInitialProps () {
|
||||
await new Promise(resolve => setTimeout(resolve, 5000))
|
||||
return {}
|
||||
}
|
||||
|
||||
export default Page1
|
5
test/integration/route-load-cancel/pages/page2.js
Normal file
5
test/integration/route-load-cancel/pages/page2.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
function Page2 () {
|
||||
return <p id='page-text'>2</p>
|
||||
}
|
||||
|
||||
export default Page2
|
67
test/integration/route-load-cancel/test/index.test.js
Normal file
67
test/integration/route-load-cancel/test/index.test.js
Normal file
|
@ -0,0 +1,67 @@
|
|||
/* eslint-env jest */
|
||||
/* global jasmine */
|
||||
import webdriver from 'next-webdriver'
|
||||
import { join } from 'path'
|
||||
import {
|
||||
findPort,
|
||||
launchApp,
|
||||
killApp,
|
||||
waitFor,
|
||||
runNextCommand,
|
||||
nextServer,
|
||||
startApp,
|
||||
stopApp
|
||||
} from 'next-test-utils'
|
||||
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5
|
||||
|
||||
let app
|
||||
let appPort
|
||||
let server
|
||||
const appDir = join(__dirname, '../')
|
||||
|
||||
function runTests () {
|
||||
it('should cancel slow page loads on re-navigation', async () => {
|
||||
const browser = await webdriver(appPort, '/')
|
||||
await waitFor(5000)
|
||||
|
||||
await browser.elementByCss('#link-1').click()
|
||||
await waitFor(1000)
|
||||
await browser.elementByCss('#link-2').click()
|
||||
await waitFor(1000)
|
||||
|
||||
const text = await browser.elementByCss('#page-text').text()
|
||||
expect(text).toMatch(/2/)
|
||||
expect(await browser.eval('window.routeCancelled')).toBe('yes')
|
||||
})
|
||||
}
|
||||
|
||||
describe('next/dynamic', () => {
|
||||
describe('dev mode', () => {
|
||||
beforeAll(async () => {
|
||||
appPort = await findPort()
|
||||
app = await launchApp(appDir, appPort)
|
||||
})
|
||||
afterAll(() => killApp(app))
|
||||
|
||||
runTests(true)
|
||||
})
|
||||
|
||||
describe('production mode', () => {
|
||||
beforeAll(async () => {
|
||||
await runNextCommand(['build', appDir])
|
||||
|
||||
app = nextServer({
|
||||
dir: appDir,
|
||||
dev: false,
|
||||
quiet: true
|
||||
})
|
||||
|
||||
server = await startApp(app)
|
||||
appPort = server.address().port
|
||||
})
|
||||
afterAll(() => stopApp(server))
|
||||
|
||||
runTests()
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue