diff --git a/test/e2e/app-dir/use-cache/app/(suspense)/layout.tsx b/test/e2e/app-dir/use-cache/app/(suspense)/layout.tsx deleted file mode 100644 index 2d8f3d5939bc0..0000000000000 --- a/test/e2e/app-dir/use-cache/app/(suspense)/layout.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { Suspense } from 'react' - -export default function Root({ children }: { children: React.ReactNode }) { - return ( - - - {children} - - - ) -} diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/[id]/page.tsx b/test/e2e/app-dir/use-cache/app/[id]/page.tsx similarity index 67% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/[id]/page.tsx rename to test/e2e/app-dir/use-cache/app/[id]/page.tsx index 2962d2b3c239c..74f4ed6d08dc3 100644 --- a/test/e2e/app-dir/use-cache/app/(no-suspense)/[id]/page.tsx +++ b/test/e2e/app-dir/use-cache/app/[id]/page.tsx @@ -4,7 +4,10 @@ async function getCachedRandom(n: number) { } export async function generateStaticParams() { - return [{ id: await getCachedRandom(10) }, { id: await getCachedRandom(2) }] + return [ + { id: `a${await getCachedRandom(9)}` }, + { id: `b${await getCachedRandom(2)}` }, + ] } export default async function Page() { diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/api/route.ts b/test/e2e/app-dir/use-cache/app/api/route.ts similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/api/route.ts rename to test/e2e/app-dir/use-cache/app/api/route.ts diff --git a/test/e2e/app-dir/use-cache/app/(suspense)/cache-fetch-auth-header/page.tsx b/test/e2e/app-dir/use-cache/app/cache-fetch-auth-header/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(suspense)/cache-fetch-auth-header/page.tsx rename to test/e2e/app-dir/use-cache/app/cache-fetch-auth-header/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/cache-fetch-no-store/page.tsx b/test/e2e/app-dir/use-cache/app/cache-fetch-no-store/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/cache-fetch-no-store/page.tsx rename to test/e2e/app-dir/use-cache/app/cache-fetch-no-store/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/cache-fetch/page.tsx b/test/e2e/app-dir/use-cache/app/cache-fetch/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/cache-fetch/page.tsx rename to test/e2e/app-dir/use-cache/app/cache-fetch/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/cache-life/page.tsx b/test/e2e/app-dir/use-cache/app/cache-life/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/cache-life/page.tsx rename to test/e2e/app-dir/use-cache/app/cache-life/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/cache-tag/buttons.tsx b/test/e2e/app-dir/use-cache/app/cache-tag/buttons.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/cache-tag/buttons.tsx rename to test/e2e/app-dir/use-cache/app/cache-tag/buttons.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/cache-tag/page.tsx b/test/e2e/app-dir/use-cache/app/cache-tag/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/cache-tag/page.tsx rename to test/e2e/app-dir/use-cache/app/cache-tag/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(suspense)/complex-args/page.tsx b/test/e2e/app-dir/use-cache/app/complex-args/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(suspense)/complex-args/page.tsx rename to test/e2e/app-dir/use-cache/app/complex-args/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(suspense)/custom-handler/page.tsx b/test/e2e/app-dir/use-cache/app/custom-handler/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(suspense)/custom-handler/page.tsx rename to test/e2e/app-dir/use-cache/app/custom-handler/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(suspense)/errors/error-boundary.tsx b/test/e2e/app-dir/use-cache/app/errors/error-boundary.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(suspense)/errors/error-boundary.tsx rename to test/e2e/app-dir/use-cache/app/errors/error-boundary.tsx diff --git a/test/e2e/app-dir/use-cache/app/(suspense)/errors/page.tsx b/test/e2e/app-dir/use-cache/app/errors/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(suspense)/errors/page.tsx rename to test/e2e/app-dir/use-cache/app/errors/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(suspense)/errors/util.ts b/test/e2e/app-dir/use-cache/app/errors/util.ts similarity index 100% rename from test/e2e/app-dir/use-cache/app/(suspense)/errors/util.ts rename to test/e2e/app-dir/use-cache/app/errors/util.ts diff --git a/test/e2e/app-dir/use-cache/app/(suspense)/fetch-revalidate/page.tsx b/test/e2e/app-dir/use-cache/app/fetch-revalidate/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(suspense)/fetch-revalidate/page.tsx rename to test/e2e/app-dir/use-cache/app/fetch-revalidate/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/form/page.tsx b/test/e2e/app-dir/use-cache/app/form/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/form/page.tsx rename to test/e2e/app-dir/use-cache/app/form/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/imported-from-client/cached.ts b/test/e2e/app-dir/use-cache/app/imported-from-client/cached.ts similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/imported-from-client/cached.ts rename to test/e2e/app-dir/use-cache/app/imported-from-client/cached.ts diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/imported-from-client/page.tsx b/test/e2e/app-dir/use-cache/app/imported-from-client/page.tsx similarity index 80% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/imported-from-client/page.tsx rename to test/e2e/app-dir/use-cache/app/imported-from-client/page.tsx index b0d264669ce36..dc0a8c9ebd5aa 100644 --- a/test/e2e/app-dir/use-cache/app/(no-suspense)/imported-from-client/page.tsx +++ b/test/e2e/app-dir/use-cache/app/imported-from-client/page.tsx @@ -1,7 +1,7 @@ 'use client' import { foo, bar, baz } from './cached' -import { Form } from '../../form' +import { Form } from '../form' export default function Page() { return
diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/layout.tsx b/test/e2e/app-dir/use-cache/app/layout.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/layout.tsx rename to test/e2e/app-dir/use-cache/app/layout.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/logs/page.tsx b/test/e2e/app-dir/use-cache/app/logs/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/logs/page.tsx rename to test/e2e/app-dir/use-cache/app/logs/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/method-props/cached.ts b/test/e2e/app-dir/use-cache/app/method-props/cached.ts similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/method-props/cached.ts rename to test/e2e/app-dir/use-cache/app/method-props/cached.ts diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/method-props/form.tsx b/test/e2e/app-dir/use-cache/app/method-props/form.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/method-props/form.tsx rename to test/e2e/app-dir/use-cache/app/method-props/form.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/method-props/page.tsx b/test/e2e/app-dir/use-cache/app/method-props/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/method-props/page.tsx rename to test/e2e/app-dir/use-cache/app/method-props/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/not-found/page.tsx b/test/e2e/app-dir/use-cache/app/not-found/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/not-found/page.tsx rename to test/e2e/app-dir/use-cache/app/not-found/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(suspense)/page.tsx b/test/e2e/app-dir/use-cache/app/page.tsx similarity index 94% rename from test/e2e/app-dir/use-cache/app/(suspense)/page.tsx rename to test/e2e/app-dir/use-cache/app/page.tsx index 9aa93354ed958..ebe11f94e23a8 100644 --- a/test/e2e/app-dir/use-cache/app/(suspense)/page.tsx +++ b/test/e2e/app-dir/use-cache/app/page.tsx @@ -1,4 +1,4 @@ -import { Foo } from '../client' +import { Foo } from './client' async function getCachedRandom(x: number, children: React.ReactNode) { 'use cache' diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/passed-to-client/page.tsx b/test/e2e/app-dir/use-cache/app/passed-to-client/page.tsx similarity index 93% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/passed-to-client/page.tsx rename to test/e2e/app-dir/use-cache/app/passed-to-client/page.tsx index b54f6412ed721..529547e8f8d01 100644 --- a/test/e2e/app-dir/use-cache/app/(no-suspense)/passed-to-client/page.tsx +++ b/test/e2e/app-dir/use-cache/app/passed-to-client/page.tsx @@ -1,4 +1,4 @@ -import { Form } from '../../form' +import { Form } from '../form' function getRandomValue() { const v = Math.random() diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/react-cache/page.tsx b/test/e2e/app-dir/use-cache/app/react-cache/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/react-cache/page.tsx rename to test/e2e/app-dir/use-cache/app/react-cache/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/static-class-method/cached.ts b/test/e2e/app-dir/use-cache/app/static-class-method/cached.ts similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/static-class-method/cached.ts rename to test/e2e/app-dir/use-cache/app/static-class-method/cached.ts diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/static-class-method/form.tsx b/test/e2e/app-dir/use-cache/app/static-class-method/form.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/static-class-method/form.tsx rename to test/e2e/app-dir/use-cache/app/static-class-method/form.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/static-class-method/page.tsx b/test/e2e/app-dir/use-cache/app/static-class-method/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/static-class-method/page.tsx rename to test/e2e/app-dir/use-cache/app/static-class-method/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/use-action-state/cached.ts b/test/e2e/app-dir/use-cache/app/use-action-state/cached.ts similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/use-action-state/cached.ts rename to test/e2e/app-dir/use-cache/app/use-action-state/cached.ts diff --git a/test/e2e/app-dir/use-cache/app/(no-suspense)/use-action-state/page.tsx b/test/e2e/app-dir/use-cache/app/use-action-state/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(no-suspense)/use-action-state/page.tsx rename to test/e2e/app-dir/use-cache/app/use-action-state/page.tsx diff --git a/test/e2e/app-dir/use-cache/app/(suspense)/with-server-action/form.tsx b/test/e2e/app-dir/use-cache/app/with-server-action/form.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(suspense)/with-server-action/form.tsx rename to test/e2e/app-dir/use-cache/app/with-server-action/form.tsx diff --git a/test/e2e/app-dir/use-cache/app/(suspense)/with-server-action/page.tsx b/test/e2e/app-dir/use-cache/app/with-server-action/page.tsx similarity index 100% rename from test/e2e/app-dir/use-cache/app/(suspense)/with-server-action/page.tsx rename to test/e2e/app-dir/use-cache/app/with-server-action/page.tsx diff --git a/test/e2e/app-dir/use-cache/next.config.js b/test/e2e/app-dir/use-cache/next.config.js index ed836e3b2d455..4364cab19bb93 100644 --- a/test/e2e/app-dir/use-cache/next.config.js +++ b/test/e2e/app-dir/use-cache/next.config.js @@ -3,6 +3,7 @@ */ const nextConfig = { experimental: { + ppr: process.env.__NEXT_EXPERIMENTAL_PPR === 'true', useCache: true, cacheLife: { frequent: { diff --git a/test/e2e/app-dir/use-cache/use-cache.test.ts b/test/e2e/app-dir/use-cache/use-cache.test.ts index 84d9bb9ef8b65..409f3ec036a62 100644 --- a/test/e2e/app-dir/use-cache/use-cache.test.ts +++ b/test/e2e/app-dir/use-cache/use-cache.test.ts @@ -277,6 +277,49 @@ describe('use-cache', () => { } if (isNextStart) { + it('should prerender fully cacheable pages as static HTML', async () => { + const prerenderManifest = JSON.parse( + await next.readFile('.next/prerender-manifest.json') + ) + + let prerenderedRoutes = Object.keys(prerenderManifest.routes).sort() + + if (process.env.__NEXT_EXPERIMENTAL_PPR === 'true') { + // For the purpose of this test we don't consider an incomplete shell. + prerenderedRoutes = prerenderedRoutes.filter((route) => { + const filename = route.replace(/^\//, '').replace(/^$/, 'index') + + return next + .readFileSync(`.next/server/app/${filename}.html`) + .endsWith('') + }) + } + + expect(prerenderedRoutes).toEqual([ + // [id] route, first entry in generateStaticParams + expect.stringMatching(/\/a\d/), + // [id] route, second entry in generateStaticParams + expect.stringMatching(/\/b\d/), + '/cache-fetch', + '/cache-fetch-no-store', + '/cache-life', + '/cache-tag', + // TODO(useCache): Should be prerendered when NAR-85 is fixed. + // '/form', + '/imported-from-client', + '/logs', + '/method-props', + // TODO(useCache): Should be prerendered when NAR-85 is fixed. + // '/not-found', + '/passed-to-client', + '/react-cache', + '/static-class-method', + '/use-action-state', + // TODO(useCache): Should be prerendered when NAR-85 is fixed. + // '/with-server-action', + ]) + }) + it('should match the expected revalidate config on the prerender manifest', async () => { const prerenderManifest = JSON.parse( await next.readFile('.next/prerender-manifest.json') diff --git a/test/lib/next-modes/base.ts b/test/lib/next-modes/base.ts index ec86ad7d75510..461b3426ad0b2 100644 --- a/test/lib/next-modes/base.ts +++ b/test/lib/next-modes/base.ts @@ -1,6 +1,6 @@ import os from 'os' import path from 'path' -import { existsSync, promises as fs, rmSync } from 'fs' +import { existsSync, promises as fs, rmSync, readFileSync } from 'fs' import treeKill from 'tree-kill' import type { NextConfig } from 'next' import { FileRef, isNextDeploy } from '../e2e-utils' @@ -521,6 +521,10 @@ export class NextInstance { return fs.readFile(path.join(this.testDir, filename), 'utf8') } + public readFileSync(filename: string) { + return readFileSync(path.join(this.testDir, filename), 'utf8') + } + public async readJSON(filename: string) { return JSON.parse( await fs.readFile(path.join(this.testDir, filename), 'utf-8')