mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
### What? Changing an env var that is used in an RSC doesn't lead to HMR updates. It only refetches the RSC stream and no compilation happens at all since the env var is consumed only at runtime. This test did pass before as the `run_once` created a task for the `project_update` and we counted that as computation. Changing this to `turbo_tasks::run` removes the once task and no computation happens at all.
136 lines
4.7 KiB
TypeScript
136 lines
4.7 KiB
TypeScript
import { FileRef, nextTestSetup } from 'e2e-utils'
|
|
import { retry, waitFor } from 'next-test-utils'
|
|
import path from 'path'
|
|
|
|
const envFile = '.env.development.local'
|
|
|
|
describe(`app-dir-hmr`, () => {
|
|
const { next } = nextTestSetup({
|
|
files: new FileRef(path.join(__dirname, 'fixtures', 'default-template')),
|
|
patchFileDelay: 1000,
|
|
})
|
|
|
|
describe('filesystem changes', () => {
|
|
it('should not continously poll when hitting a not found page', async () => {
|
|
let requestCount = 0
|
|
|
|
const browser = await next.browser('/does-not-exist', {
|
|
beforePageLoad(page) {
|
|
page.on('request', (request) => {
|
|
const url = new URL(request.url())
|
|
if (url.pathname === '/does-not-exist') {
|
|
requestCount++
|
|
}
|
|
})
|
|
},
|
|
})
|
|
const body = await browser.elementByCss('body').text()
|
|
expect(body).toContain('404')
|
|
|
|
await waitFor(3000)
|
|
|
|
expect(requestCount).toBe(1)
|
|
})
|
|
|
|
it('should not break when renaming a folder', async () => {
|
|
const browser = await next.browser('/folder')
|
|
const text = await browser.elementByCss('h1').text()
|
|
expect(text).toBe('Hello')
|
|
|
|
// Rename folder
|
|
await next.renameFolder('app/folder', 'app/folder-renamed')
|
|
|
|
try {
|
|
// Should be 404 in a few seconds
|
|
await retry(async () => {
|
|
const body = await browser.elementByCss('body').text()
|
|
expect(body).toContain('404')
|
|
})
|
|
|
|
// The new page should be rendered
|
|
const newHTML = await next.render('/folder-renamed')
|
|
expect(newHTML).toContain('Hello')
|
|
|
|
expect(next.cliOutput).not.toContain('FATAL')
|
|
} finally {
|
|
// Rename it back
|
|
await next.renameFolder('app/folder-renamed', 'app/folder')
|
|
}
|
|
})
|
|
|
|
it('should update server components after navigating to a page with a different runtime', async () => {
|
|
const browser = await next.browser('/env/node')
|
|
expect(await browser.elementByCss('p').text()).toBe('mac')
|
|
|
|
await browser.loadPage(`${next.url}/env/edge`)
|
|
await browser.eval('window.__TEST_NO_RELOAD = true')
|
|
expect(await browser.elementByCss('p').text()).toBe('mac')
|
|
|
|
const getCliOutput = next.getCliOutputFromHere()
|
|
await next.patchFile(envFile, 'MY_DEVICE="ipad"', async () => {
|
|
await waitFor(() => getCliOutput().includes('Reload env'))
|
|
|
|
// use an extra-long timeout since the environment reload can be a
|
|
// little slow (especially on overloaded CI servers)
|
|
await retry(async () => {
|
|
expect(await browser.elementByCss('p').text()).toBe('ipad')
|
|
}, 5000 /* ms */)
|
|
|
|
expect(await browser.eval('window.__TEST_NO_RELOAD === true')).toBe(
|
|
true
|
|
)
|
|
})
|
|
|
|
// ensure it's restored back to "mac" before the next test
|
|
await retry(async () => {
|
|
expect(await browser.elementByCss('p').text()).toBe('mac')
|
|
})
|
|
|
|
expect(next.cliOutput).not.toContain('FATAL')
|
|
})
|
|
|
|
it('should have no unexpected action error for hmr', async () => {
|
|
expect(next.cliOutput).not.toContain('Unexpected action')
|
|
})
|
|
|
|
it('can navigate cleanly to a page that requires a change in the Webpack runtime', async () => {
|
|
// This isn't a very accurate test since the Webpack runtime is somewhat an implementation detail.
|
|
// To ensure this is still valid, check the `*/webpack.*.hot-update.js` network response content when the navigation is triggered.
|
|
// If there is new functionality added, the test is still valid.
|
|
// If not, the test doesn't cover anything new.
|
|
// TODO: Enforce console.error assertions or MPA navigation assertions in all tests instead.
|
|
const browser = await next.browser('/bundler-runtime-changes')
|
|
await browser.eval('window.__TEST_NO_RELOAD = true')
|
|
|
|
await browser
|
|
.elementByCss('a')
|
|
.click()
|
|
.waitForElementByCss('[data-testid="new-runtime-functionality-page"]', {
|
|
state: 'attached',
|
|
})
|
|
|
|
const logs = await browser.log()
|
|
// TODO: Should assert on all logs but these are cluttered with logs from our test utils (e.g. playwright tracing or webdriver)
|
|
expect(logs).toEqual(
|
|
expect.arrayContaining([
|
|
{
|
|
message: expect.stringContaining('[Fast Refresh] done in'),
|
|
source: 'log',
|
|
},
|
|
])
|
|
)
|
|
expect(logs).not.toEqual(
|
|
expect.arrayContaining([
|
|
expect.objectContaining({
|
|
source: 'error',
|
|
}),
|
|
])
|
|
)
|
|
// No MPA navigation triggered
|
|
expect(await browser.eval('window.__TEST_NO_RELOAD')).toEqual(true)
|
|
|
|
expect(next.cliOutput).not.toContain('FATAL')
|
|
})
|
|
})
|
|
})
|