diff --git a/test/e2e/app-dir/app-prefetch/app/dashboard/layout.server.js b/test/e2e/app-dir/app-prefetch/app/dashboard/layout.server.js index 84ebbb490d40..8c83d8e7a216 100644 --- a/test/e2e/app-dir/app-prefetch/app/dashboard/layout.server.js +++ b/test/e2e/app-dir/app-prefetch/app/dashboard/layout.server.js @@ -1,5 +1,5 @@ export async function getServerSideProps() { - await new Promise((resolve) => setTimeout(resolve, 2000)) + await new Promise((resolve) => setTimeout(resolve, 400)) return { props: { message: 'Hello World', @@ -9,7 +9,7 @@ export async function getServerSideProps() { export default function DashboardLayout({ children, message }) { return ( <> -

Dashboard {message}

+

Dashboard {message}

{children} ) diff --git a/test/e2e/app-dir/app-prefetch/app/dashboard/page.server.js b/test/e2e/app-dir/app-prefetch/app/dashboard/page.server.js index d22dfdf51e84..5171e25e542d 100644 --- a/test/e2e/app-dir/app-prefetch/app/dashboard/page.server.js +++ b/test/e2e/app-dir/app-prefetch/app/dashboard/page.server.js @@ -9,7 +9,7 @@ export async function getServerSideProps() { export default function DashboardPage({ message }) { return ( <> -

{message}

+

{message}

) } diff --git a/test/e2e/app-dir/app-prefetch/app/page.server.js b/test/e2e/app-dir/app-prefetch/app/page.server.js index 5cb37da2ad8a..be3690c6321b 100644 --- a/test/e2e/app-dir/app-prefetch/app/page.server.js +++ b/test/e2e/app-dir/app-prefetch/app/page.server.js @@ -2,7 +2,9 @@ import Link from 'next/link' export default function HomePage() { return ( <> - To Dashboard + + To Dashboard + ) } diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 6af635e765ed..0bf456d2dbdc 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -23,15 +23,7 @@ describe('app dir', () => { function runTests({ assetPrefix }: { assetPrefix?: boolean }) { beforeAll(async () => { next = await createNext({ - files: { - public: new FileRef(path.join(__dirname, 'app/public')), - styles: new FileRef(path.join(__dirname, 'app/styles')), - pages: new FileRef(path.join(__dirname, 'app/pages')), - app: new FileRef(path.join(__dirname, 'app/app')), - 'next.config.js': new FileRef( - path.join(__dirname, 'app/next.config.js') - ), - }, + files: new FileRef(path.join(__dirname, 'app')), dependencies: { react: 'experimental', 'react-dom': 'experimental', diff --git a/test/e2e/app-dir/prefetching.test.ts b/test/e2e/app-dir/prefetching.test.ts new file mode 100644 index 000000000000..5f9f6bdb5474 --- /dev/null +++ b/test/e2e/app-dir/prefetching.test.ts @@ -0,0 +1,57 @@ +import { createNext, FileRef } from 'e2e-utils' +import { NextInstance } from 'test/lib/next-modes/base' +import { waitFor } from 'next-test-utils' +import path from 'path' +import webdriver from 'next-webdriver' + +describe('app dir prefetching', () => { + if ((global as any).isNextDeploy) { + it('should skip next deploy for now', () => {}) + return + } + + if (process.env.NEXT_TEST_REACT_VERSION === '^17') { + it('should skip for react v17', () => {}) + return + } + let next: NextInstance + + beforeAll(async () => { + next = await createNext({ + files: new FileRef(path.join(__dirname, 'app-prefetch')), + dependencies: { + react: 'experimental', + 'react-dom': 'experimental', + }, + skipStart: true, + }) + await next.start() + }) + afterAll(() => next.destroy()) + + it('should show layout eagerly when prefetched with loading one level down', async () => { + const browser = await webdriver(next.url, '/') + // Ensure the page is prefetched + await waitFor(1000) + + const before = Date.now() + await browser + .elementByCss('#to-dashboard') + .click() + .waitForElementByCss('#dashboard-layout') + const after = Date.now() + const timeToComplete = after - before + + expect(timeToComplete < 1000).toBe(true) + + expect(await browser.elementByCss('#dashboard-layout').text()).toBe( + 'Dashboard Hello World' + ) + + await browser.waitForElementByCss('#dashboard-page') + + expect(await browser.waitForElementByCss('#dashboard-page').text()).toBe( + 'Welcome to the dashboard' + ) + }) +}) diff --git a/test/e2e/app-dir/rendering.test.ts b/test/e2e/app-dir/rendering.test.ts index 69f1f0dd3859..d7168bcd275d 100644 --- a/test/e2e/app-dir/rendering.test.ts +++ b/test/e2e/app-dir/rendering.test.ts @@ -20,12 +20,7 @@ describe('app dir rendering', () => { beforeAll(async () => { next = await createNext({ - files: { - app: new FileRef(path.join(__dirname, 'app-rendering/app')), - 'next.config.js': new FileRef( - path.join(__dirname, 'app-rendering/next.config.js') - ), - }, + files: new FileRef(path.join(__dirname, 'app-rendering')), dependencies: { react: 'experimental', 'react-dom': 'experimental', diff --git a/test/e2e/app-dir/rsc-basic.test.ts b/test/e2e/app-dir/rsc-basic.test.ts index 0debb6818399..e548c458445f 100644 --- a/test/e2e/app-dir/rsc-basic.test.ts +++ b/test/e2e/app-dir/rsc-basic.test.ts @@ -35,15 +35,8 @@ describe('app dir - react server components', () => { } beforeAll(async () => { - const appDir = path.join(__dirname, './rsc-basic') next = await createNext({ - files: { - node_modules_bak: new FileRef(path.join(appDir, 'node_modules_bak')), - public: new FileRef(path.join(appDir, 'public')), - components: new FileRef(path.join(appDir, 'components')), - app: new FileRef(path.join(appDir, 'app')), - 'next.config.js': new FileRef(path.join(appDir, 'next.config.js')), - }, + files: new FileRef(path.join(__dirname, './rsc-basic')), dependencies: { 'styled-components': '6.0.0-alpha.5', react: 'experimental', diff --git a/test/e2e/app-dir/trailingslash.test.ts b/test/e2e/app-dir/trailingslash.test.ts new file mode 100644 index 000000000000..0b8ca82f7553 --- /dev/null +++ b/test/e2e/app-dir/trailingslash.test.ts @@ -0,0 +1,66 @@ +import { createNext, FileRef } from 'e2e-utils' +import { NextInstance } from 'test/lib/next-modes/base' +import { fetchViaHTTP, renderViaHTTP } from 'next-test-utils' +import path from 'path' +import cheerio from 'cheerio' +import webdriver from 'next-webdriver' + +describe('app-dir trailingSlash handling', () => { + if ((global as any).isNextDeploy) { + it('should skip next deploy for now', () => {}) + return + } + + if (process.env.NEXT_TEST_REACT_VERSION === '^17') { + it('should skip for react v17', () => {}) + return + } + let next: NextInstance + + beforeAll(async () => { + next = await createNext({ + files: new FileRef(path.join(__dirname, 'trailingslash')), + dependencies: { + react: 'experimental', + 'react-dom': 'experimental', + }, + skipStart: true, + }) + + await next.start() + }) + afterAll(() => next.destroy()) + + it('should redirect route when requesting it directly', async () => { + const res = await fetchViaHTTP( + next.url, + '/a', + {}, + { + redirect: 'manual', + } + ) + expect(res.status).toBe(308) + expect(res.headers.get('location')).toBe(next.url + '/a/') + }) + + it('should render link with trailing slash', async () => { + const html = await renderViaHTTP(next.url, '/') + const $ = cheerio.load(html) + expect($('#to-a-trailing-slash').attr('href')).toBe('/a/') + }) + + it('should redirect route when requesting it directly by browser', async () => { + const browser = await webdriver(next.url, '/a') + expect(await browser.waitForElementByCss('#a-page').text()).toBe('A page') + }) + + it('should redirect route when clicking link', async () => { + const browser = await webdriver(next.url, '/') + await browser + .elementByCss('#to-a-trailing-slash') + .click() + .waitForElementByCss('#a-page') + expect(await browser.waitForElementByCss('#a-page').text()).toBe('A page') + }) +}) diff --git a/test/e2e/app-dir/trailingslash/app/a/page.server.js b/test/e2e/app-dir/trailingslash/app/a/page.server.js new file mode 100644 index 000000000000..d61256ee9f3d --- /dev/null +++ b/test/e2e/app-dir/trailingslash/app/a/page.server.js @@ -0,0 +1,9 @@ +import Link from 'next/link' +export default function HomePage() { + return ( + <> +

A page

+ To home + + ) +} diff --git a/test/e2e/app-dir/trailingslash/app/layout.server.js b/test/e2e/app-dir/trailingslash/app/layout.server.js new file mode 100644 index 000000000000..05b841b280b3 --- /dev/null +++ b/test/e2e/app-dir/trailingslash/app/layout.server.js @@ -0,0 +1,10 @@ +export default function Root({ children }) { + return ( + + + Hello + + {children} + + ) +} diff --git a/test/e2e/app-dir/trailingslash/app/page.server.js b/test/e2e/app-dir/trailingslash/app/page.server.js new file mode 100644 index 000000000000..f02fd1b341b1 --- /dev/null +++ b/test/e2e/app-dir/trailingslash/app/page.server.js @@ -0,0 +1,12 @@ +import Link from 'next/link' +export default function HomePage() { + return ( + <> +

+ + To a with trailing slash + +

+ + ) +} diff --git a/test/e2e/app-dir/trailingslash/next.config.js b/test/e2e/app-dir/trailingslash/next.config.js new file mode 100644 index 000000000000..a4194e110b51 --- /dev/null +++ b/test/e2e/app-dir/trailingslash/next.config.js @@ -0,0 +1,9 @@ +module.exports = { + experimental: { + appDir: true, + serverComponents: true, + legacyBrowsers: false, + browsersListForSwc: true, + }, + trailingSlash: true, +}