import { nextTestSetup } from 'e2e-utils' // cSpell:words lowcard highcard describe('cache-components', () => { const { next, isNextDev, skipped } = nextTestSetup({ files: __dirname, skipDeployment: true, }) if (skipped) { return } let cliIndex = 0 beforeEach(() => { cliIndex = next.cliOutput.length }) function getLines(containing: string): Array { const warnings = next.cliOutput .slice(cliIndex) .split('\n') .filter((l) => l.includes(containing)) cliIndex = next.cliOutput.length return warnings } describe('Params', () => { it('should partially prerender pages that await params in a server components', async () => { expect(getLines('Route "/params')).toEqual([]) let $ = await next.render$( '/params/semantics/one/build/layout-access/server' ) if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('build') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#page').text()).toBe('at buildtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('build') } $ = await next.render$('/params/semantics/one/run/layout-access/server') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('run') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#highcard-fallback').text()).toBe('loading highcard children') expect($('#page').text()).toBe('at runtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('run') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/build/page-access/server') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('build') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#page').text()).toBe('at buildtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('build') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/run/page-access/server') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('run') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#highcard-fallback').text()).toBe('loading highcard children') expect($('#page').text()).toBe('at runtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('run') expect(getLines('Route "/params')).toEqual([]) } }) // Since #85155, we intentionally omit search params from client segments // if the page is otherwise static, and resume using a client fetch // instead. So it's expected that the value is missing pre-hydration. // There are separate tests that verify that it is eventually hydrated. // TODO: Rewrite or update this test. it.skip('should partially prerender pages that use params in a client components', async () => { expect(getLines('Route "/params')).toEqual([]) let $ = await next.render$( '/params/semantics/one/build/layout-access/client' ) if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('build') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#page').text()).toBe('at buildtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('build') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/run/layout-access/client') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('run') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#highcard-fallback').text()).toBe('loading highcard children') expect($('#page').text()).toBe('at runtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('run') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/build/page-access/client') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('build') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#page').text()).toBe('at buildtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('build') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/run/page-access/client') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('run') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#highcard-fallback').text()).toBe('loading highcard children') expect($('#page').text()).toBe('at runtime') expect($('#param-lowcard').text()).toBe('one') expect($('#param-highcard').text()).toBe('run') expect(getLines('Route "/params')).toEqual([]) } }) it('should fully prerender pages that check individual param keys after awaiting params in a server component', async () => { expect(getLines('Route "/params')).toEqual([]) let $ = await next.render$( '/params/semantics/one/build/layout-has/server' ) if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#page').text()).toBe('at buildtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/build/page-has/server') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#page').text()).toBe('at buildtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/run/layout-has/server') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } else { // With PPR fallbacks the first visit is still partially prerendered expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#highcard-fallback').text()).toBe('loading highcard children') expect($('#page').text()).toBe('at runtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/run/page-has/server') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } else { // With PPR fallbacks the first visit is still partially prerendered expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#highcard-fallback').text()).toBe('loading highcard children') expect($('#page').text()).toBe('at runtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } }) // Since #85155, we intentionally omit search params from client segments // if the page is otherwise static, and resume using a client fetch // instead. So it's expected that the value is missing pre-hydration. // There are separate tests that verify that it is eventually hydrated. // TODO: Rewrite or update this test. it.skip('should fully prerender pages that check individual param keys after `use`ing params in a client component', async () => { expect(getLines('Route "/params')).toEqual([]) let $ = await next.render$( '/params/semantics/one/build/layout-has/client' ) if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#page').text()).toBe('at buildtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/build/page-has/client') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#page').text()).toBe('at buildtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/run/layout-has/client') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } else { // With PPR fallbacks the first visit is still partially prerendered expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#highcard-fallback').text()).toBe('loading highcard children') expect($('#page').text()).toBe('at runtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/run/page-has/client') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } else { // With PPR fallbacks the first visit is still partially prerendered expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#highcard-fallback').text()).toBe('loading highcard children') expect($('#page').text()).toBe('at runtime') expect($('#param-has-lowcard').text()).toBe('true') expect($('#param-has-highcard').text()).toBe('true') expect($('#param-has-foo').text()).toBe('false') expect(getLines('Route "/params')).toEqual([]) } }) it('should partially prerender pages that spread awaited params in a server component', async () => { expect(getLines('Route "/params')).toEqual([]) let $ = await next.render$( '/params/semantics/one/build/layout-spread/server' ) if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('build') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#page').text()).toBe('at buildtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('build') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/build/page-spread/server') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('build') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#page').text()).toBe('at buildtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('build') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/run/layout-spread/server') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('run') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#highcard-fallback').text()).toBe('loading highcard children') expect($('#page').text()).toBe('at runtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('run') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/run/page-spread/server') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('run') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#highcard-fallback').text()).toBe('loading highcard children') expect($('#page').text()).toBe('at runtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('run') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } }) // Since #85155, we intentionally omit search params from client segments // if the page is otherwise static, and resume using a client fetch // instead. So it's expected that the value is missing pre-hydration. // There are separate tests that verify that it is eventually hydrated. // TODO: Rewrite or update this test. it.skip('should partially prerender pages that spread `use`ed params in a client component', async () => { expect(getLines('Route "/params')).toEqual([]) let $ = await next.render$( '/params/semantics/one/build/layout-spread/client' ) if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('build') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#page').text()).toBe('at buildtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('build') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/build/page-spread/client') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('build') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#page').text()).toBe('at buildtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('build') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/run/layout-spread/client') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('run') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#highcard-fallback').text()).toBe('loading highcard children') expect($('#page').text()).toBe('at runtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('run') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/semantics/one/run/page-spread/client') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#lowcard').text()).toBe('at runtime') expect($('#highcard').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('run') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#lowcard').text()).toBe('at buildtime') expect($('#highcard').text()).toBe('at buildtime') expect($('#highcard-fallback').text()).toBe('loading highcard children') expect($('#page').text()).toBe('at runtime') expect($('#param-copied-lowcard').text()).toBe('one') expect($('#param-copied-highcard').text()).toBe('run') expect($('#param-key-count').text()).toBe('2') expect(getLines('Route "/params')).toEqual([]) } }) }) describe('Param Shadowing', () => { it('should correctly allow param names like then, value, and status when awaiting params in a server component', async () => { expect(getLines('Route "/params')).toEqual([]) let $ = await next.render$( '/params/shadowing/foo/bar/baz/qux/layout/server' ) if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-dyn').text()).toBe('foo') expect($('#param-then').text()).toBe('bar') expect($('#param-value').text()).toBe('baz') expect($('#param-status').text()).toBe('qux') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#page').text()).toBe('at runtime') expect($('#param-dyn').text()).toBe('foo') expect($('#param-then').text()).toBe('bar') expect($('#param-value').text()).toBe('baz') expect($('#param-status').text()).toBe('qux') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/shadowing/foo/bar/baz/qux/page/server') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-dyn').text()).toBe('foo') expect($('#param-then').text()).toBe('bar') expect($('#param-value').text()).toBe('baz') expect($('#param-status').text()).toBe('qux') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#page').text()).toBe('at runtime') expect($('#param-dyn').text()).toBe('foo') expect($('#param-then').text()).toBe('bar') expect($('#param-value').text()).toBe('baz') expect($('#param-status').text()).toBe('qux') expect(getLines('Route "/params')).toEqual([]) } }) // Since #85155, we intentionally omit search params from client segments // if the page is otherwise static, and resume using a client fetch // instead. So it's expected that the value is missing pre-hydration. // There are separate tests that verify that it is eventually hydrated. // TODO: Rewrite or update this test. it.skip('should correctly allow param names like then, value, and status when `use`ing params in a client component', async () => { expect(getLines('Route "/params')).toEqual([]) let $ = await next.render$( '/params/shadowing/foo/bar/baz/qux/layout/client' ) if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-dyn').text()).toBe('foo') expect($('#param-then').text()).toBe('bar') expect($('#param-value').text()).toBe('baz') expect($('#param-status').text()).toBe('qux') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#page').text()).toBe('at runtime') expect($('#param-dyn').text()).toBe('foo') expect($('#param-then').text()).toBe('bar') expect($('#param-value').text()).toBe('baz') expect($('#param-status').text()).toBe('qux') expect(getLines('Route "/params')).toEqual([]) } $ = await next.render$('/params/shadowing/foo/bar/baz/qux/page/client') if (isNextDev) { expect($('#layout').text()).toBe('at runtime') expect($('#page').text()).toBe('at runtime') expect($('#param-dyn').text()).toBe('foo') expect($('#param-then').text()).toBe('bar') expect($('#param-value').text()).toBe('baz') expect($('#param-status').text()).toBe('qux') expect(getLines('Route "/params')).toEqual([]) } else { expect($('#layout').text()).toBe('at buildtime') expect($('#page').text()).toBe('at runtime') expect($('#param-dyn').text()).toBe('foo') expect($('#param-then').text()).toBe('bar') expect($('#param-value').text()).toBe('baz') expect($('#param-status').text()).toBe('qux') expect(getLines('Route "/params')).toEqual([]) } }) }) if (!isNextDev) { describe('generateStaticParams', () => { // This test is skipped as the previous workaround of using `fetch-cache` will no longer be supported with DIO. it.skip('should have cacheComponents semantics inside generateStaticParams', async () => { // This test is named what we want but our current implementation is not actually correct yet. // We are asserting current behavior and will update the test when we land the correct behavior const lines: Array = next.cliOutput.split('\n') let i = 0 while (true) { const line = lines[i++] if (typeof line !== 'string') { throw new Error( 'Could not find expected route output for /params/generate-static-params/[slug]/page/...' ) } if ( line.startsWith('├') && line.includes('/params/generate-static-params/[slug]') ) { let nextLine = lines[i++] // we expect the fallback shell first expect(nextLine).toContain('/params/generate-static-params/[slug]') nextLine = lines[i++] expect(nextLine).toMatch( /\/params\/generate-static-params\/\d+\/page/ ) nextLine = lines[i++] // Because we force-cache we only end up with one prebuilt page. // When cacheComponents semantics are fully respected we will end up with two. expect(nextLine).not.toMatch( /\/params\/generate-static-params\/\d+\/page/ ) break } } }) }) } })