mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Make onClick Link tests more consistent (#4954)
This commit is contained in:
parent
87f5df2454
commit
b7e256ba01
|
@ -8,14 +8,14 @@ export default class BuildManifestPlugin {
|
||||||
apply (compiler: any) {
|
apply (compiler: any) {
|
||||||
compiler.hooks.emit.tapAsync('NextJsBuildManifest', (compilation, callback) => {
|
compiler.hooks.emit.tapAsync('NextJsBuildManifest', (compilation, callback) => {
|
||||||
const {chunks} = compilation
|
const {chunks} = compilation
|
||||||
const assetMap = {pages: {}}
|
const assetMap = {devFiles: [], pages: {}}
|
||||||
|
|
||||||
const mainJsChunk = chunks.find((c) => c.name === CLIENT_STATIC_FILES_RUNTIME_MAIN)
|
const mainJsChunk = chunks.find((c) => c.name === CLIENT_STATIC_FILES_RUNTIME_MAIN)
|
||||||
const mainJsFiles = mainJsChunk && mainJsChunk.files.length > 0 ? mainJsChunk.files.filter((file) => /\.js$/.test(file)) : []
|
const mainJsFiles = mainJsChunk && mainJsChunk.files.length > 0 ? mainJsChunk.files.filter((file) => /\.js$/.test(file)) : []
|
||||||
|
|
||||||
for (const filePath of Object.keys(compilation.assets)) {
|
for (const filePath of Object.keys(compilation.assets)) {
|
||||||
if (/^static\/dll\//.test(filePath)) {
|
if (/^static\/dll\//.test(filePath)) {
|
||||||
mainJsFiles.push(filePath)
|
assetMap.devFiles.push(filePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,11 +199,12 @@ export class NextScript extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { staticMarkup, assetPrefix, __NEXT_DATA__ } = this.context._documentProps
|
const { staticMarkup, assetPrefix, devFiles, __NEXT_DATA__ } = this.context._documentProps
|
||||||
const { page, pathname, buildId } = __NEXT_DATA__
|
const { page, pathname, buildId } = __NEXT_DATA__
|
||||||
const pagePathname = getPagePathname(pathname)
|
const pagePathname = getPagePathname(pathname)
|
||||||
|
|
||||||
return <Fragment>
|
return <Fragment>
|
||||||
|
{devFiles ? devFiles.map((file) => <script src={`${assetPrefix}/_next/${file}`} nonce={this.props.nonce} />) : null}
|
||||||
{staticMarkup ? null : <script nonce={this.props.nonce} dangerouslySetInnerHTML={{
|
{staticMarkup ? null : <script nonce={this.props.nonce} dangerouslySetInnerHTML={{
|
||||||
__html: NextScript.getInlineScriptSource(this.context._documentProps)
|
__html: NextScript.getInlineScriptSource(this.context._documentProps)
|
||||||
}} />}
|
}} />}
|
||||||
|
|
|
@ -84,6 +84,7 @@ async function doRender (req, res, pathname, query, {
|
||||||
const ctx = { err, req, res, pathname, query, asPath }
|
const ctx = { err, req, res, pathname, query, asPath }
|
||||||
const router = new Router(pathname, query, asPath)
|
const router = new Router(pathname, query, asPath)
|
||||||
const props = await loadGetInitialProps(App, {Component, router, ctx})
|
const props = await loadGetInitialProps(App, {Component, router, ctx})
|
||||||
|
const devFiles = buildManifest.devFiles
|
||||||
const files = [
|
const files = [
|
||||||
...new Set([
|
...new Set([
|
||||||
...buildManifest.pages[normalizePagePath(page)],
|
...buildManifest.pages[normalizePagePath(page)],
|
||||||
|
@ -167,6 +168,7 @@ async function doRender (req, res, pathname, query, {
|
||||||
dir,
|
dir,
|
||||||
staticMarkup,
|
staticMarkup,
|
||||||
buildManifest,
|
buildManifest,
|
||||||
|
devFiles,
|
||||||
files,
|
files,
|
||||||
dynamicImports,
|
dynamicImports,
|
||||||
assetPrefix, // We always pass assetPrefix as a top level property since _document needs it to render, even though the client side might not need it
|
assetPrefix, // We always pass assetPrefix as a top level property since _document needs it to render, even though the client side might not need it
|
||||||
|
|
|
@ -38,7 +38,7 @@ export default class extends Component {
|
||||||
<Link href='/nav/as-path' as='/as/path'><a id='as-path-link' style={linkStyle}>As Path</a></Link>
|
<Link href='/nav/as-path' as='/as/path'><a id='as-path-link' style={linkStyle}>As Path</a></Link>
|
||||||
<Link href='/nav/as-path'><a id='as-path-link-no-as' style={linkStyle}>As Path (No as)</a></Link>
|
<Link href='/nav/as-path'><a id='as-path-link-no-as' style={linkStyle}>As Path (No as)</a></Link>
|
||||||
<Link href='/nav/as-path-using-router'><a id='as-path-using-router-link' style={linkStyle}>As Path (Using Router)</a></Link>
|
<Link href='/nav/as-path-using-router'><a id='as-path-using-router-link' style={linkStyle}>As Path (Using Router)</a></Link>
|
||||||
<Link href='/nav/on-click'><a id='on-click-link' style={linkStyle}>A element with onClick</a></Link>
|
<Link href='/nav/on-click?count=1'><a id='on-click-link' style={linkStyle}>A element with onClick</a></Link>
|
||||||
<Link href='/nav/about'><a id='target-link' target='_blank'>A element with target</a></Link>
|
<Link href='/nav/about'><a id='target-link' target='_blank'>A element with target</a></Link>
|
||||||
<button
|
<button
|
||||||
onClick={() => this.visitQueryStringPage()}
|
onClick={() => this.visitQueryStringPage()}
|
||||||
|
|
|
@ -1,26 +1,31 @@
|
||||||
import { Component } from 'react'
|
import { Component } from 'react'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
|
||||||
let count = 0
|
|
||||||
|
|
||||||
export default class OnClick extends Component {
|
export default class OnClick extends Component {
|
||||||
static getInitialProps ({ res }) {
|
static getInitialProps ({ res, query: {count} }) {
|
||||||
if (res) return { count: 0 }
|
return { count: count ? parseInt(count) : 0 }
|
||||||
count += 1
|
}
|
||||||
|
|
||||||
return { count }
|
state = {
|
||||||
|
stateCounter: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
const {stateCounter} = this.state
|
||||||
|
const {count} = this.props
|
||||||
return (
|
return (
|
||||||
<div id='on-click-page'>
|
<div id='on-click-page'>
|
||||||
<Link href='/nav/on-click'>
|
<Link href={`/nav/on-click?count=${count + 1}`} replace>
|
||||||
<a id='on-click-link' onClick={() => ++count}>Self Reload</a>
|
<a id='on-click-link' onClick={() => this.setState({stateCounter: stateCounter + 1})}>Self Reload</a>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href='/nav/on-click'>
|
<Link href='/nav/on-click'>
|
||||||
<a id='on-click-link-prevent-default' onClick={(e) => { e.preventDefault(); ++count }}>Self Reload</a>
|
<a id='on-click-link-prevent-default' onClick={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
this.setState({stateCounter: stateCounter + 1})
|
||||||
|
}}>Self Reload</a>
|
||||||
</Link>
|
</Link>
|
||||||
<p>COUNT: {this.props.count}</p>
|
<p id='query-count'>QUERY COUNT: {count}</p>
|
||||||
|
<p id='state-count'>STATE COUNT: {stateCounter}</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,59 +178,79 @@ export default (context, render) => {
|
||||||
|
|
||||||
describe('with onClick action', () => {
|
describe('with onClick action', () => {
|
||||||
it('should reload the page and perform additional action', async () => {
|
it('should reload the page and perform additional action', async () => {
|
||||||
const browser = await webdriver(context.appPort, '/nav/on-click')
|
let browser
|
||||||
const defaultCount = await browser.elementByCss('p').text()
|
try {
|
||||||
expect(defaultCount).toBe('COUNT: 0')
|
browser = await webdriver(context.appPort, '/nav/on-click')
|
||||||
|
const defaultCountQuery = await browser.elementByCss('#query-count').text()
|
||||||
|
const defaultCountState = await browser.elementByCss('#state-count').text()
|
||||||
|
expect(defaultCountQuery).toBe('QUERY COUNT: 0')
|
||||||
|
expect(defaultCountState).toBe('STATE COUNT: 0')
|
||||||
|
|
||||||
const countAfterClicked = await browser
|
await browser.elementByCss('#on-click-link').click()
|
||||||
.elementByCss('#on-click-link').click()
|
|
||||||
.elementByCss('p').text()
|
|
||||||
|
|
||||||
// counts (one click + onClick handler)
|
const countQueryAfterClicked = await browser.elementByCss('#query-count').text()
|
||||||
expect(countAfterClicked).toBe('COUNT: 2')
|
const countStateAfterClicked = await browser.elementByCss('#state-count').text()
|
||||||
browser.close()
|
expect(countQueryAfterClicked).toBe('QUERY COUNT: 1')
|
||||||
|
expect(countStateAfterClicked).toBe('STATE COUNT: 1')
|
||||||
|
} finally {
|
||||||
|
if (browser) {
|
||||||
|
browser.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not reload if default was prevented', async () => {
|
it('should not reload if default was prevented', async () => {
|
||||||
const browser = await webdriver(context.appPort, '/nav/on-click')
|
let browser
|
||||||
const defaultCount = await browser.elementByCss('p').text()
|
try {
|
||||||
expect(defaultCount).toBe('COUNT: 0')
|
browser = await webdriver(context.appPort, '/nav/on-click')
|
||||||
|
const defaultCountQuery = await browser.elementByCss('#query-count').text()
|
||||||
|
const defaultCountState = await browser.elementByCss('#state-count').text()
|
||||||
|
expect(defaultCountQuery).toBe('QUERY COUNT: 0')
|
||||||
|
expect(defaultCountState).toBe('STATE COUNT: 0')
|
||||||
|
|
||||||
const countAfterClicked = await browser
|
await browser.elementByCss('#on-click-link-prevent-default').click()
|
||||||
.elementByCss('#on-click-link-prevent-default').click()
|
|
||||||
.elementByCss('p').text()
|
|
||||||
|
|
||||||
// counter is increased but there was no reload
|
const countQueryAfterClicked = await browser.elementByCss('#query-count').text()
|
||||||
expect(countAfterClicked).toBe('COUNT: 0')
|
const countStateAfterClicked = await browser.elementByCss('#state-count').text()
|
||||||
|
expect(countQueryAfterClicked).toBe('QUERY COUNT: 0')
|
||||||
|
expect(countStateAfterClicked).toBe('STATE COUNT: 1')
|
||||||
|
|
||||||
const countAfterClickedAndReloaded = await browser
|
await browser.elementByCss('#on-click-link').click()
|
||||||
.elementByCss('#on-click-link').click() // +2
|
|
||||||
.elementByCss('p').text()
|
|
||||||
|
|
||||||
// counts (onClick handler, no reload)
|
const countQueryAfterClickedAgain = await browser.elementByCss('#query-count').text()
|
||||||
expect(countAfterClickedAndReloaded).toBe('COUNT: 3')
|
const countStateAfterClickedAgain = await browser.elementByCss('#state-count').text()
|
||||||
browser.close()
|
expect(countQueryAfterClickedAgain).toBe('QUERY COUNT: 1')
|
||||||
|
expect(countStateAfterClickedAgain).toBe('STATE COUNT: 2')
|
||||||
|
} finally {
|
||||||
|
if (browser) {
|
||||||
|
browser.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should always replace the state and perform additional action', async () => {
|
it('should always replace the state and perform additional action', async () => {
|
||||||
const browser = await webdriver(context.appPort, '/nav')
|
let browser
|
||||||
|
try {
|
||||||
|
browser = await webdriver(context.appPort, '/nav')
|
||||||
|
|
||||||
const countAfterClicked = await browser
|
await browser.elementByCss('#on-click-link').click().waitForElementByCss('#on-click-page')
|
||||||
.elementByCss('#on-click-link').click() // 1
|
|
||||||
.waitForElementByCss('#on-click-page')
|
|
||||||
.elementByCss('#on-click-link').click() // 3
|
|
||||||
.elementByCss('#on-click-link').click() // 5
|
|
||||||
.elementByCss('p').text()
|
|
||||||
|
|
||||||
// counts (page change + two clicks + onClick handler)
|
const defaultCountQuery = await browser.elementByCss('#query-count').text()
|
||||||
expect(countAfterClicked).toBe('COUNT: 5')
|
expect(defaultCountQuery).toBe('QUERY COUNT: 1')
|
||||||
|
|
||||||
// Since we replace the state, back button would simply go us back to /nav
|
await browser.elementByCss('#on-click-link').click()
|
||||||
await browser
|
const countQueryAfterClicked = await browser.elementByCss('#query-count').text()
|
||||||
.back()
|
const countStateAfterClicked = await browser.elementByCss('#state-count').text()
|
||||||
.waitForElementByCss('.nav-home')
|
expect(countQueryAfterClicked).toBe('QUERY COUNT: 2')
|
||||||
|
expect(countStateAfterClicked).toBe('STATE COUNT: 1')
|
||||||
|
|
||||||
browser.close()
|
// Since we replace the state, back button would simply go us back to /nav
|
||||||
|
await browser.back().waitForElementByCss('.nav-home')
|
||||||
|
} finally {
|
||||||
|
if (browser) {
|
||||||
|
browser.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ describe('Basic Features', () => {
|
||||||
|
|
||||||
renderViaHTTP(context.appPort, '/nav'),
|
renderViaHTTP(context.appPort, '/nav'),
|
||||||
renderViaHTTP(context.appPort, '/nav/about'),
|
renderViaHTTP(context.appPort, '/nav/about'),
|
||||||
|
renderViaHTTP(context.appPort, '/nav/on-click'),
|
||||||
renderViaHTTP(context.appPort, '/nav/querystring'),
|
renderViaHTTP(context.appPort, '/nav/querystring'),
|
||||||
renderViaHTTP(context.appPort, '/nav/self-reload'),
|
renderViaHTTP(context.appPort, '/nav/self-reload'),
|
||||||
renderViaHTTP(context.appPort, '/nav/hash-changes'),
|
renderViaHTTP(context.appPort, '/nav/hash-changes'),
|
||||||
|
|
Loading…
Reference in a new issue