Files
Jamiboy Mohammad dee811ff1c test: enable verified caching deploy tests (#98523)
## Summary

Enable the same 24 previously selected deployment-test scopes across 21
caching test files, now in a stack rooted on canary. Remove 24
`@force-gate !deploy` directives and their associated TODO comments,
which are already present on canary. Other mode, bundler, middleware,
and Cache Components exclusions remain in place.

This preserves the selection with passing evidence from the previous
deployment runs. No additional candidate scopes are enabled; excluded
variants are not counted as deployment coverage.

## Verification

- All selected test registration names and assertion bodies match the
previous enabled revision, checked by AST comparison.
- Verified that the canary diff contains only the inventoried exclusions
and their obsolete skip plumbing; other exclusions are preserved.
- Formatting and lint passed; 77 gate infrastructure unit tests passed.
- Full local bootstrap was blocked by missing package-level dependencies
in the temporary worktree. Fresh deployment execution on these rewritten
commits remains to be verified in CI.

<details>
<summary>Preserved scope inventory (24)</summary>

- ID 1:
`test/e2e/app-dir/app-client-cache/client-cache.original.test.ts` —
`describe('app dir client cache semantics (30s/5min)', () => {
  const { next, isNextDev } = nextTestSetup({
    files: path.join(__dirname, 'fixtures', 'regular'),
    nextConfig: {
      experimental: { staleTimes: { dynamic: 30, static: 180 } },
    },
  })

  if (isNextDev) {
// dev doesn't support prefetch={true}, so this just performs a basic
test to make sure data is reused for 30s
it('should renew the 30s cache once the data is revalidated', async ()
=> {
      let browser = await next.browser('/', browserConfigWithFixedTime)

      // navigate to prefetch-auto page
      await browser.elementByCss('[href="/1"]').click()
      await browser.waitForElementByCss('#random-number')

let initialNumber = await browser.elementById('random-number').text()

// Navigate back to the index, and then back to the prefetch-auto page
      await browser.elementByCss('[href="/"]').click()
      await browser.waitForElementByCss('[href="/1"]')
      await browser.eval(fastForwardTo, 5 * 1000)
      await browser.elementByCss('[href="/1"]').click()
      await browser.waitForElementByCss('#random-number')

      let newNumber = await browser.elementById('random-number').text()

      // the number should be the same, as we navigated within 30s.
      expect(newNumber).toBe(initialNumber)

      // Fast forward to expire the cache
      await browser.eval(fastForwardTo, 30 * 1000)

// Navigate back to the index, and then back to the prefetch-auto page
      await browser.elementByCss('[href="/"]').click()
      await browser.waitForElementByCss('[href="/1"]')
      await browser.elementByCss('[href="/1"]').click()
      await browser.waitForElementByCss('#random-number')

      newNumber = await browser.elementById('random-number').text()

// ~35s have passed, so the cache should be expired and the number
should be different
      expect(newNumber).not.toBe(initialNumber)

// once the number is updated, we should have a renewed 30s cache for
this entry
      // store this new number so we can check that it stays the same
      initialNumber = newNumber

      await browser.eval(fastForwardTo, 5 * 1000)

// Navigate back to the index, and then back to the prefetch-auto page
      await browser.elementByCss('[href="/"]').click()
      await browser.waitForElementByCss('[href="/1"]')
      await browser.elementByCss('[href="/1"]').click()
      await browser.waitForElementByCss('#random-number')

      newNumber = await browser.elementById('random-number').text()

// the number should be the same, as we navigated within 30s (part 2).
      expect(newNumber).toBe(initialNumber)
    })
  } else {
    describe('prefetch={true}', () => {
      let browser: Playwright

      beforeEach(async () => {
        browser = await next.browser('/', browserConfigWithFixedTime)
      })

      it('should prefetch the full page', async () => {
        const { getRequests, clearRequests } =
          await createRequestsListener(browser)
        await retry(() => {
          expect(
            getRequests().some(
              ([url, didPartialPrefetch]) =>
                getPathname(url) === '/0' && !didPartialPrefetch
            )
          ).toBe(true)
        })

        clearRequests()

        await browser.elementByCss('[href="/0?timeout=0"]').click()
        await browser.waitForElementByCss('#random-number')

        await retry(() => {
          const requests = getRequests()
expect(requests.every(([url]) => getPathname(url) !== '/0')).toBe(
            true
          )
        })
      })
it('should re-use the cache for the full page, only for 5 mins', async
() => {
        await browser.elementByCss('[href="/0?timeout=0"]').click()
        await browser.waitForElementByCss('#random-number')
const randomNumber = await browser.elementById('random-number').text()

        await browser.elementByCss('[href="/"]').click()
        await browser.waitForElementByCss('[href="/0?timeout=0"]')

        await browser.elementByCss('[href="/0?timeout=0"]').click()
        await browser.waitForElementByCss('#random-number')
        const number = await browser.elementById('random-number').text()

        expect(number).toBe(randomNumber)

        await browser.eval(fastForwardTo, 5 * 60 * 1000)

        await browser.elementByCss('[href="/"]').click()
        await browser.waitForElementByCss('[href="/0?timeout=0"]')

        await browser.elementByCss('[href="/0?timeout=0"]').click()
        await browser.waitForElementByCss('#random-number')
const newNumber = await browser.elementById('random-number').text()

        expect(newNumber).not.toBe(randomNumber)
      })

it('should prefetch again after 5 mins if the link is visible again',
async () => {
        const { getRequests, clearRequests } =
          await createRequestsListener(browser)

        await retry(() => {
          expect(
            getRequests().some(
              ([url, didPartialPrefetch]) =>
                getPathname(url) === '/0' && !didPartialPrefetch
            )
          ).toBe(true)
        })

        await browser.elementByCss('[href="/0?timeout=0"]').click()
        await browser.waitForElementByCss('#random-number')
const randomNumber = await browser.elementById('random-number').text()

        await browser.eval(fastForwardTo, 5 * 60 * 1000)
        clearRequests()

        await browser.elementByCss('[href="/"]').click()
        await browser.waitForElementByCss('[href="/0?timeout=0"]')

        await retry(() => {
          expect(
            getRequests().some(
              ([url, didPartialPrefetch]) =>
                getPathname(url) === '/0' && !didPartialPrefetch
            )
          ).toBe(true)
        })

        await browser.elementByCss('[href="/0?timeout=0"]').click()
        await browser.waitForElementByCss('#random-number')
        const number = await browser.elementById('random-number').text()

        expect(number).not.toBe(randomNumber)
      })
    })
    describe('prefetch={false}', () => {
      let browser: Playwright

      beforeEach(async () => {
        browser = await next.browser('/', browserConfigWithFixedTime)
      })
      it('should not prefetch the page at all', async () => {
        const { getRequests } = await createRequestsListener(browser)

        await browser.elementByCss('[href="/2"]').click()
        await browser.waitForElementByCss('#random-number')

        await retry(() => {
          const requests = getRequests().filter(
            ([url]) => getPathname(url) === '/2'
          )
          expect(requests.length).toBe(1)
        })

        expect(
          getRequests().some(
            ([url, didPartialPrefetch]) =>
              getPathname(url) === '/2' && didPartialPrefetch
          )
        ).toBe(false)
      })
      it('should re-use the cache only for 30 seconds', async () => {
        await browser.elementByCss('[href="/2"]').click()
        await browser.waitForElementByCss('#random-number')
const randomNumber = await browser.elementById('random-number').text()

        await browser.elementByCss('[href="/"]').click()
        await browser.waitForElementByCss('[href="/2"]')

        await browser.elementByCss('[href="/2"]').click()
        await browser.waitForElementByCss('#random-number')
        const number = await browser.elementById('random-number').text()

        expect(number).toBe(randomNumber)

        await browser.eval(fastForwardTo, 30 * 1000)

        await browser.elementByCss('[href="/"]').click()
        await browser.waitForElementByCss('[href="/2"]')

        await browser.elementByCss('[href="/2"]').click()
        await browser.waitForElementByCss('#random-number')
const newNumber = await browser.elementById('random-number').text()

        expect(newNumber).not.toBe(randomNumber)
      })
    })
    describe('prefetch={undefined} - default', () => {
      let browser: Playwright

      beforeEach(async () => {
        browser = await next.browser('/', browserConfigWithFixedTime)
      })

      it('should prefetch partially a dynamic page', async () => {
        const { getRequests, clearRequests } =
          await createRequestsListener(browser)

        await retry(() => {
          expect(
            getRequests().some(
              ([url, didPartialPrefetch]) =>
                getPathname(url) === '/1' && didPartialPrefetch
            )
          ).toBe(true)
        })

        clearRequests()

        await browser.elementByCss('[href="/1"]').click()
        await browser.waitForElementByCss('#random-number')

        await retry(() => {
          expect(
            getRequests().some(
              ([url, didPartialPrefetch]) =>
                getPathname(url) === '/1' && !didPartialPrefetch
            )
          ).toBe(true)
        })
      })
it('should re-use the full cache for only 30 seconds', async () => {
        await browser.elementByCss('[href="/1"]').click()
        await browser.waitForElementByCss('#random-number')
const randomNumber = await browser.elementById('random-number').text()

        await browser.elementByCss('[href="/"]').click()
        await browser.waitForElementByCss('[href="/1"]')

        await browser.elementByCss('[href="/1"]').click()
        await browser.waitForElementByCss('#random-number')
        const number = await browser.elementById('random-number').text()

        expect(number).toBe(randomNumber)

        await browser.eval(fastForwardTo, 5 * 1000)

        await browser.elementByCss('[href="/"]').click()
        await browser.waitForElementByCss('[href="/1"]')

        await browser.elementByCss('[href="/1"]').click()
        await browser.waitForElementByCss('#random-number')
const newNumber = await browser.elementById('random-number').text()

        expect(newNumber).toBe(randomNumber)

        await browser.eval(fastForwardTo, 30 * 1000)

        await browser.elementByCss('[href="/"]').click()
        await browser.waitForElementByCss('[href="/1"]')

        await browser.elementByCss('[href="/1"]').click()
        await browser.waitForElementByCss('#random-number')
const newNumber2 = await browser.elementById('random-number').text()

        expect(newNumber2).not.toBe(newNumber)
      })

it('should renew the 30s cache once the data is revalidated', async ()
=> {
        // navigate to prefetch-auto page
        await browser.elementByCss('[href="/1"]').click()
        await browser.waitForElementByCss('#random-number')

let initialNumber = await browser.elementById('random-number').text()

// Navigate back to the index, and then back to the prefetch-auto page
        await browser.elementByCss('[href="/"]').click()
        await browser.waitForElementByCss('[href="/1"]')
        await browser.eval(fastForwardTo, 5 * 1000)
        await browser.elementByCss('[href="/1"]').click()
        await browser.waitForElementByCss('#random-number')

let newNumber = await browser.elementById('random-number').text()

        // the number should be the same, as we navigated within 30s.
        expect(newNumber).toBe(initialNumber)

        // Fast forward to expire the cache
        await browser.eval(fastForwardTo, 30 * 1000)

// Navigate back to the index, and then back to the prefetch-auto page
        await browser.elementByCss('[href="/"]').click()
        await browser.waitForElementByCss('[href="/1"]')
        await browser.elementByCss('[href="/1"]').click()
        await browser.waitForElementByCss('#random-number')

        newNumber = await browser.elementById('random-number').text()

// ~35s have passed, so the cache should be expired and the number
should be different
        expect(newNumber).not.toBe(initialNumber)

// once the number is updated, we should have a renewed 30s cache for
this entry
        // store this new number so we can check that it stays the same
        initialNumber = newNumber

        await browser.eval(fastForwardTo, 5 * 1000)

// Navigate back to the index, and then back to the prefetch-auto page
        await browser.elementByCss('[href="/"]').click()
        await browser.waitForElementByCss('[href="/1"]')
        await browser.elementByCss('[href="/1"]').click()
        await browser.waitForElementByCss('#random-number')

        newNumber = await browser.elementById('random-number').text()

// the number should be the same, as we navigated within 30s (part 2).
        expect(newNumber).toBe(initialNumber)
      })

      it('should refetch below the fold after 30 seconds', async () => {
        await browser.elementByCss('[href="/1?timeout=1000"]').click()
        await browser.waitForElementByCss('#random-number')
const randomNumber = await browser.elementById('random-number').text()

        await browser.elementByCss('[href="/"]').click()
        await browser.waitForElementByCss('[href="/1?timeout=1000"]')

        await browser.eval(fastForwardTo, 30 * 1000)

        await browser.elementByCss('[href="/1?timeout=1000"]').click()
        await browser.waitForElementByCss('#random-number')
const newNumber = await browser.elementById('random-number').text()

        expect(newNumber).not.toBe(randomNumber)
      })
      it('should refetch the full page after 5 mins', async () => {
        // Wait for initial prefetch to complete before clicking
        await browser.waitForIdleNetwork()

        const randomLoadingNumber = await browser
          .elementByCss('[href="/1?timeout=1000"]')
          .click()
          .waitForElementByCss('#loading')
          .text()

        const randomNumber = await browser
          .waitForElementByCss('#random-number')
          .text()

        await browser.eval(fastForwardTo, 5 * 60 * 1000)

        await browser
          .elementByCss('[href="/"]')
          .click()
          .waitForElementByCss('[href="/1?timeout=1000"]')

// Wait for prefetch requests to complete before clicking, otherwise
// clicking during an in-flight prefetch aborts it and skips loading
state
        await browser.waitForIdleNetwork()

        const newLoadingNumber = await browser
          .elementByCss('[href="/1?timeout=1000"]')
          .click()
          .waitForElementByCss('#loading')
          .text()

        const newNumber = await browser
          .waitForElementByCss('#random-number')
          .text()

        expect(newLoadingNumber).not.toBe(randomLoadingNumber)

        expect(newNumber).not.toBe(randomNumber)
      })

it('should respect a loading boundary that returns `null`', async () =>
{
        await browser.elementByCss('[href="/null-loading"]').click()

        // the page content should disappear immediately
        await retry(async () => {
          expect(
await browser.hasElementByCssSelector('[href="/null-loading"]')
          ).toBe(false)
        })

        // the root layout should still be visible
expect(await browser.hasElementByCssSelector('#root-layout')).toBe(true)

        // the dynamic content should eventually appear
        await browser.waitForElementByCss('#random-number')
expect(await browser.hasElementByCssSelector('#random-number')).toBe(
          true
        )
      })
    })

it('should seed the prefetch cache with the fetched page data', async ()
=> {
const browser = await next.browser('/1', browserConfigWithFixedTime)

      await browser.waitForElementByCss('#random-number')
const initialNumber = await browser.elementById('random-number').text()

// Move forward a few seconds, navigate off the page and then back to it
      await browser.eval(fastForwardTo, 5 * 1000)
      await browser.elementByCss('[href="/"]').click()
      await browser.waitForElementByCss('[href="/1"]')

      await browser.waitForIdleNetwork()

      await browser.elementByCss('[href="/1"]').click()
      await browser.waitForElementByCss('#random-number')

const newNumber = await browser.elementById('random-number').text()

// The number should be the same as we've seeded it in the prefetch
cache when we loaded the full page
      expect(newNumber).toBe(initialNumber)
    })

it('should renew the initial seeded data after expiration time', async
() => {
      const browser = await next.browser(
        '/without-loading/1',
        browserConfigWithFixedTime
      )

      await browser.waitForElementByCss('#random-number')
const initialNumber = await browser.elementById('random-number').text()

      // Expire the cache
      await browser.eval(fastForwardTo, 30 * 1000)
      await browser.elementByCss('[href="/without-loading"]').click()
      await browser.waitForElementByCss('[href="/without-loading/1"]')
      await browser.elementByCss('[href="/without-loading/1"]').click()
      await browser.waitForElementByCss('#random-number')

const newNumber = await browser.elementById('random-number').text()

// The number should be different, as the seeded data has expired after
30s
      expect(newNumber).not.toBe(initialNumber)
    })
  }
})`
- ID 4: `test/e2e/app-dir/app-custom-cache-handler/index.test.ts` —
`describe('app-dir - custom-cache-handler - cjs', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
    env: {
      CUSTOM_CACHE_HANDLER: 'cache-handler.js',
    },
  })

  runTests('cjs module exports', { next, isNextDev })
})`
- ID 5: `test/e2e/app-dir/app-custom-cache-handler/index.test.ts` —
`describe('app-dir - custom-cache-handler - cjs-default-export', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
    env: {
      CUSTOM_CACHE_HANDLER: 'cache-handler-cjs-default-export.js',
    },
  })

  runTests('cjs default export', { next, isNextDev })
})`
- ID 6: `test/e2e/app-dir/app-custom-cache-handler/index.test.ts` —
`describe('app-dir - custom-cache-handler - esm', () => {
  const { next, isNextDev } = nextTestSetup({
    files: {
      app: new FileRef(__dirname + '/app'),
'cache-handler-esm.js': new FileRef(__dirname +
'/cache-handler-esm.js'),
      'next.config.js': originalNextConfig.replace(
        'module.exports = ',
        'export default '
      ),
    },
    packageJson: {
      type: 'module',
    },
    env: {
      CUSTOM_CACHE_HANDLER: 'cache-handler-esm.js',
    },
  })

  runTests('esm default export', { next, isNextDev })
})`
- ID 7: `test/e2e/app-dir/app-custom-cache-handler/index.test.ts` —
`describe('app-dir - custom-cache-handler - esm import.meta.resolve', ()
=> {
  const { next, isNextDev } = nextTestSetup({
    files: {
      app: new FileRef(__dirname + '/app'),
'cache-handler-esm.js': new FileRef(__dirname +
'/cache-handler-esm.js'),
      'next.config.js': importMetaResolveNextConfig,
    },
    packageJson: {
      type: 'module',
    },
  })

  runTests('esm default export', { next, isNextDev })
})`
- ID 9: `test/e2e/app-dir/app-prefetch/prefetching.stale-times.test.ts`
— `describe('app dir - prefetching (custom staleTime)', () => {
  const { next, isNextDev } = nextTestSetup({
    files: {
      app: new FileRef(join(__dirname, 'app')),
    },
    nextConfig: {
      experimental: {
        staleTimes: {
static: 30, // Minimum enforced by clientSegmentCache is 30 seconds
          dynamic: 5,
        },
      },
    },
  })

  if (isNextDev) {
    it('should skip next dev for now', () => {})
    return
  }

it('should not fetch again when a static page was prefetched when
navigating to it twice', async () => {
    let act: ReturnType<typeof createRouterAct>
    const browser = await next.browser('/', {
      beforePageLoad(page) {
        act = createRouterAct(page)
      },
    })

    // Reveal the link to trigger prefetch and wait for it to complete
    const link = await act(
      async () => {
const reveal = await browser.elementByCss('#accordion-to-static-page')
        await reveal.click()
        return browser.elementByCss('#to-static-page')
      },
      { includes: 'Static Page [prefetch-sentinel]' }
    )

// Navigate to static page - should use prefetched data with no
additional requests
    await act(async () => {
      await link.click()
const staticPageText = await browser.elementByCss('#static-page').text()
      expect(staticPageText).toBe('Static Page [prefetch-sentinel]')
    }, 'no-requests')

    // Reveal the "to-home" link and navigate back
// Note: Not using act() here because behavior differs between cache
models.
// With clientSegmentCache, revealing may trigger a prefetch. Without
it, home is already
// cached so no prefetch occurs. Either way, navigation works with
cached data.
    const reveal = await browser.elementByCss('#accordion-to-home')
    await reveal.click()
    const homeLink = await browser.waitForElementByCss('#to-home')
    await homeLink.click()
    await browser.waitForElementByCss('#accordion-to-static-page')

// Reveal the static page link again since accordion is hidden after
navigation
    await browser.elementByCss('#accordion-to-static-page').click()
    await browser.waitForElementByCss('#to-static-page')

// Navigate to static page again using the accordion - should still use
cached data with no additional requests
    const staticPageText = await act(async () => {
      await browser.elementByCss('#to-static-page').click()
      return browser.elementByCss('#static-page').text()
    }, 'no-requests')

    expect(staticPageText).toBe('Static Page [prefetch-sentinel]')
  })

it('should fetch again when a static page was prefetched when navigating
to it after the stale time has passed', async () => {
    let act: ReturnType<typeof createRouterAct>
    const timeController = createTimeController()
    const browser = await next.browser('/', {
      beforePageLoad(page) {
        act = createRouterAct(page)
      },
    })

    // Install time controller
    await timeController.install(browser)

// Reveal the static-page link to trigger prefetch and wait for it to
complete
    let link = await act(
      async () => {
const reveal = await browser.elementByCss('#accordion-to-static-page')
        await reveal.click()
        return browser.elementByCss('#to-static-page')
      },
      { includes: 'Static Page [prefetch-sentinel]' }
    )

// Navigate to static page - should use prefetched data with no
additional requests
    await act(async () => {
      await link.click()
      await browser.waitForElementByCss('#static-page')
    }, 'no-requests')

    // Reveal the "to-home" link and navigate back
    const reveal = await browser.elementByCss('#accordion-to-home')
    await reveal.click()
    const homeLink = await browser.waitForElementByCss('#to-home')
    await homeLink.click()
    await browser.waitForElementByCss('#accordion-to-static-page')

    // Advance time past the stale time
    await timeController.advance(browser, 31000)

// Reveal the static-page link to trigger prefetch and wait for it to
complete
    link = await act(
      async () => {
const reveal = await browser.elementByCss('#accordion-to-static-page')
        await reveal.click()
        return browser.elementByCss('#to-static-page')
      },
      { includes: 'Static Page [prefetch-sentinel]' }
    )

// Navigate to static page - should use prefetched data with no
additional requests
    await act(async () => {
      await link.click()
      await browser.waitForElementByCss('#static-page')
    }, 'no-requests')
  })

  // FIXME: Flaky test - investigate and re-enable
it.skip('should not re-fetch cached data when navigating back to a route
group', async () => {
    let act: ReturnType<typeof createRouterAct>
// Just installing so that the page doesn't automatically move past
dynamic stale time
    createTimeController()
    const browser = await next.browser('/prefetch-auto-route-groups', {
      beforePageLoad(page) {
        act = createRouterAct(page)
      },
    })

// Once the page has loaded, we expect a data fetch (initial page load)
    expect(await browser.elementById('count').text()).toBe('1')

    // Navigate to a sub-page - this will trigger a data fetch
    await act(async () => {
      await browser
        .elementByCss("[href='/prefetch-auto-route-groups/sub/foo']")
        .click()
    })

// Navigate back to the route group page - should use cached data with
no additional fetch
    await act(async () => {
await
browser.elementByCss("[href='/prefetch-auto-route-groups']").click()
// Confirm that the dashboard page is still rendering the stale fetch
count, as it should be cached
    }, 'no-requests')

    expect(await browser.elementById('count').text()).toBe('1')

    // Navigate to a new sub-page - this will trigger another data fetch
    await act(async () => {
      await browser
        .elementByCss("[href='/prefetch-auto-route-groups/sub/bar']")
        .click()
    })

// Finally, go back to the route group page - should use cached data
with no additional fetch
    await act(async () => {
await
browser.elementByCss("[href='/prefetch-auto-route-groups']").click()
    }, 'no-requests')

// Confirm that the dashboard page is still rendering the stale fetch
count, as it should be cached
    expect(await browser.elementById('count').text()).toBe('1')

    // Reload the page to get the accurate total number of fetches
    await browser.refresh()

// The initial fetch, 2 sub-page fetches, and a final fetch when
reloading the page
    expect(await browser.elementById('count').text()).toBe('4')
  })

it('should fetch again when the initially visited static page is visited
after the stale time has passed', async () => {
    let act: ReturnType<typeof createRouterAct>
    const timeController = createTimeController()
    const browser = await next.browser('/static-page-no-prefetch', {
      beforePageLoad(page) {
        act = createRouterAct(page)
      },
    })

    // Install time controller
    await timeController.install(browser)

// Wait for the page to load (initial navigation request happened during
browser load)
    await browser.waitForElementByCss('#static-page-no-prefetch')

// Reveal the home link and wait for prefetch to complete, then navigate
    const homeLink = await act(
      async () => {
        const reveal = await browser.elementByCss('#accordion-to-home')
        await reveal.click()
        return browser.elementByCss('#to-home')
      },
      { includes: 'Home Page [prefetch-sentinel]' }
    )

// Navigate to home - no additional requests since we just prefetched
    await homeLink.click()
    await browser.waitForElementByCss('#accordion-to-static-page')

    // Advance time past the stale time
    await timeController.advance(browser, 31000)

    // Reveal the link to static-page-no-prefetch and wait for prefetch
    const link = await act(
      async () => {
        const reveal = await browser.elementByCss(
          '#accordion-to-static-page-no-prefetch'
        )
        await reveal.click()
        return browser.elementByCss('#to-static-page-no-prefetch')
      },
      { includes: 'Static Page No Prefetch [prefetch-sentinel]' }
    )

// Navigate back to static-page-no-prefetch - should use the fresh
prefetch data
    const staticPageText = await act(async () => {
      await link.click()
      return browser.elementByCss('#static-page-no-prefetch').text()
    }, 'no-requests')
expect(staticPageText).toBe('Static Page No Prefetch
[prefetch-sentinel]')
  })

it('should renew the stale time after refetching expired RSC data',
async () => {
    let act: ReturnType<typeof createRouterAct>
    const timeController = createTimeController()
    const browser = await next.browser('/', {
      beforePageLoad(page) {
        act = createRouterAct(page)
      },
    })

    // Install time controller
    await timeController.install(browser)

// Reveal the static-page link to trigger prefetch and wait for it to
complete
    let link = await act(
      async () => {
const reveal = await browser.elementByCss('#accordion-to-static-page')
        await reveal.click()
        return browser.elementByCss('#to-static-page')
      },
      { includes: 'Static Page [prefetch-sentinel]' }
    )

// Navigate to static page (should use prefetched data with no
additional requests)
    await act(async () => {
      await link.click()
      await browser.waitForElementByCss('#static-page')
    }, 'no-requests')

    // Reveal the "to-home" link and navigate back
// Note: Not using act() here because behavior differs between cache
models.
// With clientSegmentCache, revealing may trigger a prefetch. Without
it, home is already
// cached so no prefetch occurs. Either way, navigation works with
cached data.
    const reveal = await browser.elementByCss('#accordion-to-home')
    await reveal.click()
    const homeLink = await browser.waitForElementByCss('#to-home')
    await homeLink.click()
    await browser.waitForElementByCss('#accordion-to-static-page')

    // Advance time past the stale time
    await timeController.advance(browser, 31000)

// Reveal the static-page link to trigger prefetch and wait for it to
complete
    link = await act(
      async () => {
const reveal = await browser.elementByCss('#accordion-to-static-page')
        await reveal.click()
        return browser.elementByCss('#to-static-page')
      },
      { includes: 'Static Page [prefetch-sentinel]' }
    )

// Navigate to static page again (should use freshly prefetched data
with no additional requests)
    await act(async () => {
      await link.click()
      await browser.waitForElementByCss('#static-page')
    }, 'no-requests')

    // Go back to home (reveal the link and navigate)
// Note: Not using act() here because behavior differs between cache
models.
    const reveal2 = await browser.elementByCss('#accordion-to-home')
    await reveal2.click()
    const homeLink2 = await browser.waitForElementByCss('#to-home')
    await homeLink2.click()
    await browser.waitForElementByCss('#accordion-to-static-page')

// Advance time but not past the stale time (20 seconds < 30 second
stale time - should still be fresh)
    await timeController.advance(browser, 20000)

// Reveal the static-page link to trigger prefetch (should use cached
data, not refetch)
    link = await act(async () => {
const reveal = await browser.elementByCss('#accordion-to-static-page')
      await reveal.click()
      return browser.elementByCss('#to-static-page')
    }, 'no-requests')

// Navigate to static page again (should NOT refetch - stale time should
be renewed)
// If this assertion passes, it means the stale time was properly
renewed after the refetch
    const staticPageText = await act(async () => {
      await link.click()
      return browser.elementByCss('#static-page').text()
    }, 'no-requests')
    expect(staticPageText).toBe('Static Page [prefetch-sentinel]')
  })
})`
- ID 10: `test/e2e/app-dir/app-root-params-getters/use-cache.test.ts` —
`describe('app-root-param-getters - cache dedup with root params', () =>
{
  const { next, isNextDev } = nextTestSetup({
    files: join(__dirname, 'fixtures', 'use-cache-dedup'),
  })

it('should dedupe same root params and isolate different root params',
async () => {
    // Three concurrent requests: ca/en, ca/fr, ca/fr.
    const [$en, $fr1, $fr2] = await Promise.all([
      next.render$('/ca/en'),
      next.render$('/ca/fr'),
      next.render$('/ca/fr'),
    ])

    const randomEn = $en('#random').text()
    const randomFr1 = $fr1('#random').text()
    const randomFr2 = $fr2('#random').text()

    expect(randomEn).toBeTruthy()
    expect(randomFr1).toBeTruthy()

    // ca/en and ca/fr should have different results (isolation).
    expect(randomEn).not.toBe(randomFr1)

    // Both ca/fr requests should have the same result (deduped).
    expect(randomFr1).toBe(randomFr2)
  })

it('should dedupe same root params and isolate different root params for
private caches', async () => {
    // Three concurrent requests: ca/en, ca/fr, ca/fr.
    const [$en, $fr1, $fr2] = await Promise.all([
      next.render$('/ca/en/use-cache-private'),
      next.render$('/ca/fr/use-cache-private'),
      next.render$('/ca/fr/use-cache-private'),
    ])

    const randomEn = $en('#random').text()
    const randomFr1 = $fr1('#random').text()
    const randomFr2 = $fr2('#random').text()

    expect(randomEn).toBeTruthy()
    expect(randomFr1).toBeTruthy()

// Different root params produce different entries, in dev and
production.
    expect(randomEn).not.toBe(randomFr1)

    if (isNextDev) {
// In dev, private caches are persisted and participate in cross-request
// deduplication keyed by root params, so the two ca/fr requests join
one
      // in-flight invocation and share a single fill.
      expect(randomFr1).toBe(randomFr2)
    } else {
// In production, private caches are not persisted and are never deduped
      // across requests, so each ca/fr request generates its own value.
      expect(randomFr1).not.toBe(randomFr2)
    }
  })
})`
- ID 21: `test/e2e/app-dir/cache-components-errors/module-scope.test.ts`
— `describe('Lazy Module Init', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname + '/fixtures/lazy-module-init',
    skipStart: true,
  })

  if (isNextDev) {
    it('does not run in dev', () => {})
    return
  }

it('should build statically even if module scope uses sync APIs like
current time and random', async () => {
    try {
      await next.start()
    } catch {
throw new Error('expected build not to fail for fully static project')
    }

    expect(next.cliOutput).toContain('○ /server')
    expect(next.cliOutput).toContain('○ /client')
    expect(next.cliOutput).toContain('○ /client-page')
    expect(next.cliOutput).toContain('◐ /[dyn]')
    let $

    $ = await next.render$('/server')
    expect($('#id').text().length).toBeGreaterThan(0)

    $ = await next.render$('/client')
    expect($('#id').text().length).toBeGreaterThan(0)

    $ = await next.render$('/client-page')
    expect($('#id').text().length).toBeGreaterThan(0)

    $ = await next.render$('/foo')
    expect($('#id').text().length).toBeGreaterThan(0)

    $ = await next.render$('/serial-client-sync-io')
    expect($('#id').text().length).toBeGreaterThan(0)
  })
})`
- ID 27:
`test/e2e/app-dir/cache-components/cache-components.connection.test.ts`
— `describe('cache-components', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
  })

it('should partially prerender pages that use connection', async () => {
let $ = await next.render$('/connection/static-behavior/boundary', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#foo').text()).toBe('foo')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#foo').text()).toBe('foo')
    }
  })

it('should be able to pass connection as a promise to another component
and trigger an intermediate Suspense boundary', async () => {
const $ = await next.render$('/connection/static-behavior/pass-deeply')
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
// In dev, whether or not the fallback appears in the HTML is unreliable
      // and depends on timing, so we don't assert on its presence
      // (if we want to assert on it, we should use a browser test)
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#fallback').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at runtime')
    }
  })
})`
- ID 28:
`test/e2e/app-dir/cache-components/cache-components.cookies.test.ts` —
`describe('cache-components', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
  })

  it('should partially prerender pages that use cookies', async () => {
    let $ = await next.render$('/cookies/static-behavior', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#x-sentinel').text()).toBe('hello')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#x-sentinel').text()).toBe('hello')
    }
  })

it('should be able to pass cookies as a promise to another component and
trigger an intermediate Suspense boundary', async () => {
    const $ = await next.render$('/cookies/static-behavior/pass-deeply')
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#fallback').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#fallback').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at runtime')
    }
  })

  it('should be able to access cookie properties', async () => {
    let $ = await next.render$('/cookies/exercise', {})
    let cookieWarnings = next.cliOutput
      .split('\n')
      .filter((l) => l.includes('Route "/cookies/exercise'))

    expect(cookieWarnings).toHaveLength(0)

    // For...of iteration
    expect($('#for-of-x-sentinel').text()).toContain('hello')

expect($('#for-of-x-sentinel-path').text()).toContain('/cookies/exercise')

expect($('#for-of-x-sentinel-rand').text()).toContain('x-sentinel-rand')

    // ...spread iteration
    expect($('#spread-x-sentinel').text()).toContain('hello')

expect($('#spread-x-sentinel-path').text()).toContain('/cookies/exercise')

expect($('#spread-x-sentinel-rand').text()).toContain('x-sentinel-rand')

    // cookies().size
expect(parseInt($('#size-cookies').text())).toBeGreaterThanOrEqual(3)

    // cookies().get('...') && cookies().getAll('...')
    expect($('#get-x-sentinel').text()).toContain('hello')
expect($('#get-x-sentinel-path').text()).toContain('/cookies/exercise')
expect($('#get-x-sentinel-rand').text()).toContain('x-sentinel-rand')

    // cookies().has('...')
    expect($('#has-x-sentinel').text()).toContain('true')
    expect($('#has-x-sentinel-foobar').text()).toContain('false')

    // cookies().set('...', '...')
    expect($('#set-result-x-sentinel').text()).toContain(
      'Cookies can only be modified in a Server Action'
    )
    expect($('#set-value-x-sentinel').text()).toContain('hello')

    // cookies().delete('...', '...')
    expect($('#delete-result-x-sentinel').text()).toContain(
      'Cookies can only be modified in a Server Action'
    )
    expect($('#delete-value-x-sentinel').text()).toContain('hello')

    // cookies().clear()
    expect($('#clear-result').text()).toContain(
      'Cookies can only be modified in a Server Action'
    )
    expect($('#clear-value-x-sentinel').text()).toContain('hello')

    // cookies().toString()
    expect($('#toString').text()).toContain('x-sentinel=hello')
    expect($('#toString').text()).toContain('x-sentinel-path')
    expect($('#toString').text()).toContain('x-sentinel-rand=')
  })
})`
- ID 29:
`test/e2e/app-dir/cache-components/cache-components.date.test.ts` —
`describe('cache-components', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
  })

  it('should not have route specific errors', async () => {
    expect(next.cliOutput).not.toMatch('Error: Route "/')
expect(next.cliOutput).not.toMatch('Error occurred prerendering page')
  })

it('should prerender pages with cached `Date.now()` calls', async () =>
{
    let $ = await next.render$('/date/now/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#value').text()).toMatch(/^\d+$/)
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#value').text()).toMatch(/^\d+$/)
    }
  })

  it('should prerender pages with cached `Date()` calls', async () => {
    let $ = await next.render$('/date/date/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#value').text()).toContain('GMT')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#value').text()).toContain('GMT')
    }
  })

it('should prerender pages with cached `new Date()` calls', async () =>
{
    let $ = await next.render$('/date/new-date/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#value').text()).toContain('GMT')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#value').text()).toContain('GMT')
    }
  })

it('should prerender pages with cached static Date instances like `new
Date(0)`', async () => {
    let $ = await next.render$('/date/static-date/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#value').text()).toContain('GMT')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#value').text()).toContain('GMT')
    }
  })

it('should not prerender pages with uncached static Date instances like
`new Date(0)`', async () => {
    let $ = await next.render$('/date/static-date/uncached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#value').text()).toContain('GMT')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#value').text()).toContain('GMT')
    }
  })
})`
- ID 30:
`test/e2e/app-dir/cache-components/cache-components.draft-mode.test.ts`
— `describe('cache-components', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
  })

  let cliIndex = 0
  beforeEach(() => {
    cliIndex = next.cliOutput.length
  })
  function getLines(containing: string): Array<string> {
    const warnings = next.cliOutput
      .slice(cliIndex)
      .split('\n')
      .filter((l) => l.includes(containing))

    cliIndex = next.cliOutput.length
    return warnings
  }

  it('should fully prerender pages that use draftMode', async () => {
    expect(getLines('Route "/draftmode')).toEqual([])
    let $ = await next.render$('/draftmode', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#draft-mode').text()).toBe('false')
      expect(getLines('Route "/draftmode')).toEqual([])
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#draft-mode').text()).toBe('false')
      expect(getLines('Route "/draftmode')).toEqual([])
    }
  })

  if (!isNextDev) {
it('should stream Suspense fallbacks when draft mode is enabled', async
() => {
      const draftRes = await next.fetch('/draftmode/toggle')
      const setCookie = draftRes.headers.get('set-cookie')
      const cookieHeader = { Cookie: setCookie?.split(';', 1)[0] }

      expect(cookieHeader.Cookie).toBeTruthy()

      const $ = await next.render$('/draftmode/streaming', undefined, {
        headers: cookieHeader,
      })

      expect($('#draft-mode').text()).toBe('true')
      expect($('#delayed-runtime-fallback').text()).toBe(
        'Loading draft content...'
      )
    })
  }
})`
- ID 32:
`test/e2e/app-dir/cache-components/cache-components.node-crypto.test.ts`
— `describe('cache-components', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
  })

  it('should not have route specific errors', async () => {
    expect(next.cliOutput).not.toMatch('Error: Route "/')
expect(next.cliOutput).not.toMatch('Error occurred prerendering page')
  })

it("should prerender pages with cached
`require('node:crypto').getRandomValues(...)` calls", async () => {
let $ = await next.render$('/node-crypto/get-random-values/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    }
  })

it("should prerender pages with cached
`require('node:crypto').randomUUID()` calls", async () => {
    let $ = await next.render$('/node-crypto/random-uuid/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    }
  })

it("should prerender pages with cached
`require('node:crypto').randomBytes(size)` calls", async () => {
    let $ = await next.render$('/node-crypto/random-bytes/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    }
  })

it("should prerender pages with cached
`require('node:crypto').randomFillSync(buffer)` calls", async () => {
let $ = await next.render$('/node-crypto/random-fill-sync/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    }
  })

it("should prerender pages with cached
`require('node:crypto').randomInt(max)` calls", async () => {
let $ = await next.render$('/node-crypto/random-int/up-to/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    }
  })

it("should prerender pages with cached
`require('node:crypto').randomInt(min, max)` calls", async () => {
let $ = await next.render$('/node-crypto/random-int/between/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    }
  })

it("should prerender pages with cached
`require('node:crypto').generatePrimeSync(size, options)` calls", async
() => {
let $ = await next.render$('/node-crypto/generate-prime-sync/cached',
{})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    }
  })

it("should prerender pages with cached
`require('node:crypto').generateKeyPairSync(type, options)` calls",
async () => {
let $ = await next.render$('/node-crypto/generate-key-pair-sync/cached',
{})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    }
  })

it("should prerender pages with cached
`require('node:crypto').generateKeySync(type, options)` calls", async ()
=> {
let $ = await next.render$('/node-crypto/generate-key-sync/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    }
  })
})`
- ID 33:
`test/e2e/app-dir/cache-components/cache-components.params.test.ts` —
`describe('cache-components', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
  })

  let cliIndex = 0
  beforeEach(() => {
    cliIndex = next.cliOutput.length
  })
  function getLines(containing: string): Array<string> {
    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<string> = 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
          }
        }
      })
    })
  }
})`
- ID 34:
`test/e2e/app-dir/cache-components/cache-components.random.test.ts` —
`describe('cache-components', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
  })

  it('should not have route specific errors', async () => {
    expect(next.cliOutput).not.toMatch('Error: Route "/')
expect(next.cliOutput).not.toMatch('Error occurred prerendering page')
  })

it('should prerender pages with cached Math.random() calls', async () =>
{
    let $ = await next.render$('/random/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
    }
  })
})`
- ID 35:
`test/e2e/app-dir/cache-components/cache-components.routes.test.ts` —
`describe('cache-components', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
  })

  let cliIndex = 0
  beforeEach(() => {
    cliIndex = next.cliOutput.length
  })
  function getLines(containing: string): Array<string> {
    const warnings = next.cliOutput
      .slice(cliIndex)
      .split('\n')
      .filter((l) => l.includes(containing))

    cliIndex = next.cliOutput.length
    return warnings
  }

it('should not prerender GET route handlers that use dynamic APIs',
async () => {
    let str = await next.render('/routes/dynamic-cookies', {})
    let json = JSON.parse(str)

    expect(json.value).toEqual('at runtime')
    expect(json.type).toEqual('cookies')

    str = await next.render('/routes/dynamic-headers', {})
    json = JSON.parse(str)

    expect(json.value).toEqual('at runtime')
    expect(json.type).toEqual('headers')

    str = await next.render('/routes/dynamic-stream', {})
    json = JSON.parse(str)

    expect(json.value).toEqual('at runtime')
    expect(json.message).toEqual('dynamic stream')

    str = await next.render('/routes/dynamic-url?foo=bar', {})
    json = JSON.parse(str)

    expect(json.value).toEqual('at runtime')
    expect(json.search).toEqual('?foo=bar')
  })

it('should prerender GET route handlers that have entirely cached io
(fetches)', async () => {
    let str = await next.render('/routes/fetch-cached', {})
    let json = JSON.parse(str)

    let random1 = json.random1
    let random2 = json.random2

    if (isNextDev) {
      expect(json.value).toEqual('at runtime')
      expect(typeof random1).toBe('string')
      expect(typeof random2).toBe('string')
    } else {
      expect(json.value).toEqual('at buildtime')
      expect(typeof random1).toBe('string')
      expect(typeof random2).toBe('string')
    }

    str = await next.render('/routes/fetch-cached', {})
    json = JSON.parse(str)

    if (isNextDev) {
      expect(json.value).toEqual('at runtime')
      expect(random1).toEqual(json.random1)
      expect(random2).toEqual(json.random2)
    } else {
      expect(json.value).toEqual('at buildtime')
      expect(random1).toEqual(json.random1)
      expect(random2).toEqual(json.random2)
    }
  })

it('should not prerender GET route handlers that have some uncached io
(fetches)', async () => {
    let str = await next.render('/routes/fetch-mixed', {})
    let json = JSON.parse(str)

    let random1 = json.random1
    let random2 = json.random2

    expect(json.value).toEqual('at runtime')
    expect(typeof random1).toBe('string')
    expect(typeof random2).toBe('string')

    str = await next.render('/routes/fetch-mixed', {})
    json = JSON.parse(str)

    expect(json.value).toEqual('at runtime')
    expect(random1).toEqual(json.random1)
    expect(random2).not.toEqual(json.random2)
  })

it('should prerender GET route handlers that have entirely cached io
(unstable_cache)', async () => {
    let str = await next.render('/routes/io-cached', {})
    let json = JSON.parse(str)

    let message1 = json.message1
    let message2 = json.message2

    if (isNextDev) {
      expect(json.value).toEqual('at runtime')
      expect(typeof message1).toBe('string')
      expect(typeof message2).toBe('string')
    } else {
      expect(json.value).toEqual('at buildtime')
      expect(typeof message1).toBe('string')
      expect(typeof message2).toBe('string')
    }

    str = await next.render('/routes/io-cached', {})
    json = JSON.parse(str)

    if (isNextDev) {
      expect(json.value).toEqual('at runtime')
      expect(message1).toEqual(json.message1)
      expect(message2).toEqual(json.message2)
    } else {
      expect(json.value).toEqual('at buildtime')
      expect(message1).toEqual(json.message1)
      expect(message2).toEqual(json.message2)
    }
  })

it('should prerender GET route handlers that have entirely cached io
("use cache")', async () => {
    let str = await next.render('/routes/use_cache-cached', {})
    let json = JSON.parse(str)

    let message1 = json.message1
    let message2 = json.message2

    if (isNextDev) {
      expect(json.value).toEqual('at runtime')
      expect(typeof message1).toBe('string')
      expect(typeof message2).toBe('string')
    } else {
      expect(json.value).toEqual('at buildtime')
      expect(typeof message1).toBe('string')
      expect(typeof message2).toBe('string')
    }

    str = await next.render('/routes/use_cache-cached', {})
    json = JSON.parse(str)

    if (isNextDev) {
      expect(json.value).toEqual('at runtime')
      expect(message1).toEqual(json.message1)
      expect(message2).toEqual(json.message2)
    } else {
      expect(json.value).toEqual('at buildtime')
      expect(message1).toEqual(json.message1)
      expect(message2).toEqual(json.message2)
    }
  })

it('should not prerender GET route handlers that have some uncached io
(unstable_cache)', async () => {
    let str = await next.render('/routes/io-mixed', {})
    let json = JSON.parse(str)

    let message1 = json.message1
    let message2 = json.message2

    expect(json.value).toEqual('at runtime')
    expect(typeof message1).toBe('string')
    expect(typeof message2).toBe('string')

    str = await next.render('/routes/io-mixed', {})
    json = JSON.parse(str)

    expect(json.value).toEqual('at runtime')
    expect(message1).toEqual(json.message1)
    expect(message2).not.toEqual(json.message2)
  })

it('should prerender GET route handlers that complete synchronously or
in a microtask', async () => {
    let str = await next.render('/routes/microtask', {})
    let json = JSON.parse(str)

    if (isNextDev) {
      expect(json.value).toEqual('at runtime')
      expect(json.message).toBe('microtask')
    } else {
      expect(json.value).toEqual('at buildtime')
      expect(json.message).toBe('microtask')
    }

    str = await next.render('/routes/static-stream-sync', {})
    json = JSON.parse(str)

    if (isNextDev) {
      expect(json.value).toEqual('at runtime')
      expect(json.message).toBe('stream response')
    } else {
      expect(json.value).toEqual('at buildtime')
      expect(json.message).toBe('stream response')
    }

    str = await next.render('/routes/static-stream-async', {})
    json = JSON.parse(str)

    if (isNextDev) {
      expect(json.value).toEqual('at runtime')
      expect(json.message).toBe('stream response')
    } else {
      expect(json.value).toEqual('at buildtime')
      expect(json.message).toBe('stream response')
    }

    str = await next.render('/routes/static-string-sync', {})
    json = JSON.parse(str)

    if (isNextDev) {
      expect(json.value).toEqual('at runtime')
      expect(json.message).toBe('string response')
    } else {
      expect(json.value).toEqual('at buildtime')
      expect(json.message).toBe('string response')
    }

    str = await next.render('/routes/static-string-async', {})
    json = JSON.parse(str)

    if (isNextDev) {
      expect(json.value).toEqual('at runtime')
      expect(json.message).toBe('string response')
    } else {
      expect(json.value).toEqual('at buildtime')
      expect(json.message).toBe('string response')
    }
  })

it('should not prerender GET route handlers that complete in a new
Task', async () => {
    let str = await next.render('/routes/task', {})
    let json = JSON.parse(str)

    expect(json.value).toEqual('at runtime')
    expect(json.message).toBe('task')
  })

it('should prerender GET route handlers when accessing params', async ()
=> {
    expect(getLines('Route "/routes/[dyn]')).toEqual([])
    let str = await next.render('/routes/1', {})
    let json = JSON.parse(str)

    if (isNextDev) {
      expect(json.value).toEqual('at runtime')
      expect(json.type).toBe('dynamic params')
      expect(json.param).toBe('1')
      expect(getLines('Route "/routes/[dyn]')).toEqual([])
    } else {
      expect(json.value).toEqual('at buildtime')
      expect(json.type).toBe('dynamic params')
      expect(json.param).toBe('1')
      expect(getLines('Route "/routes/[dyn]')).toEqual([])
    }

    str = await next.render('/routes/2', {})
    json = JSON.parse(str)

    if (isNextDev) {
      expect(json.value).toEqual('at runtime')
      expect(json.type).toBe('dynamic params')
      expect(json.param).toBe('2')
      expect(getLines('Route "/routes/[dyn]')).toEqual([])
    } else {
      expect(json.value).toEqual('at runtime')
      expect(json.type).toBe('dynamic params')
      expect(json.param).toBe('2')
      expect(getLines('Route "/routes/[dyn]')).toEqual([])
    }
  })
})`
- ID 36:
`test/e2e/app-dir/cache-components/cache-components.search.test.ts` —
`describe('cache-components', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
  })

it('should partially prerender pages that await searchParams in a server
component', async () => {
    let $ = await next.render$('/search/server/await?sentinel=hello')
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#value').text()).toBe('hello')
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('main').text()).toContain('inner loading...')
      expect($('main').text()).not.toContain('outer loading...')
      expect($('#value').text()).toBe('hello')
      expect($('#page').text()).toBe('at runtime')
    }
  })

it('should partially prerender pages that `use` searchParams in a server
component', async () => {
    let $ = await next.render$('/search/server/use?sentinel=hello')
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#value').text()).toBe('hello')
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('main').text()).toContain('inner loading...')
      expect($('main').text()).not.toContain('outer loading...')
      expect($('#value').text()).toBe('hello')
      expect($('#page').text()).toBe('at runtime')
    }
  })

it('should partially prerender pages that `use` searchParams in a client
component', async () => {
    let $ = await next.render$('/search/client/use?sentinel=hello')
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#value').text()).toBe('hello')
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('main').text()).toContain('inner loading...')
      expect($('main').text()).not.toContain('outer loading...')
// 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.
      // expect($('#value').text()).toBe('hello')
      // expect($('#page').text()).toBe('at runtime')
      expect($('#value').text()).toBe('')
      expect($('#page').text()).toBe('')
    }
  })
})`
- ID 37: `test/e2e/app-dir/cache-components/cache-components.test.ts` —
`describe('cache-components', () => {
  const { next, isNextDev, isNextStart } = nextTestSetup({
    files: __dirname,
  })

  it('should not have route specific errors', async () => {
    expect(next.cliOutput).not.toMatch('Error: Route "/')
expect(next.cliOutput).not.toMatch('Error occurred prerendering page')
  })

  if (isNextDev) {
    it('should not log not-found errors', async () => {
      const cliOutputLength = next.cliOutput.length
      await next.browser('/cases/not-found')
      const cliOutput = next.cliOutput.slice(cliOutputLength)
expect(cliOutput).not.toMatch('Error: NEXT_HTTP_ERROR_FALLBACK;404')
      expect(cliOutput).not.toMatch('unhandledRejection')
    })
  } else {
it('should not warn about potential memory leak for even listeners on
AbortSignal', async () => {
      expect(next.cliOutput).not.toMatch('MaxListenersExceededWarning')
    })
  }

  it('should prerender fully static pages', async () => {
    let $ = await next.render$('/cases/static', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
    }

    $ = await next.render$('/cases/static_async', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
    }
  })

  it('should prerender static not-found pages', async () => {
// Using `browser` instead of `render$` because error pages must be
hydrated
    // apparently.
    const browser = await next.browser('/cases/not-found')

    if (isNextDev) {
expect(await browser.elementById('layout').text()).toBe('at runtime')
expect(await browser.elementById('page').text()).toBe('at runtime')
    } else {
expect(await browser.elementById('layout').text()).toBe('at buildtime')
expect(await browser.elementById('page').text()).toBe('at buildtime')
    }
  })

it('should render not-found with Suspense in layout without connection
errors', async () => {
    const browser = await next.browser('/cases/not-found-suspense')

    // The custom not-found component should render
    expect(await browser.elementById('not-found-text').text()).toBe(
      'Custom 404 - Not Found'
    )

    // The async Suspense content in the layout should also render
    expect(await browser.elementById('async-data').text()).toBe(
      'Async Data Loaded'
    )
  })

  it('should prerender pages that render in a microtask', async () => {
    let $ = await next.render$('/cases/microtask', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
    }

    $ = await next.render$('/cases/microtask_deep_tree', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
    }
  })

it('should partially prerender pages that take longer than a task to
render', async () => {
    let $ = await next.render$('/cases/task', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#inner').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      // The inner slot is computed during the prerender but is hidden
      // it gets revealed when the resume happens
      expect($('#inner').text()).toBe('at buildtime')
    }
  })

it('should prerender pages that only use cached fetches', async () => {
    const $ = await next.render$('/cases/fetch_cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
    }
  })

it('should partially prerender pages that use at least one fetch without
cache', async () => {
    let $ = await next.render$('/cases/fetch_mixed', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#inner').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#inner').text()).toBe('at buildtime')
    }
  })

it('should prerender pages that only use cached (unstable_cache) IO',
async () => {
    const $ = await next.render$('/cases/io_cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
    }
  })

it('should prerender pages that only use cached ("use cache") IO', async
() => {
    const $ = await next.render$('/cases/use_cache_cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
    }
  })

  it('should prerender pages that cached the whole page', async () => {
    const $ = await next.render$('/cases/full_cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
    }
  })

it('should partially prerender pages that do any uncached IO', async ()
=> {
    let $ = await next.render$('/cases/io_mixed', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#inner').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#inner').text()).toBe('at buildtime')
    }
  })

it('should partially prerender pages that do any uncached IO (use
cache)', async () => {
    let $ = await next.render$('/cases/use_cache_mixed', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#inner').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#inner').text()).toBe('at buildtime')
    }
  })

it('should partially prerender pages that use `cookies()`', async () =>
{
    let $ = await next.render$('/cases/dynamic_api_cookies', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#inner').text()).toBe('at runtime')
      expect($('#value').text()).toBe('hello')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#inner').text()).toBe('at buildtime')
      expect($('#value').text()).toBe('hello')
    }
  })

it('should partially prerender pages that use `headers()`', async () =>
{
    let $ = await next.render$('/cases/dynamic_api_headers')
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#inner').text()).toBe('at runtime')
      expect($('#value').text()).toBe('hello')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#inner').text()).toBe('at buildtime')
      expect($('#value').text()).toBe('hello')
    }
  })

it('should fully prerender pages that use `unstable_noStore()`', async
() => {
    let $ = await next.render$('/cases/dynamic_api_no_store', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#inner').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#inner').text()).toBe('at buildtime')
    }
  })

it('should partially prerender pages that use `searchParams` in Server
Components', async () => {
    let $ = await next.render$(
      '/cases/dynamic_api_search_params_server?sentinel=my+sentinel',
      {}
    )
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#inner').text()).toBe('at runtime')
      expect($('#value').text()).toBe('my sentinel')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#inner').text()).toBe('at buildtime')
      expect($('#value').text()).toBe('my sentinel')
    }
  })

it('should partially prerender pages that use `searchParams` in Client
Components', async () => {
    let $ = await next.render$(
      '/cases/dynamic_api_search_params_client?sentinel=my+sentinel',
      {}
    )
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#inner').text()).toBe('at runtime')
      expect($('#value').text()).toBe('my sentinel')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
// The second component renders before the first one aborts so we end up
      // capturing the static value during buildtime
      expect($('#inner').text()).toBe('at buildtime')
// Since there was no dynamic data access on this page, the search
params
      // are completely ommitted from the HTML document and filled in by
      // the client
      expect($('#value').text()).toBe('')
      expect($('#fallback-component-one-').text()).toBe('loading...')
    }
  })

it('can prerender pages with parallel routes that are static', async ()
=> {
    const $ = await next.render$('/cases/parallel/static', {})

    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page-slot').text()).toBe('at runtime')
      expect($('#page-children').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page-slot').text()).toBe('at buildtime')
      expect($('#page-children').text()).toBe('at buildtime')
    }
  })

it('can prerender pages with parallel routes that resolve in a
microtask', async () => {
    const $ = await next.render$('/cases/parallel/microtask', {})

    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page-slot').text()).toBe('at runtime')
      expect($('#page-children').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page-slot').text()).toBe('at buildtime')
      expect($('#page-children').text()).toBe('at buildtime')
    }
  })

it('does not prerender pages with parallel routes that resolve in a
task', async () => {
    const $ = await next.render$('/cases/parallel/task', {})

    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page-slot').text()).toBe('at runtime')
      expect($('#page-children').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page-slot').text()).toBe('at runtime')
      expect($('#page-children').text()).toBe('at buildtime')
    }
  })

it('does not prerender pages with parallel routes that uses a dynamic
API', async () => {
    let $ = await next.render$('/cases/parallel/no-store', {})

    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page-slot').text()).toBe('at runtime')
      expect($('#page-children').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page-slot').text()).toBe('at buildtime')
      expect($('#page-children').text()).toBe('at buildtime')
    }

    $ = await next.render$('/cases/parallel/cookies', {})

    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page-slot').text()).toBe('at runtime')
      expect($('#page-children').text()).toBe('at runtime')
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page-slot').text()).toBe('at runtime')
      expect($('#page-children').text()).toBe('at buildtime')
    }
  })

  if (isNextStart) {
it('should ignore late setHeader calls for direct RSC handlers after
headers are sent', async () => {
      const pageModulePath = path.join(
        next.testDir,
        '.next',
        'server',
        'app',
        'cases',
        'static',
        'page.js'
      )
      const previousCwd = process.cwd()
      const port = await findPort()
      let server: http.Server | undefined
      let handlerError: unknown
      let lateHeaderAttempted = false
      let lateHeaderError: unknown
      let resolveHandled: (() => void) | undefined
      const handled = new Promise<void>((resolve) => {
        resolveHandled = resolve
      })

      try {
        process.chdir(next.testDir)

        const { handler } = require(pageModulePath) as {
          handler: (
            req: http.IncomingMessage,
            res: http.ServerResponse,
            ctx: {
              requestMeta?: Record<string, unknown>
              waitUntil?: (promise: Promise<void>) => void
            }
          ) => Promise<void>
        }

        server = http.createServer(async (req, res) => {
          const originalWriteHead = res.writeHead.bind(res)
          res.writeHead = ((...args: any[]) => {
            const result = originalWriteHead(...args)

            if (!lateHeaderAttempted) {
              lateHeaderAttempted = true

              try {
                res.setHeader('x-test-late', '1')
              } catch (error) {
                lateHeaderError = error
              }
            }

            return result
          }) as typeof res.writeHead

          try {
            await handler(req, res, {
              waitUntil: () => {},
              requestMeta: {
                initURL: `https://localhost:${port}${req.url ?? '/'}`,
                minimalMode: true,
                relativeProjectDir: '.',
              },
            })
          } catch (error) {
            handlerError = error

            if (!res.writableEnded) {
              if (!res.headersSent) {
                res.statusCode = 500
              }
              res.end()
            }
          } finally {
            resolveHandled?.()
          }
        })

        await new Promise<void>((resolve, reject) => {
          server.listen(port, () => {
            resolve()
          })
          server.once('error', reject)
        })

        const stateTree = JSON.stringify(['', {}])
const requestUrl = new URL('/cases/static', `http://localhost:${port}`)
        const cacheBustingParam = await computeCacheBustingSearchParam(
          undefined,
          undefined,
          stateTree,
          undefined
        )

        if (cacheBustingParam) {
          requestUrl.searchParams.set('_rsc', cacheBustingParam)
        }

        const res = await fetchViaHTTP(
          port,
          requestUrl.pathname + requestUrl.search,
          undefined,
          {
            headers: {
              rsc: '1',
              'next-router-state-tree': stateTree,
            },
            redirect: 'manual',
          }
        )
        const flight = await res.text()

        expect(res.status).toBe(200)
expect(res.headers.get('content-type')).toContain('text/x-component')
        await handled

        expect(handlerError).toBeUndefined()
        expect(lateHeaderAttempted).toBe(true)
        expect(lateHeaderError).toBeUndefined()
        expect(flight.length).toBeGreaterThan(0)
      } finally {
        process.chdir(previousCwd)

        if (server) {
          await new Promise<void>((resolve, reject) => {
            server.close((error) => {
              if (error) {
                reject(error)
                return
              }

              resolve()
            })
          })
        }
      }
    })
  }

it('should not resume when client components are dynamic but the RSC
render was static', async () => {
    let html = await next.render('/cases/static-rsc-dynamic-client', {})
    const $ = cheerio.load(html)

    // Confirm the HTML document was sent completely
    expect(html).toContain('</body></html>')

    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      // In dev we SSR the time
      expect($('#time').length).toBe(1)
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
// Confirm the time span is not part of the completed HTML document
      expect($('#time').length).toBe(0)
    }

const browser = await next.browser('/cases/static-rsc-dynamic-client')

    const now = new Date()

    if (isNextDev) {
expect(await browser.elementById('layout').text()).toBe('at runtime')
expect(await browser.elementById('page').text()).toBe('at runtime')
      // Assert that we rendered a time within the last couple seconds.
      const inPageDate = new Date(
        await browser.waitForElementByCss('#time').text()
      )
      expect(inPageDate.getTime() - now.getTime()).toBeLessThan(2000)
    } else {
expect(await browser.elementById('layout').text()).toBe('at buildtime')
expect(await browser.elementById('page').text()).toBe('at buildtime')
      // Assert that we rendered a time within the last 2 seconds.
      const inPageDate = new Date(
        await browser.waitForElementByCss('#time').text()
      )
      expect(inPageDate.getTime() - now.getTime()).toBeLessThan(2000)
    }
  })
})`
- ID 38:
`test/e2e/app-dir/cache-components/cache-components.web-crypto.test.ts`
— `describe('cache-components', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
  })

  it('should not have route specific errors', async () => {
    expect(next.cliOutput).not.toMatch('Error: Route "/')
expect(next.cliOutput).not.toMatch('Error occurred prerendering page')
  })

it('should prerender pages with cached `crypto.getRandomValues(...)`
calls', async () => {
let $ = await next.render$('/web-crypto/get-random-values/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    }
  })

it('should prerender pages with cached `crypto.randomUUID()` calls',
async () => {
    let $ = await next.render$('/web-crypto/random-uuid/cached', {})
    if (isNextDev) {
      expect($('#layout').text()).toBe('at runtime')
      expect($('#page').text()).toBe('at runtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    } else {
      expect($('#layout').text()).toBe('at buildtime')
      expect($('#page').text()).toBe('at buildtime')
      expect($('#first').text()).not.toEqual($('#second').text())
    }
  })
})`
- ID 40:
`test/e2e/app-dir/instant-validation-static-shells/instant-validation-static-shells.test.ts`
— `describe('instant validation - opting out of static shells', () => {
  const { next, isNextDev } = nextTestSetup({
    files: join(__dirname, 'fixtures', 'valid'),
  })

// NOTE: if something's wrong in build, we'll fail before any tests run.
  // Visiting the pages is mostly just a sanity check.

it('does not require a static shell if a root layouts is configured as
blocking', async () => {
    const browser = await next.browser('/blocking-root-layout')
    await browser.elementByCss('main')
    if (isNextDev) await waitForNoErrorToast(browser)
  })
it('does not require a static shell if a layout is configured as
blocking', async () => {
    const browser = await next.browser('/blocking-layout')
    await browser.elementByCss('main')
    if (isNextDev) await waitForNoErrorToast(browser)
  })
it('does not require a static shell if a page is configured as
blocking', async () => {
    const browser = await next.browser('/blocking-page')
    await browser.elementByCss('main')
    if (isNextDev) await waitForNoErrorToast(browser)
  })
})`
- ID 42:
`test/e2e/app-dir/non-rsc-router-prefetch/non-rsc-router-prefetch.test.ts`
— `describe('non-rsc-router-prefetch', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

  beforeAll(async () => {
    const res = await next.fetch('/')
    await res.text()
  })

it('ignores the router prefetch header for HTML requests', async () => {
    const res = await next.fetch('/', {
      headers: {
        [NEXT_ROUTER_PREFETCH_HEADER]: '1',
      },
      signal: AbortSignal.timeout(5_000),
    })
    const html = await res.text()

    expect(res.status).toBe(200)
    expect(res.headers.get('content-type')).toContain('text/html')
    expect(html).toContain('hello world')
  })

  it('honors the router prefetch header for RSC requests', async () => {
    const res = await next.fetch('/', {
      headers: {
        [RSC_HEADER]: '1',
        [NEXT_ROUTER_PREFETCH_HEADER]: '1',
      },
    })

    expect(res.status).toBe(200)
expect(res.headers.get('content-type')).toContain('text/x-component')
  })
})`
- ID 56:
`test/e2e/app-dir/use-cache-infinity-profile/use-cache-infinity-profile.test.ts`
— `describe('use-cache-infinity-profile', () => {
  const { next, isNextStart } = nextTestSetup({
    files: __dirname,
  })

it('caches forever with a configured profile using Infinity revalidate
and expire', async () => {
    const $ = await next.render$('/')
    const initialValue = $('#value').text()
    expect(initialValue).toMatch(uuidRegExp)

// An infinite cache life must not degrade into a dynamic cache life, so
    // the value stays the same across requests instead of regenerating.
    const $second = await next.render$('/')
    expect($second('#value').text()).toBe(initialValue)

    if (isNextStart) {
      // The page must be fully prerendered at build time.
const prerendered = await next.readFile('.next/server/app/index.html')
      expect(prerendered).toContain(initialValue)
    }
  })

it('serves an inline Infinity cache life from a JSON-backed cache
handler across requests', async () => {
    const $ = await next.render$('/inline?key=a')
    const initialValue = $('#value').text()
    expect(initialValue).toMatch(uuidRegExp)

// The second request reads the entry back from the cache handler. If
the
// infinite cache life doesn't survive the handler's JSON round trip,
the
// entry is treated as immediately expired and the value regenerates.
    const $second = await next.render$('/inline?key=a')
    expect($second('#value').text()).toBe(initialValue)
  })
})`
- ID 57:
`test/e2e/app-dir/use-cache-og-image-top-level-await/use-cache-og-image-top-level-await.test.ts`
— `describe('use-cache-og-image-top-level-await', () => {
  const { next, isNextStart } = nextTestSetup({
    files: __dirname,
    skipStart: true,
  })

  if (isNextStart) {
    beforeAll(async () => {
await next.build({ args: ['--experimental-build-mode', 'compile'] })
    })

it('should prerender a page whose opengraph image uses a top-level
await', async () => {
      const { exitCode, cliOutput } = await next.build({
        args: [
          '--experimental-build-mode',
          'generate',
          '--debug-build-paths',
          'app/[slug]/page.tsx,app/[slug]/opengraph-image.tsx',
        ],
      })

      expect(cliOutput).not.toContain(
        'Unexpected cache miss after cache warming phase'
      )
      expect(cliOutput).not.toContain(
'Next.js encountered uncached or runtime data in `generateMetadata()`'
      )
      expect(exitCode).toBe(0)

// The image route uses generateStaticParams, so the build is expected
      // to prerender it for each param.
      expect(cliOutput).toMatch(/● \/first-post\/opengraph-image/)
      expect(cliOutput).toMatch(/● \/second-post\/opengraph-image/)
    })
  } else {
    beforeAll(async () => {
      await next.start()
    })

it('should render a page whose opengraph image uses a top-level await',
async () => {
      const $ = await next.render$('/first-post')
      expect($('article').text()).toBe('First Post')

      const res = await next.fetch('/first-post/opengraph-image')
      expect(res.status).toBe(200)
      expect(res.headers.get('content-type')).toBe('image/png')
    })
  }
})`
- ID 58:
`test/e2e/app-dir/use-cache-output-export/use-cache-output-export.test.ts`
— `describe('use-cache-output-export', () => {
  const { next, isNextStart } = nextTestSetup({
    files: __dirname,
    skipStart: process.env.NEXT_TEST_MODE !== 'dev',
  })

  if (process.env.__NEXT_CACHE_COMPONENTS === 'true') {
    return it.skip('for PPR', () => {
      // PPR is not compatible with `output: 'export'`.
    })
  }

  it('should work', async () => {
    let html: string
    let server: Server | undefined

    if (isNextStart) {
      const { cliOutput } = await next.build()

      expect(cliOutput).not.toInclude(
        'Server Actions are not supported with static export.'
      )

      server = await startCleanStaticServer(join(next.testDir, 'out'))
      const { port } = server.address() as AddressInfo
      html = await renderViaHTTP(port, '/')
    } else {
      html = await next.render('/')
    }

    expect(html).toMatch(/<p>[0,1]\.\d+<\/p>/)

    if (server) {
      await new Promise((resolve) => server.close(resolve))
    }
  })
})`

</details>

<details>
<summary>Deployment evidence for the additional scopes</summary>

- `test/e2e/app-dir/app-prefetch/prefetching.stale-times.test.ts` —
`describe('app dir - prefetching (custom staleTime)', () => {`:
[normal](https://github.com/vercel/next.js/actions/runs/34426785098/job/102728710370);
Cache Components excluded by manifest.
- `test/e2e/app-dir/cache-components-errors/module-scope.test.ts` —
`describe('Lazy Module Init', () => {`:
[normal](https://github.com/vercel/next.js/actions/runs/34426785098/job/102728710410);
Cache Components excluded by manifest.
- `test/e2e/app-dir/cache-components/cache-components.params.test.ts` —
`describe('cache-components', () => {`:
[normal](https://github.com/vercel/next.js/actions/runs/34426785098/job/102728710449);
Cache Components excluded by manifest.
-
`test/e2e/app-dir/instant-validation-static-shells/instant-validation-static-shells.test.ts`
— `describe('instant validation - opting out of static shells', () =>
{`:
[normal](https://github.com/vercel/next.js/actions/runs/34426785098/job/102728710456),
[cache](https://github.com/vercel/next.js/actions/runs/34426785098/job/102728710457).
-
`test/e2e/app-dir/use-cache-output-export/use-cache-output-export.test.ts`
— `describe('use-cache-output-export', () => {`:
[normal](https://github.com/vercel/next.js/actions/runs/34426785098/job/102728710496),
[cache](https://github.com/vercel/next.js/actions/runs/34426785098/job/102728710503);
Cache Components explicitly skipped for PPR.

</details>

<!-- NEXT_JS_LLM -->
2026-09-15 10:29:05 -07:00
..