未验证 提交 b7e256ba 编写于 作者: T Tim Neutkens 提交者: GitHub

Make onClick Link tests more consistent (#4954)

上级 87f5df24
......@@ -8,14 +8,14 @@ export default class BuildManifestPlugin {
apply (compiler: any) {
compiler.hooks.emit.tapAsync('NextJsBuildManifest', (compilation, callback) => {
const {chunks} = compilation
const assetMap = {pages: {}}
const assetMap = {devFiles: [], pages: {}}
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)) : []
for (const filePath of Object.keys(compilation.assets)) {
if (/^static\/dll\//.test(filePath)) {
mainJsFiles.push(filePath)
assetMap.devFiles.push(filePath)
}
}
......
......@@ -199,11 +199,12 @@ export class NextScript extends Component {
}
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 pagePathname = getPagePathname(pathname)
return <Fragment>
{devFiles ? devFiles.map((file) => <script src={`${assetPrefix}/_next/${file}`} nonce={this.props.nonce} />) : null}
{staticMarkup ? null : <script nonce={this.props.nonce} dangerouslySetInnerHTML={{
__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 router = new Router(pathname, query, asPath)
const props = await loadGetInitialProps(App, {Component, router, ctx})
const devFiles = buildManifest.devFiles
const files = [
...new Set([
...buildManifest.pages[normalizePagePath(page)],
......@@ -167,6 +168,7 @@ async function doRender (req, res, pathname, query, {
dir,
staticMarkup,
buildManifest,
devFiles,
files,
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
......
......@@ -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'><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/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>
<button
onClick={() => this.visitQueryStringPage()}
......
import { Component } from 'react'
import Link from 'next/link'
let count = 0
export default class OnClick extends Component {
static getInitialProps ({ res }) {
if (res) return { count: 0 }
count += 1
static getInitialProps ({ res, query: {count} }) {
return { count: count ? parseInt(count) : 0 }
}
return { count }
state = {
stateCounter: 0
}
render () {
const {stateCounter} = this.state
const {count} = this.props
return (
<div id='on-click-page'>
<Link href='/nav/on-click'>
<a id='on-click-link' onClick={() => ++count}>Self Reload</a>
<Link href={`/nav/on-click?count=${count + 1}`} replace>
<a id='on-click-link' onClick={() => this.setState({stateCounter: stateCounter + 1})}>Self Reload</a>
</Link>
<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>
<p>COUNT: {this.props.count}</p>
<p id='query-count'>QUERY COUNT: {count}</p>
<p id='state-count'>STATE COUNT: {stateCounter}</p>
</div>
)
}
......
......@@ -178,59 +178,79 @@ export default (context, render) => {
describe('with onClick action', () => {
it('should reload the page and perform additional action', async () => {
const browser = await webdriver(context.appPort, '/nav/on-click')
const defaultCount = await browser.elementByCss('p').text()
expect(defaultCount).toBe('COUNT: 0')
const countAfterClicked = await browser
.elementByCss('#on-click-link').click()
.elementByCss('p').text()
// counts (one click + onClick handler)
expect(countAfterClicked).toBe('COUNT: 2')
browser.close()
let browser
try {
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')
await browser.elementByCss('#on-click-link').click()
const countQueryAfterClicked = await browser.elementByCss('#query-count').text()
const countStateAfterClicked = await browser.elementByCss('#state-count').text()
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 () => {
const browser = await webdriver(context.appPort, '/nav/on-click')
const defaultCount = await browser.elementByCss('p').text()
expect(defaultCount).toBe('COUNT: 0')
let browser
try {
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
.elementByCss('#on-click-link-prevent-default').click()
.elementByCss('p').text()
await browser.elementByCss('#on-click-link-prevent-default').click()
// counter is increased but there was no reload
expect(countAfterClicked).toBe('COUNT: 0')
const countQueryAfterClicked = await browser.elementByCss('#query-count').text()
const countStateAfterClicked = await browser.elementByCss('#state-count').text()
expect(countQueryAfterClicked).toBe('QUERY COUNT: 0')
expect(countStateAfterClicked).toBe('STATE COUNT: 1')
const countAfterClickedAndReloaded = await browser
.elementByCss('#on-click-link').click() // +2
.elementByCss('p').text()
await browser.elementByCss('#on-click-link').click()
// counts (onClick handler, no reload)
expect(countAfterClickedAndReloaded).toBe('COUNT: 3')
browser.close()
const countQueryAfterClickedAgain = await browser.elementByCss('#query-count').text()
const countStateAfterClickedAgain = await browser.elementByCss('#state-count').text()
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 () => {
const browser = await webdriver(context.appPort, '/nav')
let browser
try {
browser = await webdriver(context.appPort, '/nav')
const countAfterClicked = await browser
.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()
await browser.elementByCss('#on-click-link').click().waitForElementByCss('#on-click-page')
// counts (page change + two clicks + onClick handler)
expect(countAfterClicked).toBe('COUNT: 5')
const defaultCountQuery = await browser.elementByCss('#query-count').text()
expect(defaultCountQuery).toBe('QUERY COUNT: 1')
// Since we replace the state, back button would simply go us back to /nav
await browser
.back()
.waitForElementByCss('.nav-home')
await browser.elementByCss('#on-click-link').click()
const countQueryAfterClicked = await browser.elementByCss('#query-count').text()
const countStateAfterClicked = await browser.elementByCss('#state-count').text()
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/about'),
renderViaHTTP(context.appPort, '/nav/on-click'),
renderViaHTTP(context.appPort, '/nav/querystring'),
renderViaHTTP(context.appPort, '/nav/self-reload'),
renderViaHTTP(context.appPort, '/nav/hash-changes'),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册