Files
Benjamin WoodruffandGitHub 837e086479 chore(CI): Break pages-dir client-navigation dev tests into smaller parallelizable files/suites (#78787)
Jest can run different suites in parallel, but tests within the same suite must run sequentially in the same worker.

You don't want suites that are too small, because each suite requires relatively expensive repository setup, but you also don't want suites that are too large because it inhibits parallelism.

This is a big problem for arewerspackyet, where many of these test cases are currently failing. Each test can take up to 4 minutes to time out, so we easily time out the entire 90 minute long test runner job.

## Test plan

Tested by running all these tests in parallel with:

```
NEXT_TEST_MODE=dev HEADLESS=true node_modules/.bin/jest test/development/pages-dir/client-navigation
```

It completes in about 2m40s minutes on my machine.
2025-05-05 17:10:56 -07:00

164 lines
5.6 KiB
TypeScript

/* eslint-env jest */
import { check } from 'next-test-utils'
import path from 'path'
import { nextTestSetup } from 'e2e-utils'
describe('Client navigation with asPath', () => {
const { next } = nextTestSetup({
files: path.join(__dirname, 'fixture'),
env: {
TEST_STRICT_NEXT_HEAD: String(true),
},
})
describe('inside getInitialProps', () => {
it('should show the correct asPath with a Link with as prop', async () => {
const browser = await next.browser('/nav')
const asPath = await browser
.elementByCss('#as-path-link')
.click()
.waitForElementByCss('.as-path-content')
.elementByCss('.as-path-content')
.text()
expect(asPath).toBe('/as/path')
await browser.close()
})
it('should show the correct asPath with a Link without the as prop', async () => {
const browser = await next.browser('/nav')
const asPath = await browser
.elementByCss('#as-path-link-no-as')
.click()
.waitForElementByCss('.as-path-content')
.elementByCss('.as-path-content')
.text()
expect(asPath).toBe('/nav/as-path')
await browser.close()
})
})
describe('with next/router', () => {
it('should show the correct asPath', async () => {
const browser = await next.browser('/nav')
const asPath = await browser
.elementByCss('#as-path-using-router-link')
.click()
.waitForElementByCss('.as-path-content')
.elementByCss('.as-path-content')
.text()
expect(asPath).toBe('/nav/as-path-using-router')
await browser.close()
})
it('should navigate an absolute url on push', async () => {
const browser = await next.browser(`/absolute-url?port=${next.appPort}`)
await browser.waitForElementByCss('#router-push').click()
await check(
() => browser.eval(() => window.location.origin),
'https://vercel.com'
)
})
it('should navigate an absolute url on replace', async () => {
const browser = await next.browser(`/absolute-url?port=${next.appPort}`)
await browser.waitForElementByCss('#router-replace').click()
await check(
() => browser.eval(() => window.location.origin),
'https://vercel.com'
)
})
it('should navigate an absolute local url on push', async () => {
const browser = await next.browser(`/absolute-url?port=${next.appPort}`)
// @ts-expect-error _didNotNavigate is set intentionally
await browser.eval(() => (window._didNotNavigate = true))
await browser.waitForElementByCss('#router-local-push').click()
const text = await browser
.waitForElementByCss('.nav-about')
.elementByCss('p')
.text()
expect(text).toBe('This is the about page.')
// @ts-expect-error _didNotNavigate is set intentionally
expect(await browser.eval(() => window._didNotNavigate)).toBe(true)
})
it('should navigate an absolute local url on replace', async () => {
const browser = await next.browser(`/absolute-url?port=${next.appPort}`)
// @ts-expect-error _didNotNavigate is set intentionally
await browser.eval(() => (window._didNotNavigate = true))
await browser.waitForElementByCss('#router-local-replace').click()
const text = await browser
.waitForElementByCss('.nav-about')
.elementByCss('p')
.text()
expect(text).toBe('This is the about page.')
// @ts-expect-error _didNotNavigate is set intentionally
expect(await browser.eval(() => window._didNotNavigate)).toBe(true)
})
})
describe('with next/link', () => {
it('should use pushState with same href and different asPath', async () => {
const browser = await next.browser('/nav/as-path-pushstate')
await browser
.elementByCss('#hello')
.click()
.waitForElementByCss('#something-hello')
const queryOne = JSON.parse(
await browser.elementByCss('#router-query').text()
)
expect(queryOne.something).toBe('hello')
await browser
.elementByCss('#same-query')
.click()
.waitForElementByCss('#something-same-query')
const queryTwo = JSON.parse(
await browser.elementByCss('#router-query').text()
)
expect(queryTwo.something).toBe('hello')
await browser.back().waitForElementByCss('#something-hello')
const queryThree = JSON.parse(
await browser.elementByCss('#router-query').text()
)
expect(queryThree.something).toBe('hello')
await browser
.elementByCss('#else')
.click()
.waitForElementByCss('#something-else')
await browser
.elementByCss('#hello2')
.click()
.waitForElementByCss('#nav-as-path-pushstate')
await browser.back().waitForElementByCss('#something-else')
const queryFour = JSON.parse(
await browser.elementByCss('#router-query').text()
)
expect(queryFour.something).toBe(undefined)
})
it('should detect asPath query changes correctly', async () => {
const browser = await next.browser('/nav/as-path-query')
await browser
.elementByCss('#hello')
.click()
.waitForElementByCss('#something-hello-something-hello')
const queryOne = JSON.parse(
await browser.elementByCss('#router-query').text()
)
expect(queryOne.something).toBe('hello')
await browser
.elementByCss('#hello2')
.click()
.waitForElementByCss('#something-hello-something-else')
const queryTwo = JSON.parse(
await browser.elementByCss('#router-query').text()
)
expect(queryTwo.something).toBe('else')
})
})
})