Skip to content

Commit

Permalink
Add test for Server Components HMR after navigating to page with Edge…
Browse files Browse the repository at this point in the history
… runtime (#67782)
  • Loading branch information
eps1lon committed Jul 17, 2024
1 parent 5b1c35d commit e83459c
Showing 1 changed file with 85 additions and 0 deletions.
85 changes: 85 additions & 0 deletions test/development/app-hmr/hmr.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { retry, waitFor } from 'next-test-utils'

const envFile = '.env.development.local'

const isPPREnabledByDefault = process.env.__NEXT_EXPERIMENTAL_PPR === 'true'

describe(`app-dir-hmr`, () => {
const { next } = nextTestSetup({
files: __dirname,
Expand Down Expand Up @@ -54,7 +56,86 @@ describe(`app-dir-hmr`, () => {
}
})

it('should update server components after navigating to a page with a different runtime', async () => {
const envContent = await next.readFile(envFile)

const browser = await next.browser('/env/node')
await browser.loadPage(`${next.url}/env/edge`)
await browser.eval('window.__TEST_NO_RELOAD = true')

await next.patchFile(envFile, 'MY_DEVICE="ipad"')

try {
const logs = await browser.log()

if (process.env.TURBOPACK) {
await retry(async () => {
const fastRefreshLogs = logs.filter((log) => {
return log.message.startsWith('[Fast Refresh]')
})
// FIXME: 3+ "rebuilding" but single "done" is confusing.
// There may actually be more "rebuilding" but not reliably.
// To ignore this flakiness, we just assert on subset matches.
// Once the bug is fixed, each "rebuilding" should be paired with a "done in" exactly.
expect(fastRefreshLogs).toEqual(
expect.arrayContaining([
{ source: 'log', message: '[Fast Refresh] rebuilding' },
{ source: 'log', message: '[Fast Refresh] rebuilding' },
{
source: 'log',
message: expect.stringContaining('[Fast Refresh] done in '),
},
{ source: 'log', message: '[Fast Refresh] rebuilding' },
])
)
})
} else {
await retry(
async () => {
const fastRefreshLogs = logs.filter((log) => {
return log.message.startsWith('[Fast Refresh]')
})
// FIXME: Should be either a single "rebuilding"+"done" or the last "rebuilding" should be followed by "done"
expect(fastRefreshLogs).toEqual([
{ source: 'log', message: '[Fast Refresh] rebuilding' },
{ source: 'log', message: '[Fast Refresh] rebuilding' },
{
source: 'log',
message: expect.stringContaining('[Fast Refresh] done in '),
},
{ source: 'log', message: '[Fast Refresh] rebuilding' },
])
},
// Very slow Hot Update for some reason.
// May be related to receiving 3 rebuild events but only one finish event
5000
)
}
const envValue = await browser.elementByCss('p').text()
const mpa = await browser.eval('window.__TEST_NO_RELOAD === undefined')
// Flaky sometimes in Webpack:
// A. misses update and just receives `{ envValue: 'mac', mpa: false }`
// B. triggers error on server resulting in MPA: `{ envValue: 'ipad', mpa: true }` and server logs: ⨯ [TypeError: Cannot read properties of undefined (reading 'polyfillFiles')] ⨯ [TypeError: Cannot read properties of null (reading 'default')]
// A is more common than B.
expect({ envValue, mpa }).toEqual({
envValue:
isPPREnabledByDefault && !process.env.TURBOPACK
? // FIXME: Should be 'ipad' but PPR+Webpack swallows the update reliably
'mac'
: 'ipad',
mpa: false,
})
} finally {
await next.patchFile(envFile, envContent)
}
})

it('should update server components pages when env files is changed (nodejs)', async () => {
// If "should update server components after navigating to a page with a different runtime" failed, the dev server is in a corrupted state.
// Restart fixes this.
await next.stop()
await next.start()

const envContent = await next.readFile(envFile)
const browser = await next.browser('/env/node')
expect(await browser.elementByCss('p').text()).toBe('mac')
Expand Down Expand Up @@ -91,6 +172,10 @@ describe(`app-dir-hmr`, () => {
})

it('should update server components pages when env files is changed (edge)', async () => {
// Restart to work around a bug highlighted in the flakiness of "should update server components after navigating to a page with a different runtime"
await next.stop()
await next.start()

const envContent = await next.readFile(envFile)
const browser = await next.browser('/env/edge')
expect(await browser.elementByCss('p').text()).toBe('mac')
Expand Down

0 comments on commit e83459c

Please sign in to comment.