From eadaca780b57a561e13200078d5b0626e69af633 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Wed, 14 Sep 2022 01:01:43 +0200 Subject: [PATCH] Add additional tests for prefetch and trailingSlash (#40517) Adds some of the tests we didn't have yet for app. ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm lint` - [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) --- .../app/dashboard/layout.server.js | 4 +- .../app-prefetch/app/dashboard/page.server.js | 2 +- .../app-dir/app-prefetch/app/page.server.js | 4 +- test/e2e/app-dir/index.test.ts | 10 +-- test/e2e/app-dir/prefetching.test.ts | 57 ++++++++++++++++ test/e2e/app-dir/rendering.test.ts | 7 +- test/e2e/app-dir/rsc-basic.test.ts | 9 +-- test/e2e/app-dir/trailingslash.test.ts | 66 +++++++++++++++++++ .../trailingslash/app/a/page.server.js | 9 +++ .../trailingslash/app/layout.server.js | 10 +++ .../app-dir/trailingslash/app/page.server.js | 12 ++++ test/e2e/app-dir/trailingslash/next.config.js | 9 +++ 12 files changed, 172 insertions(+), 27 deletions(-) create mode 100644 test/e2e/app-dir/prefetching.test.ts create mode 100644 test/e2e/app-dir/trailingslash.test.ts create mode 100644 test/e2e/app-dir/trailingslash/app/a/page.server.js create mode 100644 test/e2e/app-dir/trailingslash/app/layout.server.js create mode 100644 test/e2e/app-dir/trailingslash/app/page.server.js create mode 100644 test/e2e/app-dir/trailingslash/next.config.js 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, +}