/
index.test.ts
174 lines (147 loc) · 5.97 KB
/
index.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import { nextTestSetup } from 'e2e-utils'
import { check } from 'next-test-utils'
describe('app dir - not-found - basic', () => {
const { next, isNextDev, isNextStart, skipped } = nextTestSetup({
files: __dirname,
skipDeployment: true,
})
if (skipped) {
return
}
it("should propagate notFound errors past a segment's error boundary", async () => {
let browser = await next.browser('/error-boundary')
await browser.elementByCss('button').click()
expect(await browser.elementByCss('h1').text()).toBe('Root Not Found')
browser = await next.browser('/error-boundary/nested/nested-2')
await browser.elementByCss('button').click()
expect(await browser.elementByCss('h1').text()).toBe(
'Not Found (error-boundary/nested)'
)
browser = await next.browser('/error-boundary/nested/trigger-not-found')
expect(await browser.elementByCss('h1').text()).toBe(
'Not Found (error-boundary/nested)'
)
})
it('should return 404 status code for custom not-found page', async () => {
const res = await next.fetch('/_not-found')
expect(res.status).toBe(404)
})
if (isNextStart) {
it('should include not found client reference manifest in the file trace', async () => {
const fileTrace = JSON.parse(
await next.readFile('.next/server/app/_not-found/page.js.nft.json')
)
const isTraced = fileTrace.files.some((filePath) =>
filePath.includes('page_client-reference-manifest.js')
)
expect(isTraced).toBe(true)
})
it('should not output /404 in tree view logs', async () => {
const output = await next.cliOutput
expect(output).not.toContain('○ /404')
})
it('should use root not-found content for 404 html', async () => {
// static /404 page will use /_not-found content
const page404 = await next.readFile('.next/server/pages/404.html')
expect(page404).toContain('Root Not Found')
})
}
const runTests = ({ isEdge }: { isEdge: boolean }) => {
it('should use the not-found page for non-matching routes', async () => {
const browser = await next.browser('/random-content')
expect(await browser.elementByCss('h1').text()).toContain(
'Root Not Found'
)
// should contain root layout content
expect(await browser.elementByCss('#layout-nav').text()).toBe('Navbar')
})
it('should match dynamic route not-found boundary correctly', async () => {
// `/dynamic` display works
const browserDynamic = await next.browser('/dynamic')
expect(await browserDynamic.elementByCss('main').text()).toBe('dynamic')
// `/dynamic/404` calling notFound() will match the same level not-found boundary
const browserDynamic404 = await next.browser('/dynamic/404')
expect(await browserDynamic404.elementByCss('#not-found').text()).toBe(
'dynamic/[id] not found'
)
const browserDynamicId = await next.browser('/dynamic/123')
expect(await browserDynamicId.elementByCss('#page').text()).toBe(
'dynamic [id]'
)
})
it('should escalate notFound to parent layout if no not-found boundary present in current layer', async () => {
const browserDynamic = await next.browser(
'/dynamic-layout-without-not-found'
)
expect(await browserDynamic.elementByCss('h1').text()).toBe(
'Dynamic with Layout'
)
// no not-found boundary in /dynamic-layout-without-not-found, escalate to parent layout to render root not-found
const browserDynamicId = await next.browser(
'/dynamic-layout-without-not-found/404'
)
expect(await browserDynamicId.elementByCss('h1').text()).toBe(
'Root Not Found'
)
const browserDynamic404 = await next.browser(
'/dynamic-layout-without-not-found/123'
)
expect(await browserDynamic404.elementByCss('#page').text()).toBe(
'dynamic-layout-without-not-found [id]'
)
})
if (isNextDev) {
it('should not reload the page', async () => {
const browser = await next.browser('/random-content')
const timestamp = await browser.elementByCss('#timestamp').text()
await new Promise((resolve) => {
setTimeout(resolve, 3000)
})
await check(async () => {
const newTimestamp = await browser.elementByCss('#timestamp').text()
return newTimestamp !== timestamp ? 'failure' : 'success'
}, 'success')
})
// Disabling for Edge because it is too flakey.
// @TODO investigate a proper for fix for this flake
if (!isEdge) {
it('should render the 404 page when the file is removed, and restore the page when re-added', async () => {
const browser = await next.browser('/')
await check(() => browser.elementByCss('h1').text(), 'My page')
await next.renameFile('./app/page.js', './app/foo.js')
await check(() => browser.elementByCss('h1').text(), 'Root Not Found')
await next.renameFile('./app/foo.js', './app/page.js')
await check(() => browser.elementByCss('h1').text(), 'My page')
})
}
}
if (!isNextDev && !isEdge) {
it('should create the 404 mapping and copy the file to pages', async () => {
const html = await next.readFile('.next/server/pages/404.html')
expect(html).toContain('Root Not Found')
expect(
await next.readFile('.next/server/pages-manifest.json')
).toContain('"pages/404.html"')
})
}
}
describe('with default runtime', () => {
runTests({ isEdge: false })
})
describe('with runtime = edge', () => {
let originalLayout = ''
beforeAll(async () => {
await next.stop()
originalLayout = await next.readFile('app/layout.js')
await next.patchFile(
'app/layout.js',
`export const runtime = 'edge'\n${originalLayout}`
)
await next.start()
})
afterAll(async () => {
await next.patchFile('app/layout.js', originalLayout)
})
runTests({ isEdge: true })
})
})