Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b25ee4a

Browse filesBrowse files
committed
test: expand middleware + json data e2e tests
1 parent 1f8ae92 commit b25ee4a
Copy full SHA for b25ee4a
Expand file treeCollapse file tree

18 files changed

+460
-13
lines changed

‎tests/e2e/edge-middleware.test.ts

Copy file name to clipboardExpand all lines: tests/e2e/edge-middleware.test.ts
+135-13Lines changed: 135 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import { nextVersionSatisfies } from '../utils/next-version-helpers.mjs'
33
import { test } from '../utils/playwright-helpers.js'
44
import { getImageSize } from 'next/dist/server/image-optimizer.js'
55

6+
type ExtendedWindow = Window & {
7+
didReload?: boolean
8+
}
9+
610
test('Runs edge middleware', async ({ page, middleware }) => {
711
await page.goto(`${middleware.url}/test/redirect`)
812

@@ -53,21 +57,139 @@ test('it should render OpenGraph image meta tag correctly', async ({ page, middl
5357
expect([size.width, size.height]).toEqual([1200, 630])
5458
})
5559

56-
test('json data rewrite works', async ({ middlewarePages }) => {
57-
const response = await fetch(`${middlewarePages.url}/_next/data/build-id/sha.json`, {
58-
headers: {
59-
'x-nextjs-data': '1',
60+
test.describe('json data', () => {
61+
const testConfigs = [
62+
{
63+
describeLabel: 'NextResponse.next() -> getServerSideProps page',
64+
selector: 'NextResponse.next()#getServerSideProps',
65+
jsonPathMatcher: '/link/next-getserversideprops.json',
66+
},
67+
{
68+
describeLabel: 'NextResponse.next() -> getStaticProps page',
69+
selector: 'NextResponse.next()#getStaticProps',
70+
jsonPathMatcher: '/link/next-getstaticprops.json',
71+
},
72+
{
73+
describeLabel: 'NextResponse.next() -> fully static page',
74+
selector: 'NextResponse.next()#fullyStatic',
75+
jsonPathMatcher: '/link/next-fullystatic.json',
76+
},
77+
{
78+
describeLabel: 'NextResponse.rewrite() -> getServerSideProps page',
79+
selector: 'NextResponse.rewrite()#getServerSideProps',
80+
jsonPathMatcher: '/link/rewrite-me-getserversideprops.json',
6081
},
82+
{
83+
describeLabel: 'NextResponse.rewrite() -> getStaticProps page',
84+
selector: 'NextResponse.rewrite()#getStaticProps',
85+
jsonPathMatcher: '/link/rewrite-me-getstaticprops.json',
86+
},
87+
{
88+
describeLabel: 'NextResponse.rewrite() -> fully static page',
89+
selector: 'NextResponse.rewrite()#fullyStatic',
90+
jsonPathMatcher: '/link/rewrite-me-fullystatic.json',
91+
},
92+
]
93+
test.describe('no 18n', () => {
94+
for (const testConfig of testConfigs) {
95+
test.describe(testConfig.describeLabel, () => {
96+
test('json data fetch', async ({ middlewarePages, page }) => {
97+
const dataFetchPromise = new Promise<Response>((resolve) => {
98+
page.on('response', (response) => {
99+
if (response.url().includes(testConfig.jsonPathMatcher)) {
100+
resolve(response)
101+
}
102+
})
103+
})
104+
105+
await page.goto(`${middlewarePages.url}/link`)
106+
107+
await page.hover(`[data-link="${testConfig.selector}"]`)
108+
109+
const dataResponse = await dataFetchPromise
110+
111+
expect(dataResponse.ok()).toBe(true)
112+
})
113+
114+
test('navigation', async ({ middlewarePages, page }) => {
115+
await page.goto(`${middlewarePages.url}/link`)
116+
117+
await page.evaluate(() => {
118+
// set some value to window to check later if browser did reload and lost this state
119+
;(window as ExtendedWindow).didReload = false
120+
})
121+
122+
await page.click(`[data-link="${testConfig.selector}"]`)
123+
124+
// wait for page to be rendered
125+
await page.waitForSelector(`[data-page="${testConfig.selector}"]`)
126+
127+
// check if browser navigation worked by checking if state was preserved
128+
const browserNavigationWorked =
129+
(await page.evaluate(() => {
130+
return (window as ExtendedWindow).didReload
131+
})) === false
132+
133+
// we expect client navigation to work without browser reload
134+
expect(browserNavigationWorked).toBe(true)
135+
})
136+
})
137+
}
138+
})
139+
test.describe('with 18n', () => {
140+
for (const testConfig of testConfigs) {
141+
test.describe(testConfig.describeLabel, () => {
142+
for (const { localeLabel, pageWithLinksPathname } of [
143+
{ localeLabel: 'implicit default locale', pageWithLinksPathname: '/link' },
144+
{ localeLabel: 'explicit default locale', pageWithLinksPathname: '/en/link' },
145+
{ localeLabel: 'explicit non-default locale', pageWithLinksPathname: '/fr/link' },
146+
]) {
147+
test.describe(localeLabel, () => {
148+
test('json data fetch', async ({ middlewareI18n, page }) => {
149+
const dataFetchPromise = new Promise<Response>((resolve) => {
150+
page.on('response', (response) => {
151+
if (response.url().includes(testConfig.jsonPathMatcher)) {
152+
resolve(response)
153+
}
154+
})
155+
})
156+
157+
await page.goto(`${middlewareI18n.url}${pageWithLinksPathname}`)
158+
159+
await page.hover(`[data-link="${testConfig.selector}"]`)
160+
161+
const dataResponse = await dataFetchPromise
162+
163+
expect(dataResponse.ok()).toBe(true)
164+
})
165+
166+
test('navigation', async ({ middlewareI18n, page }) => {
167+
await page.goto(`${middlewareI18n.url}${pageWithLinksPathname}`)
168+
169+
await page.evaluate(() => {
170+
// set some value to window to check later if browser did reload and lost this state
171+
;(window as ExtendedWindow).didReload = false
172+
})
173+
174+
await page.click(`[data-link="${testConfig.selector}"]`)
175+
176+
// wait for page to be rendered
177+
await page.waitForSelector(`[data-page="${testConfig.selector}"]`)
178+
179+
// check if browser navigation worked by checking if state was preserved
180+
const browserNavigationWorked =
181+
(await page.evaluate(() => {
182+
return (window as ExtendedWindow).didReload
183+
})) === false
184+
185+
// we expect client navigation to work without browser reload
186+
expect(browserNavigationWorked).toBe(true)
187+
})
188+
})
189+
}
190+
})
191+
}
61192
})
62-
63-
expect(response.ok).toBe(true)
64-
const body = await response.text()
65-
66-
expect(body).toMatch(/^{"pageProps":/)
67-
68-
const data = JSON.parse(body)
69-
70-
expect(data.pageProps.message).toBeDefined()
71193
})
72194

73195
// those tests use `fetch` instead of `page.goto` intentionally to avoid potential client rendering

‎tests/fixtures/middleware-i18n/middleware.js

Copy file name to clipboardExpand all lines: tests/fixtures/middleware-i18n/middleware.js
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,26 @@ export async function middleware(request) {
88
return NextResponse.next()
99
}
1010

11+
if (url.pathname.startsWith('/link/next')) {
12+
return NextResponse.next({
13+
headers: {
14+
'x-middleware-test': 'link-next',
15+
},
16+
})
17+
}
18+
19+
if (url.pathname.startsWith('/link/rewrite-me')) {
20+
const rewriteUrl = new URL(
21+
url.pathname.replace('/link/rewrite-me', '/link/rewrite-target'),
22+
url,
23+
)
24+
return NextResponse.rewrite(rewriteUrl, {
25+
headers: {
26+
'x-middleware-test': 'link-rewrite',
27+
},
28+
})
29+
}
30+
1131
if (url.pathname === '/old-home') {
1232
if (url.searchParams.get('override') === 'external') {
1333
return Response.redirect('https://example.vercel.sh')
+67Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import Link from 'next/link'
2+
3+
export default function Page() {
4+
return (
5+
<div>
6+
<h1>Page with Links</h1>
7+
<ul>
8+
<li>
9+
NextResponse.next()
10+
<ul>
11+
<li>
12+
<Link
13+
href="/link/next-getserversideprops"
14+
data-link="NextResponse.next()#getServerSideProps"
15+
>
16+
getServerSideProps
17+
</Link>
18+
</li>
19+
20+
<li>
21+
<Link href="/link/next-getstaticprops" data-link="NextResponse.next()#getStaticProps">
22+
getStaticProps
23+
</Link>
24+
</li>
25+
26+
<li>
27+
<Link href="/link/next-fullystatic" data-link="NextResponse.next()#fullyStatic">
28+
fullyStatic
29+
</Link>
30+
</li>
31+
</ul>
32+
</li>
33+
<li>
34+
NextResponse.rewrite()
35+
<ul>
36+
<li>
37+
<Link
38+
href="/link/rewrite-me-getserversideprops"
39+
data-link="NextResponse.rewrite()#getServerSideProps"
40+
>
41+
getServerSideProps
42+
</Link>
43+
</li>
44+
45+
<li>
46+
<Link
47+
href="/link/rewrite-me-getstaticprops"
48+
data-link="NextResponse.rewrite()#getStaticProps"
49+
>
50+
getStaticProps
51+
</Link>
52+
</li>
53+
54+
<li>
55+
<Link
56+
href="/link/rewrite-me-fullystatic"
57+
data-link="NextResponse.rewrite()#fullyStatic"
58+
>
59+
fullyStatic
60+
</Link>
61+
</li>
62+
</ul>
63+
</li>
64+
</ul>
65+
</div>
66+
)
67+
}
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default function Page() {
2+
return (
3+
<div data-page="NextResponse.next()#fullyStatic">
4+
<h1>fully static page</h1>
5+
</div>
6+
)
7+
}
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export default function Page() {
2+
return (
3+
<div data-page="NextResponse.next()#getServerSideProps">
4+
<h1>
5+
<code>getServerSideProps</code> page
6+
</h1>
7+
</div>
8+
)
9+
}
10+
11+
export function getServerSideProps() {
12+
return {
13+
props: {},
14+
}
15+
}
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export default function Page() {
2+
return (
3+
<div data-page="NextResponse.next()#getStaticProps">
4+
<h1>
5+
<code>getStaticProps</code> page
6+
</h1>
7+
</div>
8+
)
9+
}
10+
11+
export function getStaticProps() {
12+
return {
13+
props: {},
14+
}
15+
}
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default function Page() {
2+
return (
3+
<div data-page="NextResponse.rewrite()#fullyStatic">
4+
<h1>fully static page</h1>
5+
</div>
6+
)
7+
}
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export default function Page() {
2+
return (
3+
<div data-page="NextResponse.rewrite()#getServerSideProps">
4+
<h1>
5+
<code>getServerSideProps</code> page
6+
</h1>
7+
</div>
8+
)
9+
}
10+
11+
export function getServerSideProps() {
12+
return {
13+
props: {},
14+
}
15+
}
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export default function Page() {
2+
return (
3+
<div data-page="NextResponse.rewrite()#getStaticProps">
4+
<h1>
5+
<code>getStaticProps</code> page
6+
</h1>
7+
</div>
8+
)
9+
}
10+
11+
export function getStaticProps() {
12+
return {
13+
props: {},
14+
}
15+
}

‎tests/fixtures/middleware-pages/middleware.js

Copy file name to clipboardExpand all lines: tests/fixtures/middleware-pages/middleware.js
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { NextResponse, URLPattern } from 'next/server'
22

3+
console.log('middleware.js loaded')
4+
35
export async function middleware(request) {
46
const url = request.nextUrl
57

@@ -8,6 +10,26 @@ export async function middleware(request) {
810
return NextResponse.next()
911
}
1012

13+
if (url.pathname.startsWith('/link/next')) {
14+
return NextResponse.next({
15+
headers: {
16+
'x-middleware-test': 'link-next',
17+
},
18+
})
19+
}
20+
21+
if (url.pathname.startsWith('/link/rewrite-me')) {
22+
const rewriteUrl = new URL(
23+
url.pathname.replace('/link/rewrite-me', '/link/rewrite-target'),
24+
url,
25+
)
26+
return NextResponse.rewrite(rewriteUrl, {
27+
headers: {
28+
'x-middleware-test': 'link-rewrite',
29+
},
30+
})
31+
}
32+
1133
if (request.headers.get('x-prerender-revalidate')) {
1234
return NextResponse.next({
1335
headers: { 'x-middleware': 'hi' },

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.