Skip to content

Commit e186b69

Browse files
authored
[Segment Cache] Enable deploy tests (#80947)
With this PR, we're enabling deployment testing for the existing Segment Cache test suites (excluding those that need a custom server setup). Two timing issues were fixed, and one bug was uncovered. For details see the inline comments below.
1 parent d93f940 commit e186b69

File tree

10 files changed

+82
-62
lines changed

10 files changed

+82
-62
lines changed

test/e2e/app-dir/segment-cache/basic/segment-cache-basic.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ import { nextTestSetup } from 'e2e-utils'
22
import { createRouterAct } from '../router-act'
33

44
describe('segment cache (basic tests)', () => {
5-
const { next, isNextDev, skipped } = nextTestSetup({
5+
const { next, isNextDev } = nextTestSetup({
66
files: __dirname,
7-
skipDeployment: true,
87
})
9-
if (isNextDev || skipped) {
8+
if (isNextDev) {
109
test('ppr is disabled', () => {})
1110
return
1211
}

test/e2e/app-dir/segment-cache/client-only-opt-in/client-only-opt-in.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ import type * as Playwright from 'playwright'
33
import { createRouterAct } from '../router-act'
44

55
describe('segment cache prefetch scheduling', () => {
6-
const { next, isNextDev, skipped } = nextTestSetup({
6+
const { next, isNextDev } = nextTestSetup({
77
files: __dirname,
8-
skipDeployment: true,
98
})
10-
if (isNextDev || skipped) {
9+
if (isNextDev) {
1110
test('prefetching is disabled', () => {})
1211
return
1312
}

test/e2e/app-dir/segment-cache/dynamic-on-hover/dynamic-on-hover.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ import type * as Playwright from 'playwright'
33
import { createRouterAct } from '../router-act'
44

55
describe('dynamic on hover', () => {
6-
const { next, isNextDev, skipped } = nextTestSetup({
6+
const { next, isNextDev } = nextTestSetup({
77
files: __dirname,
8-
skipDeployment: true,
98
})
10-
if (isNextDev || skipped) {
9+
if (isNextDev) {
1110
test('prefetching is disabled', () => {})
1211
return
1312
}

test/e2e/app-dir/segment-cache/incremental-opt-in/segment-cache-incremental-opt-in.test.ts

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { nextTestSetup } from 'e2e-utils'
22
import { createRouterAct } from '../router-act'
3+
import { Page } from 'playwright'
34

45
describe('segment cache (incremental opt in)', () => {
5-
const { next, isNextDev, skipped } = nextTestSetup({
6+
const { next, isNextDeploy, isNextDev } = nextTestSetup({
67
files: __dirname,
7-
skipDeployment: true,
88
})
9-
if (isNextDev || skipped) {
9+
if (isNextDev) {
1010
test('ppr is disabled', () => {})
1111
return
1212
}
@@ -21,21 +21,22 @@ describe('segment cache (incremental opt in)', () => {
2121
// that occur. Then at the end we confirm there are no duplicates.
2222
const prefetches = new Map()
2323
const duplicatePrefetches = new Map()
24+
const unexpectedResponses = []
2425

25-
let act
26+
let currentPage: Page
2627
const browser = await next.browser('/', {
2728
async beforePageLoad(page) {
28-
act = createRouterAct(page)
29+
currentPage = page
2930
await page.route('**/*', async (route) => {
3031
const request = route.request()
32+
const headers = await request.allHeaders()
3133
const isPrefetch =
32-
request.headerValue('rsc') !== null &&
33-
request.headerValue('next-router-prefetch') !== null
34+
headers['rsc'] !== undefined &&
35+
headers['next-router-prefetch'] !== undefined
3436
if (isPrefetch) {
35-
const request = route.request()
36-
const headers = await request.allHeaders()
37+
const url = request.url()
3738
const prefetchInfo = {
38-
href: new URL(request.url()).pathname,
39+
href: new URL(url).pathname,
3940
segment: headers['Next-Router-Segment-Prefetch'.toLowerCase()],
4041
base: headers['Next-Router-State-Tree'.toLowerCase()] ?? null,
4142
}
@@ -45,6 +46,19 @@ describe('segment cache (incremental opt in)', () => {
4546
} else {
4647
prefetches.set(key, prefetchInfo)
4748
}
49+
const response = await page.request.fetch(request, {
50+
maxRedirects: 0,
51+
})
52+
const status = response.status()
53+
if (status !== 200) {
54+
unexpectedResponses.push({
55+
status,
56+
url,
57+
headers: response.headers(),
58+
response: await response.text(),
59+
})
60+
}
61+
return route.fulfill({ response })
4862
}
4963
route.continue()
5064
})
@@ -60,10 +74,8 @@ describe('segment cache (incremental opt in)', () => {
6074
expect(await checkbox.isChecked()).toBe(false)
6175

6276
// Click the checkbox to reveal the link and trigger a prefetch
63-
await act(async () => {
64-
await checkbox.click()
65-
await browser.elementByCss(`a[href="${linkHref}"]`)
66-
})
77+
await checkbox.click()
78+
await browser.elementByCss(`a[href="${linkHref}"]`)
6779

6880
// Toggle the visibility of the link. Prefetches are initiated on viewport,
6981
// so if the cache does not dedupe then properly, this test will detect it.
@@ -78,15 +90,23 @@ describe('segment cache (incremental opt in)', () => {
7890
await browser.elementById('page-content')
7991
expect(new URL(await browser.url()).pathname).toBe(linkHref)
8092

81-
// Finally, assert there were no duplicate prefetches
82-
expect(prefetches.size).not.toBe(0)
83-
expect(duplicatePrefetches.size).toBe(0)
93+
// Wait for all pending requests to complete.
94+
await currentPage.unrouteAll({ behavior: 'wait' })
95+
96+
// Finally, assert there were no duplicate prefetches and no unexpected
97+
// responses.
98+
expect(prefetches).not.toBeEmpty()
99+
expect(duplicatePrefetches).toBeEmpty()
100+
expect(unexpectedResponses).toBeEmpty()
84101
}
85102

86103
describe('multiple prefetches to same link are deduped', () => {
87104
it('page with PPR enabled', () => testPrefetchDeduping('/ppr-enabled'))
88-
it('page with PPR enabled, and has a dynamic param', () =>
89-
testPrefetchDeduping('/ppr-enabled/dynamic-param'))
105+
// FIXME: When deployed, the _tree prefetch request returns an empty 204.
106+
;(isNextDeploy ? it.failing : it)(
107+
'page with PPR enabled, and has a dynamic param',
108+
() => testPrefetchDeduping('/ppr-enabled/dynamic-param')
109+
)
90110
it('page with PPR disabled', () => testPrefetchDeduping('/ppr-disabled'))
91111
it('page with PPR disabled, and has a loading boundary', () =>
92112
testPrefetchDeduping('/ppr-disabled-with-loading-boundary'))

test/e2e/app-dir/segment-cache/memory-pressure/segment-cache-memory-pressure.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ import { nextTestSetup } from 'e2e-utils'
22
import { createRouterAct } from '../router-act'
33

44
describe('segment cache memory pressure', () => {
5-
const { next, isNextDev, skipped } = nextTestSetup({
5+
const { next, isNextDev } = nextTestSetup({
66
files: __dirname,
7-
skipDeployment: true,
87
})
9-
if (isNextDev || skipped) {
8+
if (isNextDev) {
109
test('disabled in development / deployment', () => {})
1110
return
1211
}

test/e2e/app-dir/segment-cache/mpa-navigations/mpa-navigations.test.ts

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { nextTestSetup } from 'e2e-utils'
2+
import { retry } from 'next-test-utils'
23

34
describe('segment cache (MPA navigations)', () => {
4-
const { next, isNextDev, skipped } = nextTestSetup({
5+
const { next, isNextDev } = nextTestSetup({
56
files: __dirname,
6-
skipDeployment: true,
77
})
8-
if (isNextDev || skipped) {
8+
if (isNextDev) {
99
test('ppr is disabled', () => {})
1010
return
1111
}
@@ -26,10 +26,14 @@ describe('segment cache (MPA navigations)', () => {
2626
await link.click()
2727

2828
// The expando should not be present because we did a full-page navigation.
29-
const htmlAfterNav = await browser.elementByCss('html')
30-
expect(
31-
await htmlAfterNav.evaluate((el) => (el as ElementWithExpando).__expando)
32-
).toBe(undefined)
29+
await retry(async () => {
30+
const htmlAfterNav = await browser.elementByCss('html')
31+
expect(
32+
await htmlAfterNav.evaluate(
33+
(el) => (el as ElementWithExpando).__expando
34+
)
35+
).toBe(undefined)
36+
})
3337
})
3438

3539
it(
@@ -53,12 +57,14 @@ describe('segment cache (MPA navigations)', () => {
5357
await link.click()
5458

5559
// The expando should not be present because we did a full-page navigation.
56-
const htmlAfterNav = await browser.elementByCss('html')
57-
expect(
58-
await htmlAfterNav.evaluate(
59-
(el) => (el as ElementWithExpando).__expando
60-
)
61-
).toBe(undefined)
60+
await retry(async () => {
61+
const htmlAfterNav = await browser.elementByCss('html')
62+
expect(
63+
await htmlAfterNav.evaluate(
64+
(el) => (el as ElementWithExpando).__expando
65+
)
66+
).toBe(undefined)
67+
})
6268
}
6369
)
6470
})

test/e2e/app-dir/segment-cache/prefetch-auto/prefetch-auto.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ import type * as Playwright from 'playwright'
33
import { createRouterAct } from '../router-act'
44

55
describe('<Link prefetch="auto">', () => {
6-
const { next, isNextDev, skipped } = nextTestSetup({
6+
const { next, isNextDev } = nextTestSetup({
77
files: __dirname,
8-
skipDeployment: true,
98
})
10-
if (isNextDev || skipped) {
9+
if (isNextDev) {
1110
it('disabled in development / deployment', () => {})
1211
return
1312
}

test/e2e/app-dir/segment-cache/prefetch-scheduling/prefetch-scheduling.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ import type * as Playwright from 'playwright'
33
import { createRouterAct } from '../router-act'
44

55
describe('segment cache prefetch scheduling', () => {
6-
const { next, isNextDev, skipped } = nextTestSetup({
6+
const { next, isNextDev } = nextTestSetup({
77
files: __dirname,
8-
skipDeployment: true,
98
})
10-
if (isNextDev || skipped) {
9+
if (isNextDev) {
1110
test('prefetching is disabled', () => {})
1211
return
1312
}

test/e2e/app-dir/segment-cache/search-params/segment-cache-search-params.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ import { nextTestSetup } from 'e2e-utils'
22
import { createRouterAct } from '../router-act'
33

44
describe('segment cache (search params)', () => {
5-
const { next, isNextDev, skipped } = nextTestSetup({
5+
const { next, isNextDev } = nextTestSetup({
66
files: __dirname,
7-
skipDeployment: true,
87
})
9-
if (isNextDev || skipped) {
8+
if (isNextDev) {
109
test('ppr is disabled', () => {})
1110
return
1211
}

test/e2e/app-dir/segment-cache/staleness/segment-cache-stale-time.test.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ import type * as Playwright from 'playwright'
33
import { createRouterAct } from '../router-act'
44

55
describe('segment cache (staleness)', () => {
6-
const { next, isNextDev, skipped } = nextTestSetup({
6+
const { next, isNextDev } = nextTestSetup({
77
files: __dirname,
8-
skipDeployment: true,
98
})
10-
if (isNextDev || skipped) {
9+
if (isNextDev) {
1110
test('disabled in development / deployment', () => {})
1211
return
1312
}
@@ -90,6 +89,8 @@ describe('segment cache (staleness)', () => {
9089
const act = createRouterAct(page)
9190

9291
await page.clock.install()
92+
const startDate = Date.now()
93+
await page.clock.setFixedTime(startDate)
9394

9495
// Navigate to the dynamic page
9596
await act(
@@ -111,10 +112,10 @@ describe('segment cache (staleness)', () => {
111112

112113
await browser.back()
113114

114-
// Fast forward 29 seconds. staleTimes.dynamic is configured as 30s, so if
115-
// we navigate to the same link again, the old data should be reused without
116-
// a new network request.
117-
await page.clock.fastForward(29 * 1000)
115+
// Advance time by 29 seconds. staleTimes.dynamic is configured as 30s, so
116+
// if we navigate to the same link again, the old data should be reused
117+
// without a new network request.
118+
await page.clock.setFixedTime(startDate + 29 * 1000)
118119

119120
await act(async () => {
120121
const toggle = await browser.elementByCss(
@@ -131,9 +132,9 @@ describe('segment cache (staleness)', () => {
131132

132133
await browser.back()
133134

134-
// Fast forward an additional second. This time, if we navigate to the link
135+
// Advance an additional second. This time, if we navigate to the link
135136
// again, the data is stale, so we issue a new request.
136-
await page.clock.fastForward(1 * 1000)
137+
await page.clock.setFixedTime(startDate + 30 * 1000)
137138

138139
await act(
139140
async () => {

0 commit comments

Comments
 (0)