Skip to content

Commit 9dc91e2

Browse files
mischnicunstubbable
authored andcommitted
add test
1 parent 3b8cd92 commit 9dc91e2

File tree

6 files changed

+131
-0
lines changed

6 files changed

+131
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use client'
2+
3+
export function Component() {
4+
return <p>Component</p>
5+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { subscribeToHMR } from './subscribeToHMR'
2+
import { Component } from './Component'
3+
4+
const RootPage = async ({ Component }: any) => {
5+
await subscribeToHMR()
6+
7+
return (
8+
<html>
9+
<body>
10+
<iframe src="/page2" />
11+
</body>
12+
</html>
13+
)
14+
}
15+
16+
export default function Page() {
17+
return <RootPage Component={Component} />
18+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
if (!global._payload) {
2+
global._payload = {
3+
payload: null,
4+
reload: false,
5+
ws: null,
6+
}
7+
}
8+
9+
export const subscribeToHMR = async () => {
10+
let cached = global._payload
11+
12+
if (cached.payload) {
13+
if (cached.reload === true) {
14+
let resolve: any
15+
16+
cached.reload = new Promise((res) => (resolve = res))
17+
18+
await new Promise((resolve) => setTimeout(resolve, 200))
19+
20+
resolve()
21+
}
22+
if (cached.reload instanceof Promise) {
23+
await cached.reload
24+
}
25+
26+
return cached.payload
27+
}
28+
29+
cached.payload = {}
30+
31+
const port = process.env.PORT || '3000'
32+
const hasHTTPS =
33+
process.env.USE_HTTPS === 'true' ||
34+
process.argv.includes('--experimental-https')
35+
const protocol = hasHTTPS ? 'wss' : 'ws'
36+
const path = '/_next/webpack-hmr'
37+
// The __NEXT_ASSET_PREFIX env variable is set for both assetPrefix and basePath (tested in Next.js 15.1.6)
38+
const prefix = process.env.__NEXT_ASSET_PREFIX ?? ''
39+
cached.ws = new WebSocket(
40+
process.env.PAYLOAD_HMR_URL_OVERRIDE ??
41+
`${protocol}://localhost:${port}${prefix}${path}`
42+
)
43+
cached.ws.onmessage = (event: any) => {
44+
if (typeof event.data === 'string') {
45+
const data = JSON.parse(event.data)
46+
if (
47+
// On Next.js 15, we need to check for data.action. On Next.js 16, we need to check for data.type.
48+
data.type === 'serverComponentChanges' ||
49+
data.action === 'serverComponentChanges'
50+
) {
51+
cached.reload = true
52+
}
53+
}
54+
}
55+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { subscribeToHMR } from '../page1/subscribeToHMR'
2+
3+
export default async function Page() {
4+
await subscribeToHMR()
5+
6+
return (
7+
<html>
8+
<body>
9+
<p>content</p>
10+
</body>
11+
</html>
12+
)
13+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { nextTestSetup } from 'e2e-utils'
2+
import { waitForNoRedbox } from 'next-test-utils'
3+
4+
describe('hmr-iframe', () => {
5+
const { next } = nextTestSetup({
6+
files: __dirname,
7+
})
8+
9+
it('should do HMR when rendering two server component changes at the same time', async () => {
10+
let browser = await next.browser('/page1')
11+
12+
expect(
13+
await (await (await browser.elementByCss('iframe')).contentFrame())
14+
.locator('p')
15+
.innerText()
16+
).toEqual('content')
17+
18+
await next.patchFile('app/page2/page.tsx', (content) =>
19+
content.replace('content', 'content-new')
20+
)
21+
22+
await waitForNoRedbox(browser)
23+
expect(
24+
await (await (await browser.elementByCss('iframe')).contentFrame())
25+
.locator('p')
26+
.innerText()
27+
).toEqual('content-new')
28+
29+
expect(next.cliOutput).not.toContain('Error')
30+
expect(next.cliOutput).not.toContain('Could not find the module')
31+
32+
await next.stop()
33+
await next.clean()
34+
})
35+
})
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
experimental: {
3+
appDir: true,
4+
},
5+
}

0 commit comments

Comments
 (0)