diff --git a/test/e2e/app-dir/autoscroll-with-css-modules/app/layout.tsx b/test/e2e/app-dir/autoscroll-with-css-modules/app/layout.tsx
index 8a4dca4e78301..e969c82dc2a32 100644
--- a/test/e2e/app-dir/autoscroll-with-css-modules/app/layout.tsx
+++ b/test/e2e/app-dir/autoscroll-with-css-modules/app/layout.tsx
@@ -1,12 +1,16 @@
+import { Suspense } from 'react'
+
export default function Layout({ children }: any) {
return (
-
-
{children}
-
+
-
-
-
+
+
+
-
-
- {children}
-
-
+
+
+
+ {children}
+
+
+
)
}
diff --git a/test/e2e/app-dir/router-autoscroll/app/loading-scroll/page.tsx b/test/e2e/app-dir/router-autoscroll/app/loading-scroll/page.tsx
index fef9fe6315f9b..b70fac07da7fa 100644
--- a/test/e2e/app-dir/router-autoscroll/app/loading-scroll/page.tsx
+++ b/test/e2e/app-dir/router-autoscroll/app/loading-scroll/page.tsx
@@ -1,7 +1,5 @@
import Link from 'next/link'
-export const dynamic = 'force-dynamic'
-
export default async function Page(props: PageProps<'/loading-scroll'>) {
const search = await props.searchParams
const skipSleep = !!search.skipSleep
diff --git a/test/e2e/app-dir/router-autoscroll/next.config.js b/test/e2e/app-dir/router-autoscroll/next.config.js
index 4ba52ba2c8df6..36e8d82ea1afd 100644
--- a/test/e2e/app-dir/router-autoscroll/next.config.js
+++ b/test/e2e/app-dir/router-autoscroll/next.config.js
@@ -1 +1,6 @@
-module.exports = {}
+/**
+ * @type {import('next').NextConfig}
+ */
+const config = {}
+
+module.exports = config
diff --git a/test/e2e/app-dir/router-autoscroll/router-autoscroll.test.ts b/test/e2e/app-dir/router-autoscroll/router-autoscroll.test.ts
index 03379d79da82e..22040eafe2152 100644
--- a/test/e2e/app-dir/router-autoscroll/router-autoscroll.test.ts
+++ b/test/e2e/app-dir/router-autoscroll/router-autoscroll.test.ts
@@ -1,7 +1,10 @@
-import webdriver, { type Playwright } from 'next-webdriver'
+import type { Playwright } from 'next-webdriver'
import { nextTestSetup } from 'e2e-utils'
import { check, assertNoConsoleErrors, retry } from 'next-test-utils'
+const isClientSegmentCacheEnabled =
+ process.env.__NEXT_EXPERIMENTAL_PPR === 'true'
+
describe('router autoscrolling on navigation', () => {
const { next, isNextDev } = nextTestSetup({
files: __dirname,
@@ -17,7 +20,7 @@ describe('router autoscrolling on navigation', () => {
browser: Playwright,
options: { x: number; y: number }
) => {
- await retry(async () => {
+ await retry(async function expectScrolledTo() {
const top = await getTopScroll(browser)
const left = await getLeftScroll(browser)
expect({ top, left }).toEqual({ top: options.y, left: options.x })
@@ -35,17 +38,16 @@ describe('router autoscrolling on navigation', () => {
describe('vertical scroll', () => {
it('should scroll to top of document when navigating between to pages without layout', async () => {
- const browser = await webdriver(next.url, '/0/0/100/10000/page1')
+ const browser = await next.browser('/0/0/100/10000/page1')
await scrollTo(browser, { x: 0, y: 1000 })
- expect(await getTopScroll(browser)).toBe(1000)
await browser.eval(`window.router.push("/0/0/100/10000/page2")`)
await waitForScrollToComplete(browser, { x: 0, y: 0 })
})
it("should scroll to top of page when scrolling to phe top of the document wouldn't have the page in the viewport", async () => {
- const browser = await webdriver(next.url, '/0/1000/100/1000/page1')
+ const browser = await next.browser('/0/1000/100/1000/page1')
await scrollTo(browser, { x: 0, y: 1500 })
expect(await getTopScroll(browser)).toBe(1500)
@@ -55,7 +57,7 @@ describe('router autoscrolling on navigation', () => {
})
it("should scroll down to the navigated page when it's below viewort", async () => {
- const browser = await webdriver(next.url, '/0/1000/100/1000/page1')
+ const browser = await next.browser('/0/1000/100/1000/page1')
expect(await getTopScroll(browser)).toBe(0)
await browser.eval(`window.router.push("/0/1000/100/1000/page2")`)
@@ -63,37 +65,34 @@ describe('router autoscrolling on navigation', () => {
})
it('should not scroll when the top of the page is in the viewport', async () => {
- const browser = await webdriver(next.url, '/10/1000/100/1000/page1')
+ const browser = await next.browser('/10/1000/100/1000/page1')
await scrollTo(browser, { x: 0, y: 800 })
- expect(await getTopScroll(browser)).toBe(800)
await browser.eval(`window.router.push("/10/1000/100/1000/page2")`)
await waitForScrollToComplete(browser, { x: 0, y: 800 })
})
it('should not scroll to top of document if page in viewport', async () => {
- const browser = await webdriver(next.url, '/10/100/100/1000/page1')
+ const browser = await next.browser('/10/100/100/1000/page1')
await scrollTo(browser, { x: 0, y: 50 })
- expect(await getTopScroll(browser)).toBe(50)
await browser.eval(`window.router.push("/10/100/100/1000/page2")`)
await waitForScrollToComplete(browser, { x: 0, y: 50 })
})
it('should scroll to top of document if possible while giving focus to page', async () => {
- const browser = await webdriver(next.url, '/10/100/100/1000/page1')
+ const browser = await next.browser('/10/100/100/1000/page1')
await scrollTo(browser, { x: 0, y: 200 })
- expect(await getTopScroll(browser)).toBe(200)
await browser.eval(`window.router.push("/10/100/100/1000/page2")`)
await waitForScrollToComplete(browser, { x: 0, y: 0 })
})
it('should scroll to top of document with new metadata', async () => {
- const browser = await webdriver(next.url, '/')
+ const browser = await next.browser('/')
// scroll to bottom
await browser.eval(
@@ -112,11 +111,9 @@ describe('router autoscrolling on navigation', () => {
describe('horizontal scroll', () => {
it("should't scroll horizontally", async () => {
- const browser = await webdriver(next.url, '/0/0/10000/10000/page1')
+ const browser = await next.browser('/0/0/10000/10000/page1')
await scrollTo(browser, { x: 1000, y: 1000 })
- expect(await getLeftScroll(browser)).toBe(1000)
- expect(await getTopScroll(browser)).toBe(1000)
await browser.eval(`window.router.push("/0/0/10000/10000/page2")`)
await waitForScrollToComplete(browser, { x: 1000, y: 0 })
@@ -125,20 +122,18 @@ describe('router autoscrolling on navigation', () => {
describe('router.refresh()', () => {
it('should not scroll when called alone', async () => {
- const browser = await webdriver(next.url, '/10/10000/100/1000/page1')
+ const browser = await next.browser('/10/10000/100/1000/page1')
await scrollTo(browser, { x: 0, y: 12000 })
- expect(await getTopScroll(browser)).toBe(12000)
await browser.eval(`window.router.refresh()`)
await waitForScrollToComplete(browser, { x: 0, y: 12000 })
})
it('should not stop router.push() from scrolling', async () => {
- const browser = await webdriver(next.url, '/10/10000/100/1000/page1')
+ const browser = await next.browser('/10/10000/100/1000/page1')
await scrollTo(browser, { x: 0, y: 12000 })
- expect(await getTopScroll(browser)).toBe(12000)
await browser.eval(`
window.React.startTransition(() => {
@@ -154,7 +149,7 @@ describe('router autoscrolling on navigation', () => {
;(isNextDev ? it : it.skip)(
'should not scroll the page when we hot reload',
async () => {
- const browser = await webdriver(next.url, '/10/10000/100/1000/page1')
+ const browser = await next.browser('/10/10000/100/1000/page1')
await scrollTo(browser, { x: 0, y: 12000 })
@@ -180,7 +175,7 @@ describe('router autoscrolling on navigation', () => {
describe('bugs', () => {
it('Should scroll to the top of the layout when the first child is display none', async () => {
- const browser = await webdriver(next.url, '/')
+ const browser = await next.browser('/')
await browser.eval('window.scrollTo(0, 500)')
await browser
.elementByCss('#to-invisible-first-element')
@@ -190,7 +185,7 @@ describe('router autoscrolling on navigation', () => {
})
it('Should scroll to the top of the layout when the first child is position fixed', async () => {
- const browser = await webdriver(next.url, '/')
+ const browser = await next.browser('/')
await browser.eval('window.scrollTo(0, 500)')
await browser
.elementByCss('#to-fixed-first-element')
@@ -214,7 +209,7 @@ describe('router autoscrolling on navigation', () => {
})
it('Should scroll to the top of the layout when the first child is position sticky', async () => {
- const browser = await webdriver(next.url, '/')
+ const browser = await next.browser('/')
await browser.eval('window.scrollTo(0, 500)')
await browser
.elementByCss('#to-sticky-first-element')
@@ -238,13 +233,16 @@ describe('router autoscrolling on navigation', () => {
})
it('Should apply scroll when loading.js is used', async () => {
- const browser = await webdriver(next.url, '/')
+ const browser = await next.browser('/')
await browser.eval('window.scrollTo(0, 500)')
- await browser
- .elementByCss('#to-loading-scroll')
- .click()
- .waitForElementByCss('#loading-component')
- await check(() => browser.eval('window.scrollY'), 0)
+ await (await browser.elementByCss('#to-loading-scroll')).hover()
+ await browser.elementByCss('#to-loading-scroll').click()
+ if (isClientSegmentCacheEnabled) {
+ // TODO(clientSegmentCache): Should always show loading.tsx
+ } else {
+ await browser.waitForElementByCss('#loading-component')
+ await check(() => browser.eval('window.scrollY'), 0)
+ }
await browser.waitForElementByCss('#content-that-is-visible')
await check(() => browser.eval('window.scrollY'), 0)
})
diff --git a/test/e2e/app-dir/static-generation-status/app/not-found-page/page.js b/test/e2e/app-dir/static-generation-status/app/not-found-page/page.js
index 4e414d2316321..97ea65b48340c 100644
--- a/test/e2e/app-dir/static-generation-status/app/not-found-page/page.js
+++ b/test/e2e/app-dir/static-generation-status/app/not-found-page/page.js
@@ -3,5 +3,3 @@ import { notFound } from 'next/navigation'
export default function Page() {
notFound()
}
-
-export const dynamic = 'force-static'
diff --git a/test/e2e/app-dir/static-generation-status/app/redirect-client-page/client-component.js b/test/e2e/app-dir/static-generation-status/app/redirect-client-page/client-component.js
new file mode 100644
index 0000000000000..1d82f47060a29
--- /dev/null
+++ b/test/e2e/app-dir/static-generation-status/app/redirect-client-page/client-component.js
@@ -0,0 +1,7 @@
+'use client'
+import { redirect } from 'next/navigation'
+
+export default function ClientComp() {
+ redirect('/')
+ return <>>
+}
diff --git a/test/e2e/app-dir/static-generation-status/app/redirect-client-page/page.js b/test/e2e/app-dir/static-generation-status/app/redirect-client-page/page.js
new file mode 100644
index 0000000000000..b058b05f9d5d2
--- /dev/null
+++ b/test/e2e/app-dir/static-generation-status/app/redirect-client-page/page.js
@@ -0,0 +1,5 @@
+import ClientComp from './client-component'
+
+export default function Page() {
+ return
+}
diff --git a/test/e2e/app-dir/static-generation-status/app/redirect-page/page.js b/test/e2e/app-dir/static-generation-status/app/redirect-page/page.js
index 0f2a2234c2c43..27a26b52db00d 100644
--- a/test/e2e/app-dir/static-generation-status/app/redirect-page/page.js
+++ b/test/e2e/app-dir/static-generation-status/app/redirect-page/page.js
@@ -3,5 +3,3 @@ import { redirect } from 'next/navigation'
export default function Page() {
redirect('/')
}
-
-export const dynamic = 'force-static'
diff --git a/test/e2e/app-dir/static-generation-status/app/redirect-permanent/page.js b/test/e2e/app-dir/static-generation-status/app/redirect-permanent/page.js
new file mode 100644
index 0000000000000..c020e6175cf05
--- /dev/null
+++ b/test/e2e/app-dir/static-generation-status/app/redirect-permanent/page.js
@@ -0,0 +1,6 @@
+import { permanentRedirect, RedirectType } from 'next/navigation'
+
+export default function Page() {
+ permanentRedirect('/', RedirectType.push)
+ return <>>
+}
diff --git a/test/e2e/app-dir/static-generation-status/index.test.ts b/test/e2e/app-dir/static-generation-status/index.test.ts
index 851baf31b4c7a..12b1081e6cc8b 100644
--- a/test/e2e/app-dir/static-generation-status/index.test.ts
+++ b/test/e2e/app-dir/static-generation-status/index.test.ts
@@ -17,6 +17,20 @@ describe('app-dir static-generation-status', () => {
expect(status).toBe(307)
})
+ it('should render the client page using redirect with status 307', async () => {
+ const { status } = await next.fetch('/redirect-client-page', {
+ redirect: 'manual',
+ })
+ expect(status).toBe(307)
+ })
+
+ it('should respond with 308 status code if permanent flag is set', async () => {
+ const { status } = await next.fetch('/redirect-permanent', {
+ redirect: 'manual',
+ })
+ expect(status).toBe(308)
+ })
+
it('should render the non existed route redirect with status 404', async () => {
expect((await next.fetch('/does-not-exist')).status).toBe(404)
})
diff --git a/test/experimental-tests-manifest.json b/test/experimental-tests-manifest.json
index 75ff2169af9b6..febc6315d541a 100644
--- a/test/experimental-tests-manifest.json
+++ b/test/experimental-tests-manifest.json
@@ -141,7 +141,6 @@
"test/e2e/app-dir/app/standalone.test.ts",
"test/e2e/app-dir/app/useReportWebVitals.test.ts",
"test/e2e/app-dir/async-component-preload/async-component-preload.test.ts",
- "test/e2e/app-dir/autoscroll-with-css-modules/index.test.ts",
"test/e2e/app-dir/back-forward-cache/back-forward-cache.test.ts",
"test/e2e/app-dir/crypto-globally-available/crypto-globally-available.test.ts",
"test/e2e/app-dir/css-chunking/css-chunking.test.ts",
@@ -239,7 +238,6 @@
"test/e2e/app-dir/rewrites-redirects/rewrites-redirects.test.ts",
"test/e2e/app-dir/root-layout-render-once/index.test.ts",
"test/e2e/app-dir/root-layout/root-layout.test.ts",
- "test/e2e/app-dir/router-autoscroll/router-autoscroll.test.ts",
"test/e2e/app-dir/router-stuck-dynamic-static-segment/router-stuck-dynamic-static-segment.test.ts",
"test/e2e/app-dir/rsc-basic/rsc-basic-react-experimental.test.ts",
"test/e2e/app-dir/rsc-basic/rsc-basic.test.ts",
diff --git a/test/lib/next-test-utils.ts b/test/lib/next-test-utils.ts
index d292128f4b032..3373664b4e9e8 100644
--- a/test/lib/next-test-utils.ts
+++ b/test/lib/next-test-utils.ts
@@ -800,7 +800,7 @@ export async function retry
(
fn: () => T | Promise,
duration: number = 3000,
interval: number = 500,
- description?: string
+ description: string = fn.name
): Promise {
if (duration % interval !== 0) {
throw new Error(