Repository: vercel/next.js
File: test/e2e/app-dir/instant-validation/instant-validation.test.ts (TypeScript)

Code before:
        '/suspense-in-root/runtime/invalid-sync-io-in-generate-metadata'
      )
      await expect(browser).toDisplayCollapsedRedbox(`
       {
         "description": "Route "/suspense-in-root/runtime/invalid-sync-io-in-generate-metadata" used \`Date.now()\` before accessing either uncached data (e.g. \`fetch()\`) or awaiting \`connection()\`. When configured for Runtime prefetching, accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-runtime-current-time",
         "environmentLabel": "Server",
         "label": "Console Error",
         "source": "app/suspense-in-root/runtime/invalid-sync-io-in-generate-metadata/page.tsx (11:20) @ Module.generateMetadata
       > 11 |   const now = Date.now()
            |                    ^",
         "stack": [
           "Module.generateMetadata app/suspense-in-root/runtime/invalid-sync-io-in-generate-metadata/page.tsx (11:20)",
           "Next.MetadataOutlet <anonymous>",
         ],
       }
      `)
    })

    it('valid - runtime prefetch - sync IO in generateMetadata on a static page is allowed', async () => {
      // The page does NOT have runtime prefetch. generateMetadata uses
      // cookies() then Date.now(). Since no segment is runtime-prefetchable,
      // sync IO in generateMetadata should be allowed.
      const browser = await navigateTo(
        '/suspense-in-root/runtime/valid-sync-io-in-generate-metadata-static-page'
      )
      await waitForNoErrorToast(browser)
    })

    it('invalid - runtime prefetch - sync IO in layout generateMetadata when page is prefetchable', async () => {
      // The layout has generateMetadata with sync IO after cookies().
      // The layout itself does NOT have runtime prefetch, but the child
      // page does. Since metadata belongs to the Page, and the Page is
      // runtime-prefetchable, sync IO in the layout's generateMetadata
      // should error.
      const browser = await navigateTo(
        '/suspense-in-root/runtime/invalid-sync-io-in-layout-generate-metadata'
      )
      await expect(browser).toDisplayCollapsedRedbox(`
       {
         "description": "Route "/suspense-in-root/runtime/invalid-sync-io-in-layout-generate-metadata" used \`Date.now()\` before accessing either uncached data (e.g. \`fetch()\`) or awaiting \`connection()\`. When configured for Runtime prefetching, accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-runtime-current-time",
         "environmentLabel": "Server",
         "label": "Console Error",
         "source": "app/suspense-in-root/runtime/invalid-sync-io-in-layout-generate-metadata/layout.tsx (11:20) @ Module.generateMetadata
       > 11 |   const now = Date.now()
            |                    ^",
         "stack": [
           "Module.generateMetadata app/suspense-in-root/runtime/invalid-sync-io-in-layout-generate-metadata/layout.tsx (11:20)",
           "Next.MetadataOutlet <anonymous>",
         ],
       }
      `)

Review comment (suggestion):
should rebase and use `await expectNoValidationErrors(browser, await browser.url())` instead (added in #90214, it's much faster)

Code after:
           |                  ^",
         "stack": [
           "Page app/suspense-in-root/static/missing-suspense-around-search-params/page.tsx (4:18)",
         ],
       }
      `)
    })

    it('valid - runtime prefetch - does not require Suspense around search params', async () => {
      const browser = await navigateTo(
        '/suspense-in-root/runtime/valid-no-suspense-around-search-params?foo=bar'
      )
      await expectNoValidationErrors(browser, await browser.url())
    })

    it('valid - target segment not visible in all navigations', async () => {
      // Notable special case -- we accept that the segment with the assertion might not
      // *itself* be visible in all navigations as long as they're instant.
      // A parent layout might be blocked from rendering the children slot,
      // but that's fine as long as it provides a fallback.
      //
      // This is in opposition to an alternate model we considered at some point,
      // where putting an assertion on a segment would mean that it must be visible
      // in all navigations (which would require that its parent layouts must never
      // block the children slots)
      const browser = await navigateTo('/default/static/valid-blocked-children')
      await expectNoValidationErrors(browser, await browser.url())
    })

    it('invalid - static prefetch - suspense too high', async () => {
      const browser = await navigateTo(
        '/suspense-in-root/static/suspense-too-high'
      )
      await expect(browser).toDisplayCollapsedRedbox(`
       {
         "cause": [
           {
             "label": "Caused by: Instant Validation",
             "source": "app/suspense-in-root/static/suspense-too-high/page.tsx (3:33) @ unstable_instant
       > 3 | export const unstable_instant = { prefetch: 'static' }
           |                                 ^",
             "stack": [
               "unstable_instant app/suspense-in-root/static/suspense-too-high/page.tsx (3:33)",
               "Set.forEach <anonymous>",
             ],
           },
         ],
         "description": "Runtime data was accessed outside of <Suspense>

       This delays the entire page from rendering, resulting in a slow user experience. Next.js uses this error to ensure your app loads instantly on every navigation. cookies(), headers(), and searchParams, are examples of Runtime data that can only come from a user request.