From 12b766d75ed7d25c8f8f29be2280cbd590f7a233 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Wed, 6 Jul 2022 17:26:29 -0600 Subject: [PATCH 01/17] test: added some test cases for new client side router --- .../app/app/link-hard-push/page.server.js | 9 + .../app/app/link-hard-replace/page.server.js | 9 + .../app/app/link-soft-push/page.server.js | 9 + .../app/app/link-soft-replace/page.server.js | 9 + .../app-dir/app/app/navigation/page.server.js | 3 + .../app-dir/app/app/with-date/page.server.js | 12 ++ test/e2e/app-dir/index.test.ts | 169 ++++++++++++++++++ 7 files changed, 220 insertions(+) create mode 100644 test/e2e/app-dir/app/app/link-hard-push/page.server.js create mode 100644 test/e2e/app-dir/app/app/link-hard-replace/page.server.js create mode 100644 test/e2e/app-dir/app/app/link-soft-push/page.server.js create mode 100644 test/e2e/app-dir/app/app/link-soft-replace/page.server.js create mode 100644 test/e2e/app-dir/app/app/navigation/page.server.js create mode 100644 test/e2e/app-dir/app/app/with-date/page.server.js diff --git a/test/e2e/app-dir/app/app/link-hard-push/page.server.js b/test/e2e/app-dir/app/app/link-hard-push/page.server.js new file mode 100644 index 000000000000..f692aaeb9e89 --- /dev/null +++ b/test/e2e/app-dir/app/app/link-hard-push/page.server.js @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default function Page() { + return ( + + With Date + + ) +} diff --git a/test/e2e/app-dir/app/app/link-hard-replace/page.server.js b/test/e2e/app-dir/app/app/link-hard-replace/page.server.js new file mode 100644 index 000000000000..4fbb8eecc548 --- /dev/null +++ b/test/e2e/app-dir/app/app/link-hard-replace/page.server.js @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default function Page() { + return ( + + With Date + + ) +} diff --git a/test/e2e/app-dir/app/app/link-soft-push/page.server.js b/test/e2e/app-dir/app/app/link-soft-push/page.server.js new file mode 100644 index 000000000000..166a862d98df --- /dev/null +++ b/test/e2e/app-dir/app/app/link-soft-push/page.server.js @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default function Page() { + return ( + + With Date + + ) +} diff --git a/test/e2e/app-dir/app/app/link-soft-replace/page.server.js b/test/e2e/app-dir/app/app/link-soft-replace/page.server.js new file mode 100644 index 000000000000..e20dbe188527 --- /dev/null +++ b/test/e2e/app-dir/app/app/link-soft-replace/page.server.js @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default function Page() { + return ( + + With Date + + ) +} diff --git a/test/e2e/app-dir/app/app/navigation/page.server.js b/test/e2e/app-dir/app/app/navigation/page.server.js new file mode 100644 index 000000000000..72cac83794ae --- /dev/null +++ b/test/e2e/app-dir/app/app/navigation/page.server.js @@ -0,0 +1,3 @@ +export default function Page() { + return

{new Date().toString()}

+} diff --git a/test/e2e/app-dir/app/app/with-date/page.server.js b/test/e2e/app-dir/app/app/with-date/page.server.js new file mode 100644 index 000000000000..bdc5ef140dd6 --- /dev/null +++ b/test/e2e/app-dir/app/app/with-date/page.server.js @@ -0,0 +1,12 @@ +import Link from 'next/link' + +export default function Page() { + return ( + <> +

{new Date().toString()}

+ + To Navigation + + + ) +} diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 30cb129cc8c9..971e4767263a 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -206,6 +206,175 @@ describe('app dir', () => { expect(html).toContain('hello from app/partial-match-[id]. ID is: 123') }) + describe('', () => { + it('should hard push', async () => { + const browser = await webdriver(next.url, '/link-hard-push') + + try { + // Click the link on the page, and verify that the history entry was + // added. + await browser.elementById('link').click() + // TODO: verify that a history entry was added + + // Get the date on the rendered page. + let element = await browser.elementById('date') + const firstDate = await element.text() + + // Wait one second, + await new Promise((resolve) => setTimeout(resolve, 1000)) + + // Go back, and redo the navigation by clicking the link. + await browser.back() + await browser.elementById('link').click() + + // Get the date again, and compare, they should not be the same. + element = await browser.elementById('date') + const secondDate = await element.text() + expect(firstDate).not.toBe(secondDate) + } finally { + await browser.close() + } + }) + + it('should hard replace', async () => { + const browser = await webdriver(next.url, '/link-hard-replace') + + try { + // Click the link on the page, and verify that the history entry was NOT + // added. + await browser.elementById('link').click() + // TODO: verify that a history entry was NOT added + + // Get the date on the rendered page. + let element = await browser.elementById('date') + const firstDate = await element.text() + + // Wait one second, + await new Promise((resolve) => setTimeout(resolve, 1000)) + + // Go back, and redo the navigation by clicking the link. + await browser.back() + await browser.elementById('link').click() + + // Get the date again, and compare, they should not be the same. + element = await browser.elementById('date') + const secondDate = await element.text() + expect(firstDate).not.toBe(secondDate) + } finally { + await browser.close() + } + }) + + it('should soft push', async () => { + const browser = await webdriver(next.url, '/link-soft-push') + + try { + // Click the link on the page, and verify that the history entry was + // added. + await browser.elementById('link').click() + // TODO: verify that a history entry was added + + // Get the date on the rendered page. + let element = await browser.elementById('date') + const firstDate = await element.text() + + // Wait one second, + await new Promise((resolve) => setTimeout(resolve, 1000)) + + // Go back, and redo the navigation by clicking the link. + await browser.back() + await browser.elementById('link').click() + + // Get the date again, and compare, they should be the same. + element = await browser.elementById('date') + const secondDate = await element.text() + expect(firstDate).toBe(secondDate) + } finally { + await browser.close() + } + }) + + it('should soft replace', async () => { + const browser = await webdriver(next.url, '/link-soft-replace') + + try { + // Click the link on the page, and verify that the history entry was NOT + // added. + await browser.elementById('link').click() + // TODO: verify that a history entry was NOT added + + // Get the date on the rendered page. + let element = await browser.elementById('date') + const firstDate = await element.text() + + // Wait one second, + await new Promise((resolve) => setTimeout(resolve, 1000)) + + // Go back, and redo the navigation by clicking the link. + await browser.back() + await browser.elementById('link').click() + + // Get the date again, and compare, they should be the same. + element = await browser.elementById('date') + const secondDate = await element.text() + expect(firstDate).toBe(secondDate) + } finally { + await browser.close() + } + }) + + it('should be soft for back navigation', async () => { + const browser = await webdriver(next.url, '/with-date') + + try { + // Get the date on the rendered page. + let element = await browser.elementById('date') + const firstDate = await element.text() + + // Wait one second, + await new Promise((resolve) => setTimeout(resolve, 1000)) + + // Click the link, and go back. + await browser.elementById('link').click() + await browser.back() + + // Get the date again, and compare, they should be the same. + element = await browser.elementById('date') + const secondDate = await element.text() + expect(firstDate).toBe(secondDate) + } finally { + await browser.close() + } + }) + + it('should be soft for forward navigation', async () => { + const browser = await webdriver(next.url, '/with-date') + + try { + // Click the link. + await browser.elementById('link').click() + + // Get the date on the rendered page. + let element = await browser.elementById('date') + const firstDate = await element.text() + + // Wait one second, + await new Promise((resolve) => setTimeout(resolve, 1000)) + + // Go back, then forward. + await browser.back() + await browser.forward() + + // Get the date again, and compare, they should be the same. + element = await browser.elementById('date') + const secondDate = await element.text() + expect(firstDate).toBe(secondDate) + } finally { + await browser.close() + } + }) + }) + describe('server components', () => { // TODO: why is this not servable but /dashboard+rootonly/hello.server.js // should be? Seems like they both either should be servable or not From bb7c5e7a067033aee2ed9c7333579c8e16f129a9 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 7 Jul 2022 13:17:29 -0600 Subject: [PATCH 02/17] tests: added additional test cases --- test/e2e/app-dir/app/app/rewrites/page.js | 9 ++++++ test/e2e/app-dir/index.test.ts | 36 ++++++++++++++++++++--- 2 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 test/e2e/app-dir/app/app/rewrites/page.js diff --git a/test/e2e/app-dir/app/app/rewrites/page.js b/test/e2e/app-dir/app/app/rewrites/page.js new file mode 100644 index 000000000000..ae97d2af2cbd --- /dev/null +++ b/test/e2e/app-dir/app/app/rewrites/page.js @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default function Page() { + return ( + + To Dashboard Rewritten + + ) +} diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 971e4767263a..150b6c90cff1 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -206,6 +206,11 @@ describe('app dir', () => { expect(html).toContain('hello from app/partial-match-[id]. ID is: 123') }) + it('should support rewrites', async () => { + const html = await renderViaHTTP(next.url, '/rewritten-to-dashboard') + expect(html).toContain('hello from app/dashboard') + }) + describe('', () => { it('should hard push', async () => { const browser = await webdriver(next.url, '/link-hard-push') @@ -213,8 +218,9 @@ describe('app dir', () => { try { // Click the link on the page, and verify that the history entry was // added. + expect(await browser.eval('window.history.length')).toBe(2) await browser.elementById('link').click() - // TODO: verify that a history entry was added + expect(await browser.eval('window.history.length')).toBe(3) // Get the date on the rendered page. let element = await browser.elementById('date') @@ -242,8 +248,9 @@ describe('app dir', () => { try { // Click the link on the page, and verify that the history entry was NOT // added. + expect(await browser.eval('window.history.length')).toBe(2) await browser.elementById('link').click() - // TODO: verify that a history entry was NOT added + expect(await browser.eval('window.history.length')).toBe(2) // Get the date on the rendered page. let element = await browser.elementById('date') @@ -271,8 +278,9 @@ describe('app dir', () => { try { // Click the link on the page, and verify that the history entry was // added. + expect(await browser.eval('window.history.length')).toBe(2) await browser.elementById('link').click() - // TODO: verify that a history entry was added + expect(await browser.eval('window.history.length')).toBe(3) // Get the date on the rendered page. let element = await browser.elementById('date') @@ -300,8 +308,9 @@ describe('app dir', () => { try { // Click the link on the page, and verify that the history entry was NOT // added. + expect(await browser.eval('window.history.length')).toBe(2) await browser.elementById('link').click() - // TODO: verify that a history entry was NOT added + expect(await browser.eval('window.history.length')).toBe(2) // Get the date on the rendered page. let element = await browser.elementById('date') @@ -373,6 +382,25 @@ describe('app dir', () => { await browser.close() } }) + + it('should respect rewrites', async () => { + const browser = await webdriver(next.url, '/rewrites') + + try { + // Click the link. + await browser.elementById('link').click() + + // Check to see that we were rewritten and not redirected. + const pathname = await browser.eval('window.location.pathname') + expect(pathname).toBe('/rewritten-to-dashboard') + + // Check to see that the page we navigated to is in fact the dashboard. + const html = await browser.text() + expect(html).toContain('hello from app/dashboard') + } finally { + await browser.close() + } + }) }) describe('server components', () => { From 017b41c19c2f782b6582c7ef12c92af6fe004837 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 7 Jul 2022 22:29:44 -0600 Subject: [PATCH 03/17] test: improved test support --- .../app/app/link-hard-push/page.server.js | 4 +- .../app/app/link-hard-replace/page.server.js | 13 +- .../link-hard-replace/subpage/page.server.js | 9 ++ .../app/app/link-soft-push/page.server.js | 4 +- .../app/app/link-soft-replace/page.server.js | 4 +- .../app-dir/app/app/navigation/page.server.js | 4 +- .../app/app/same-layout/first/page.server.js | 12 ++ .../app/app/same-layout/layout.server.js | 10 ++ .../app/app/same-layout/second/page.server.js | 12 ++ .../app-dir/app/app/with-date/page.server.js | 3 +- test/e2e/app-dir/index.test.ts | 137 ++++++++++-------- 11 files changed, 140 insertions(+), 72 deletions(-) create mode 100644 test/e2e/app-dir/app/app/link-hard-replace/subpage/page.server.js create mode 100644 test/e2e/app-dir/app/app/same-layout/first/page.server.js create mode 100644 test/e2e/app-dir/app/app/same-layout/layout.server.js create mode 100644 test/e2e/app-dir/app/app/same-layout/second/page.server.js diff --git a/test/e2e/app-dir/app/app/link-hard-push/page.server.js b/test/e2e/app-dir/app/app/link-hard-push/page.server.js index f692aaeb9e89..049e5be9c49c 100644 --- a/test/e2e/app-dir/app/app/link-hard-push/page.server.js +++ b/test/e2e/app-dir/app/app/link-hard-push/page.server.js @@ -2,8 +2,8 @@ import Link from 'next/link' export default function Page() { return ( - - With Date + + With ID ) } diff --git a/test/e2e/app-dir/app/app/link-hard-replace/page.server.js b/test/e2e/app-dir/app/app/link-hard-replace/page.server.js index 4fbb8eecc548..340baa107e37 100644 --- a/test/e2e/app-dir/app/app/link-hard-replace/page.server.js +++ b/test/e2e/app-dir/app/app/link-hard-replace/page.server.js @@ -1,9 +1,16 @@ +import { nanoid } from 'nanoid' import Link from 'next/link' export default function Page() { return ( - - With Date - + <> +

{nanoid()}

+ + Self Link + + + Subpage + + ) } diff --git a/test/e2e/app-dir/app/app/link-hard-replace/subpage/page.server.js b/test/e2e/app-dir/app/app/link-hard-replace/subpage/page.server.js new file mode 100644 index 000000000000..cd586543ab75 --- /dev/null +++ b/test/e2e/app-dir/app/app/link-hard-replace/subpage/page.server.js @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default function Page() { + return ( + + Self Link + + ) +} diff --git a/test/e2e/app-dir/app/app/link-soft-push/page.server.js b/test/e2e/app-dir/app/app/link-soft-push/page.server.js index 166a862d98df..3f5d6bde9ebf 100644 --- a/test/e2e/app-dir/app/app/link-soft-push/page.server.js +++ b/test/e2e/app-dir/app/app/link-soft-push/page.server.js @@ -2,8 +2,8 @@ import Link from 'next/link' export default function Page() { return ( - - With Date + + With ID ) } diff --git a/test/e2e/app-dir/app/app/link-soft-replace/page.server.js b/test/e2e/app-dir/app/app/link-soft-replace/page.server.js index e20dbe188527..bd5af65a4734 100644 --- a/test/e2e/app-dir/app/app/link-soft-replace/page.server.js +++ b/test/e2e/app-dir/app/app/link-soft-replace/page.server.js @@ -2,8 +2,8 @@ import Link from 'next/link' export default function Page() { return ( - - With Date + + With ID ) } diff --git a/test/e2e/app-dir/app/app/navigation/page.server.js b/test/e2e/app-dir/app/app/navigation/page.server.js index 72cac83794ae..b60097faad14 100644 --- a/test/e2e/app-dir/app/app/navigation/page.server.js +++ b/test/e2e/app-dir/app/app/navigation/page.server.js @@ -1,3 +1,5 @@ +import { nanoid } from 'nanoid' + export default function Page() { - return

{new Date().toString()}

+ return

{nanoid()}

} diff --git a/test/e2e/app-dir/app/app/same-layout/first/page.server.js b/test/e2e/app-dir/app/app/same-layout/first/page.server.js new file mode 100644 index 000000000000..bf4ba9e2455b --- /dev/null +++ b/test/e2e/app-dir/app/app/same-layout/first/page.server.js @@ -0,0 +1,12 @@ +import Link from 'next/link' + +export default function Page() { + return ( + <> +

hello from same-layout/first

+ + To Second + + + ) +} diff --git a/test/e2e/app-dir/app/app/same-layout/layout.server.js b/test/e2e/app-dir/app/app/same-layout/layout.server.js new file mode 100644 index 000000000000..42734ad7255d --- /dev/null +++ b/test/e2e/app-dir/app/app/same-layout/layout.server.js @@ -0,0 +1,10 @@ +import { nanoid } from 'nanoid' + +export default function Layout({ children }) { + return ( + <> +

{nanoid()}

+
{children}
+ + ) +} diff --git a/test/e2e/app-dir/app/app/same-layout/second/page.server.js b/test/e2e/app-dir/app/app/same-layout/second/page.server.js new file mode 100644 index 000000000000..9d981dcb708a --- /dev/null +++ b/test/e2e/app-dir/app/app/same-layout/second/page.server.js @@ -0,0 +1,12 @@ +import Link from 'next/link' + +export default function Page() { + return ( + <> +

hello from same-layout/second

+ + To First + + + ) +} diff --git a/test/e2e/app-dir/app/app/with-date/page.server.js b/test/e2e/app-dir/app/app/with-date/page.server.js index bdc5ef140dd6..07beecc4203f 100644 --- a/test/e2e/app-dir/app/app/with-date/page.server.js +++ b/test/e2e/app-dir/app/app/with-date/page.server.js @@ -1,9 +1,10 @@ import Link from 'next/link' +import { nanoid } from 'nanoid' export default function Page() { return ( <> -

{new Date().toString()}

+

{nanoid()}

To Navigation diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 150b6c90cff1..d376b8611995 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -211,6 +211,31 @@ describe('app dir', () => { expect(html).toContain('hello from app/dashboard') }) + it('should not rerender layout when navigating between routes in the same layout', async () => { + const browser = await webdriver(next.url, '/same-layout/first') + + try { + // Get the render id from the dom and click the first link. + const firstRenderID = await browser.elementById('render-id').text() + await browser.elementById('link').click() + await browser.waitForElementByCss('#second-page') + + // Get the render id from the dom again, it should be the same! + const secondRenderID = await browser.elementById('render-id').text() + expect(secondRenderID).toBe(firstRenderID) + + // Navigate back to the first page again by clicking the link. + await browser.elementById('link').click() + await browser.waitForElementByCss('#first-page') + + // Get the render id from the dom again, it should be the same! + const thirdRenderID = await browser.elementById('render-id').text() + expect(thirdRenderID).toBe(firstRenderID) + } finally { + await browser.close() + } + }) + describe('', () => { it('should hard push', async () => { const browser = await webdriver(next.url, '/link-hard-push') @@ -220,23 +245,20 @@ describe('app dir', () => { // added. expect(await browser.eval('window.history.length')).toBe(2) await browser.elementById('link').click() + await browser.waitForElementByCss('#render-id') expect(await browser.eval('window.history.length')).toBe(3) - // Get the date on the rendered page. - let element = await browser.elementById('date') - const firstDate = await element.text() - - // Wait one second, - await new Promise((resolve) => setTimeout(resolve, 1000)) + // Get the id on the rendered page. + const firstID = await browser.elementById('render-id').text() // Go back, and redo the navigation by clicking the link. await browser.back() await browser.elementById('link').click() + await browser.waitForElementByCss('#render-id') - // Get the date again, and compare, they should not be the same. - element = await browser.elementById('date') - const secondDate = await element.text() - expect(firstDate).not.toBe(secondDate) + // Get the id again, and compare, they should not be the same. + const secondID = await browser.elementById('render-id').text() + expect(secondID).not.toBe(firstID) } finally { await browser.close() } @@ -246,27 +268,33 @@ describe('app dir', () => { const browser = await webdriver(next.url, '/link-hard-replace') try { + // Get the render ID so we can compare it. + const firstID = await browser.elementById('render-id').text() + // Click the link on the page, and verify that the history entry was NOT // added. expect(await browser.eval('window.history.length')).toBe(2) - await browser.elementById('link').click() + await browser.elementById('self-link').click() + await browser.waitForElementByCss('#render-id') expect(await browser.eval('window.history.length')).toBe(2) - // Get the date on the rendered page. - let element = await browser.elementById('date') - const firstDate = await element.text() + // Get the date again, and compare, they should not be the same. + const secondID = await browser.elementById('render-id').text() + expect(secondID).not.toBe(firstID) - // Wait one second, - await new Promise((resolve) => setTimeout(resolve, 1000)) + // Navigate to the subpage, verify that the history entry was NOT added. + await browser.elementById('subpage-link').click() + await browser.waitForElementByCss('#back-link') + expect(await browser.eval('window.history.length')).toBe(2) - // Go back, and redo the navigation by clicking the link. - await browser.back() - await browser.elementById('link').click() + // Navigate back again, verify that the history entry was NOT added. + await browser.elementById('back-link').click() + await browser.waitForElementByCss('#render-id') + expect(await browser.eval('window.history.length')).toBe(2) // Get the date again, and compare, they should not be the same. - element = await browser.elementById('date') - const secondDate = await element.text() - expect(firstDate).not.toBe(secondDate) + const thirdID = await browser.elementById('render-id').text() + expect(thirdID).not.toBe(secondID) } finally { await browser.close() } @@ -280,28 +308,25 @@ describe('app dir', () => { // added. expect(await browser.eval('window.history.length')).toBe(2) await browser.elementById('link').click() + await browser.waitForElementByCss('#render-id') expect(await browser.eval('window.history.length')).toBe(3) - // Get the date on the rendered page. - let element = await browser.elementById('date') - const firstDate = await element.text() - - // Wait one second, - await new Promise((resolve) => setTimeout(resolve, 1000)) + // Get the id on the rendered page. + const firstID = await browser.elementById('render-id').text() // Go back, and redo the navigation by clicking the link. await browser.back() await browser.elementById('link').click() // Get the date again, and compare, they should be the same. - element = await browser.elementById('date') - const secondDate = await element.text() - expect(firstDate).toBe(secondDate) + const secondID = await browser.elementById('render-id').text() + expect(firstID).toBe(secondID) } finally { await browser.close() } }) + // FIXME: update it('should soft replace', async () => { const browser = await webdriver(next.url, '/link-soft-replace') @@ -312,77 +337,65 @@ describe('app dir', () => { await browser.elementById('link').click() expect(await browser.eval('window.history.length')).toBe(2) - // Get the date on the rendered page. - let element = await browser.elementById('date') - const firstDate = await element.text() - - // Wait one second, - await new Promise((resolve) => setTimeout(resolve, 1000)) + // Get the id on the rendered page. + const firstID = await browser.elementById('render-id').text() // Go back, and redo the navigation by clicking the link. await browser.back() await browser.elementById('link').click() // Get the date again, and compare, they should be the same. - element = await browser.elementById('date') - const secondDate = await element.text() - expect(firstDate).toBe(secondDate) + const secondID = await browser.elementById('render-id').text() + expect(firstID).toBe(secondID) } finally { await browser.close() } }) + // FIXME: update it('should be soft for back navigation', async () => { - const browser = await webdriver(next.url, '/with-date') + const browser = await webdriver(next.url, '/with-id') try { - // Get the date on the rendered page. - let element = await browser.elementById('date') - const firstDate = await element.text() - - // Wait one second, - await new Promise((resolve) => setTimeout(resolve, 1000)) + // Get the id on the rendered page. + const firstID = await browser.elementById('render-id').text() // Click the link, and go back. await browser.elementById('link').click() await browser.back() // Get the date again, and compare, they should be the same. - element = await browser.elementById('date') - const secondDate = await element.text() - expect(firstDate).toBe(secondDate) + const secondID = await browser.elementById('render-id').text() + expect(firstID).toBe(secondID) } finally { await browser.close() } }) + // FIXME: update it('should be soft for forward navigation', async () => { - const browser = await webdriver(next.url, '/with-date') + const browser = await webdriver(next.url, '/with-id') try { // Click the link. await browser.elementById('link').click() - // Get the date on the rendered page. - let element = await browser.elementById('date') - const firstDate = await element.text() - - // Wait one second, - await new Promise((resolve) => setTimeout(resolve, 1000)) + // Get the id on the rendered page. + const firstID = await browser.elementById('render-id').text() // Go back, then forward. await browser.back() await browser.forward() // Get the date again, and compare, they should be the same. - element = await browser.elementById('date') - const secondDate = await element.text() - expect(firstDate).toBe(secondDate) + const secondID = await browser.elementById('render-id').text() + expect(firstID).toBe(secondID) } finally { await browser.close() } }) + // FIXME: update it('should respect rewrites', async () => { const browser = await webdriver(next.url, '/rewrites') @@ -395,7 +408,9 @@ describe('app dir', () => { expect(pathname).toBe('/rewritten-to-dashboard') // Check to see that the page we navigated to is in fact the dashboard. - const html = await browser.text() + const html = await browser.eval( + 'window.document.documentElement.innerText' + ) expect(html).toContain('hello from app/dashboard') } finally { await browser.close() From 0fb999888f21a904c8d400db7c2e41542f14771d Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 7 Jul 2022 22:30:17 -0600 Subject: [PATCH 04/17] feat: added support for `` --- packages/next/client/link.tsx | 44 ++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/packages/next/client/link.tsx b/packages/next/client/link.tsx index 5477b7e4867b..607a6c1c1790 100644 --- a/packages/next/client/link.tsx +++ b/packages/next/client/link.tsx @@ -8,7 +8,10 @@ import { } from '../shared/lib/router/router' import { addLocale } from './add-locale' import { RouterContext } from '../shared/lib/router-context' -import { AppRouterContext } from '../shared/lib/app-router-context' +import { + AppRouterContext, + AppRouterInstance, +} from '../shared/lib/app-router-context' import { useIntersection } from './use-intersection' import { getDomainLocale } from './get-domain-locale' import { addBasePath } from './add-base-path' @@ -28,6 +31,11 @@ type InternalLinkProps = { href: Url as?: Url replace?: boolean + + /** + * TODO + */ + soft?: boolean scroll?: boolean shallow?: boolean passHref?: boolean @@ -95,10 +103,11 @@ function isModifiedEvent(event: React.MouseEvent): boolean { function linkClicked( e: React.MouseEvent, - router: NextRouter, + router: NextRouter | AppRouterInstance, href: string, as: string, replace?: boolean, + soft?: boolean, shallow?: boolean, scroll?: boolean, locale?: string | false, @@ -117,12 +126,27 @@ function linkClicked( e.preventDefault() const navigate = () => { - // replace state instead of push if prop is present - router[replace ? 'replace' : 'push'](href, as, { - shallow, - locale, - scroll, - }) + // If the router is an AppRouterInstance, then it'll have `softPush` and + // `softReplace`. + if ('softPush' in router && 'softReplace' in router) { + // If we're doing a soft navigation, use the soft variants of + // replace/push. + const method: keyof AppRouterInstance = soft + ? replace + ? 'softReplace' + : 'softPush' + : replace + ? 'replace' + : 'push' + + router[method](href) + } else { + router[replace ? 'replace' : 'push'](href, as, { + shallow, + locale, + scroll, + }) + } } if (startTransition) { @@ -183,6 +207,7 @@ const Link = React.forwardRef( const optionalPropsGuard: Record = { as: true, replace: true, + soft: true, scroll: true, shallow: true, passHref: true, @@ -224,6 +249,7 @@ const Link = React.forwardRef( } } else if ( key === 'replace' || + key === 'soft' || key === 'scroll' || key === 'shallow' || key === 'passHref' || @@ -264,6 +290,7 @@ const Link = React.forwardRef( prefetch: prefetchProp, passHref, replace, + soft, shallow, scroll, locale, @@ -416,6 +443,7 @@ const Link = React.forwardRef( href, as, replace, + soft, shallow, scroll, locale, From a355fbc03c5d754bc85259e136c12fbf66130492 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Fri, 8 Jul 2022 10:42:30 -0600 Subject: [PATCH 05/17] tests: improved test reliability --- .../app-dir/app/app/dashboard/page.server.js | 4 ++- .../app/app/link-soft-replace/page.server.js | 13 ++++++-- .../link-soft-replace/subpage/page.server.js | 9 ++++++ .../app-dir/app/app/navigation/page.server.js | 7 ++++- .../app/{with-date => with-id}/page.server.js | 0 test/e2e/app-dir/index.test.ts | 31 +++++++++++++------ 6 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 test/e2e/app-dir/app/app/link-soft-replace/subpage/page.server.js rename test/e2e/app-dir/app/app/{with-date => with-id}/page.server.js (100%) diff --git a/test/e2e/app-dir/app/app/dashboard/page.server.js b/test/e2e/app-dir/app/app/dashboard/page.server.js index 49c95abfbf36..5c7a89cc10b6 100644 --- a/test/e2e/app-dir/app/app/dashboard/page.server.js +++ b/test/e2e/app-dir/app/app/dashboard/page.server.js @@ -2,7 +2,9 @@ import ClientComp from './client-comp.client' export default function DashboardPage(props) { return ( <> -

hello from app/dashboard

+

+ hello from app/dashboard +

this is green

diff --git a/test/e2e/app-dir/app/app/link-soft-replace/page.server.js b/test/e2e/app-dir/app/app/link-soft-replace/page.server.js index bd5af65a4734..4558d664be32 100644 --- a/test/e2e/app-dir/app/app/link-soft-replace/page.server.js +++ b/test/e2e/app-dir/app/app/link-soft-replace/page.server.js @@ -1,9 +1,16 @@ +import { nanoid } from 'nanoid' import Link from 'next/link' export default function Page() { return ( - - With ID - + <> +

{nanoid()}

+ + Self Link + + + Subpage + + ) } diff --git a/test/e2e/app-dir/app/app/link-soft-replace/subpage/page.server.js b/test/e2e/app-dir/app/app/link-soft-replace/subpage/page.server.js new file mode 100644 index 000000000000..971f2843ed74 --- /dev/null +++ b/test/e2e/app-dir/app/app/link-soft-replace/subpage/page.server.js @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default function Page() { + return ( + + Self Link + + ) +} diff --git a/test/e2e/app-dir/app/app/navigation/page.server.js b/test/e2e/app-dir/app/app/navigation/page.server.js index b60097faad14..530c16824126 100644 --- a/test/e2e/app-dir/app/app/navigation/page.server.js +++ b/test/e2e/app-dir/app/app/navigation/page.server.js @@ -1,5 +1,10 @@ import { nanoid } from 'nanoid' export default function Page() { - return

{nanoid()}

+ return ( + <> +

{nanoid()}

+

hello from /navigation

+ + ) } diff --git a/test/e2e/app-dir/app/app/with-date/page.server.js b/test/e2e/app-dir/app/app/with-id/page.server.js similarity index 100% rename from test/e2e/app-dir/app/app/with-date/page.server.js rename to test/e2e/app-dir/app/app/with-id/page.server.js diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index d376b8611995..443a20e3a5de 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -326,27 +326,37 @@ describe('app dir', () => { } }) - // FIXME: update it('should soft replace', async () => { const browser = await webdriver(next.url, '/link-soft-replace') try { + // Get the render ID so we can compare it. + const firstID = await browser.elementById('render-id').text() + // Click the link on the page, and verify that the history entry was NOT // added. expect(await browser.eval('window.history.length')).toBe(2) - await browser.elementById('link').click() + await browser.elementById('self-link').click() + await browser.waitForElementByCss('#render-id') expect(await browser.eval('window.history.length')).toBe(2) // Get the id on the rendered page. - const firstID = await browser.elementById('render-id').text() + const secondID = await browser.elementById('render-id').text() + expect(secondID).toBe(firstID) - // Go back, and redo the navigation by clicking the link. - await browser.back() - await browser.elementById('link').click() + // Navigate to the subpage, verify that the history entry was NOT added. + await browser.elementById('subpage-link').click() + await browser.waitForElementByCss('#back-link') + expect(await browser.eval('window.history.length')).toBe(2) + + // Navigate back again, verify that the history entry was NOT added. + await browser.elementById('back-link').click() + await browser.waitForElementByCss('#render-id') + expect(await browser.eval('window.history.length')).toBe(2) // Get the date again, and compare, they should be the same. - const secondID = await browser.elementById('render-id').text() - expect(firstID).toBe(secondID) + const thirdID = await browser.elementById('render-id').text() + expect(thirdID).toBe(firstID) } finally { await browser.close() } @@ -362,6 +372,7 @@ describe('app dir', () => { // Click the link, and go back. await browser.elementById('link').click() + await browser.waitForElementByCss('#from-navigation') await browser.back() // Get the date again, and compare, they should be the same. @@ -372,13 +383,13 @@ describe('app dir', () => { } }) - // FIXME: update it('should be soft for forward navigation', async () => { const browser = await webdriver(next.url, '/with-id') try { // Click the link. await browser.elementById('link').click() + await browser.waitForElementByCss('#from-navigation') // Get the id on the rendered page. const firstID = await browser.elementById('render-id').text() @@ -395,13 +406,13 @@ describe('app dir', () => { } }) - // FIXME: update it('should respect rewrites', async () => { const browser = await webdriver(next.url, '/rewrites') try { // Click the link. await browser.elementById('link').click() + await browser.waitForElementByCss('#from-dashboard') // Check to see that we were rewritten and not redirected. const pathname = await browser.eval('window.location.pathname') From fbeb4cf86985358382a134c07db93859ae3989a0 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Fri, 8 Jul 2022 13:47:02 -0600 Subject: [PATCH 06/17] tests: added more cases for catch-all routes --- .../app/catch-all/[...slug]/page.server.js | 11 +++++++ .../[[...slug]]/page.server.js | 11 +++++++ test/e2e/app-dir/index.test.ts | 33 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 test/e2e/app-dir/app/app/catch-all/[...slug]/page.server.js create mode 100644 test/e2e/app-dir/app/app/optional-catch-all/[[...slug]]/page.server.js diff --git a/test/e2e/app-dir/app/app/catch-all/[...slug]/page.server.js b/test/e2e/app-dir/app/app/catch-all/[...slug]/page.server.js new file mode 100644 index 000000000000..c89883d6ce13 --- /dev/null +++ b/test/e2e/app-dir/app/app/catch-all/[...slug]/page.server.js @@ -0,0 +1,11 @@ +export function getServerSideProps({ params }) { + return { props: { params } } +} + +export default function Page({ params }) { + return ( +

+ hello from /catch-all/{params.slug.join('/')} +

+ ) +} diff --git a/test/e2e/app-dir/app/app/optional-catch-all/[[...slug]]/page.server.js b/test/e2e/app-dir/app/app/optional-catch-all/[[...slug]]/page.server.js new file mode 100644 index 000000000000..3c6b1f8b1106 --- /dev/null +++ b/test/e2e/app-dir/app/app/optional-catch-all/[[...slug]]/page.server.js @@ -0,0 +1,11 @@ +export function getServerSideProps({ params }) { + return { props: { params } } +} + +export default function Page({ params }) { + return ( +

+ hello from /optional-catch-all/{params.slug?.join('/')} +

+ ) +} diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 443a20e3a5de..2b2bb6fe844c 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -498,6 +498,39 @@ describe('app dir', () => { }) }) + describe('catch-all routes', () => { + it('should handle optional segments', async () => { + const params = ['this', 'is', 'a', 'test'] + const route = params.join('/') + const html = await renderViaHTTP( + next.url, + `/optional-catch-all/${route}` + ) + const $ = cheerio.load(html) + expect($('#text').attr('data-params')).toBe(route) + }) + + it('should handle optional segments root', async () => { + const html = await renderViaHTTP(next.url, `/optional-catch-all`) + const $ = cheerio.load(html) + expect($('#text').attr('data-params')).toBe('') + }) + + it('should handle required segments', async () => { + const params = ['this', 'is', 'a', 'test'] + const route = params.join('/') + const html = await renderViaHTTP(next.url, `/catch-all/${route}`) + const $ = cheerio.load(html) + expect($('#text').attr('data-params')).toBe(route) + }) + + it('should handle required segments root as not found', async () => { + const res = await fetchViaHTTP(next.url, `/catch-all`) + expect(res.status).toBe(404) + expect(await res.text()).toContain('This page could not be found') + }) + }) + describe('should serve client component', () => { it('should serve server-side', async () => { const html = await renderViaHTTP(next.url, '/client-component-route') From 291451f96eb581f67eea4c9af861e8e1f8079d8b Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Fri, 8 Jul 2022 15:51:21 -0600 Subject: [PATCH 07/17] tests: added app -> pages -> app tests --- .../app/app/pages-linking/page.server.js | 9 +++++++++ test/e2e/app-dir/app/pages/app-linking.js | 9 +++++++++ test/e2e/app-dir/index.test.ts | 17 ++++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 test/e2e/app-dir/app/app/pages-linking/page.server.js create mode 100644 test/e2e/app-dir/app/pages/app-linking.js diff --git a/test/e2e/app-dir/app/app/pages-linking/page.server.js b/test/e2e/app-dir/app/app/pages-linking/page.server.js new file mode 100644 index 000000000000..19b7cc4b861b --- /dev/null +++ b/test/e2e/app-dir/app/app/pages-linking/page.server.js @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default function Page(props) { + return ( + + To Pages Page + + ) +} diff --git a/test/e2e/app-dir/app/pages/app-linking.js b/test/e2e/app-dir/app/pages/app-linking.js new file mode 100644 index 000000000000..0a8e0289afe4 --- /dev/null +++ b/test/e2e/app-dir/app/pages/app-linking.js @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default function Page(props) { + return ( + + To App Page + + ) +} diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 2b2bb6fe844c..10fe29a174cc 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -362,7 +362,6 @@ describe('app dir', () => { } }) - // FIXME: update it('should be soft for back navigation', async () => { const browser = await webdriver(next.url, '/with-id') @@ -427,6 +426,22 @@ describe('app dir', () => { await browser.close() } }) + + it('should allow linking from app page to pages page', async () => { + const browser = await webdriver(next.url, '/pages-linking') + + try { + // Click the link. + await browser.elementById('app-link').click() + await browser.waitForElementByCss('#pages-link') + + // Click the other link. + await browser.elementById('pages-link').click() + await browser.waitForElementByCss('#app-link') + } finally { + await browser.close() + } + }) }) describe('server components', () => { From 36e8ebeab7f9ba2ce3a94fa4689a66b1f528c209 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Fri, 8 Jul 2022 17:02:24 -0600 Subject: [PATCH 08/17] tests: add tests for useCookies + useHeaders --- .../app/app/hooks/use-cookies/page.server.js | 19 ++++++++ .../app/app/hooks/use-headers/page.server.js | 19 ++++++++ test/e2e/app-dir/index.test.ts | 48 +++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 test/e2e/app-dir/app/app/hooks/use-cookies/page.server.js create mode 100644 test/e2e/app-dir/app/app/hooks/use-headers/page.server.js diff --git a/test/e2e/app-dir/app/app/hooks/use-cookies/page.server.js b/test/e2e/app-dir/app/app/hooks/use-cookies/page.server.js new file mode 100644 index 000000000000..dd2efcccd7d5 --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-cookies/page.server.js @@ -0,0 +1,19 @@ +import { useCookies } from 'next/dist/client/components/hooks-server' + +export default function Page() { + const cookies = useCookies() + + const hasCookie = + 'use-cookies' in cookies && cookies['use-cookies'] === 'value' + + return ( + <> +

hello from /hooks/use-cookies

+ {hasCookie ? ( + + ) : ( + + )} + + ) +} diff --git a/test/e2e/app-dir/app/app/hooks/use-headers/page.server.js b/test/e2e/app-dir/app/app/hooks/use-headers/page.server.js new file mode 100644 index 000000000000..bd2b1153eba8 --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-headers/page.server.js @@ -0,0 +1,19 @@ +import { useHeaders } from 'next/dist/client/components/hooks-server' + +export default function Page() { + const headers = useHeaders() + + const hasHeader = + 'x-use-headers' in headers && headers['x-use-headers'] === 'value' + + return ( + <> +

hello from /hooks/use-headers

+ {hasHeader ? ( +

Has x-use-headers header

+ ) : ( +

Does not have x-use-headers header

+ )} + + ) +} diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 10fe29a174cc..b921ca8b7b97 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -674,6 +674,54 @@ describe('app dir', () => { ) }) }) + + describe('hooks', () => { + describe('useCookies', () => { + it('should retrive cookies in a server component', async () => { + const browser = await webdriver(next.url, '/hooks/use-cookies') + + try { + await browser.waitForElementByCss('#does-not-have-cookie') + browser.addCookie({ name: 'use-cookies', value: 'value' }) + browser.refresh() + + await browser.waitForElementByCss('#has-cookie') + browser.deleteCookies() + browser.refresh() + + await browser.waitForElementByCss('#does-not-have-cookie') + } finally { + await browser.close() + } + }) + }) + + describe('useHeaders', () => { + it('should have access to incoming headers in a server component', async () => { + // Check to see that we can't see the header when it's not present. + let html = await renderViaHTTP( + next.url, + '/hooks/use-headers', + {}, + { headers: {} } + ) + let $ = cheerio.load(html) + expect($('#does-not-have-header').length).toBe(1) + expect($('#has-header').length).toBe(0) + + // Check to see that we can see the header when it's present. + html = await renderViaHTTP( + next.url, + '/hooks/use-headers', + {}, + { headers: { 'x-use-headers': 'value' } } + ) + $ = cheerio.load(html) + expect($('#has-header').length).toBe(1) + expect($('#does-not-have-header').length).toBe(0) + }) + }) + }) }) describe('css support', () => { From 71c923d03c7de7a2e790782ff556e68679ddca34 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 11 Jul 2022 10:37:13 -0600 Subject: [PATCH 09/17] tests: added tests for usePreviewData --- .../app/hooks/use-preview-data/page.server.js | 18 +++++++++++++ test/e2e/app-dir/app/pages/api/preview.js | 4 +++ test/e2e/app-dir/index.test.ts | 26 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 test/e2e/app-dir/app/app/hooks/use-preview-data/page.server.js create mode 100644 test/e2e/app-dir/app/pages/api/preview.js diff --git a/test/e2e/app-dir/app/app/hooks/use-preview-data/page.server.js b/test/e2e/app-dir/app/app/hooks/use-preview-data/page.server.js new file mode 100644 index 000000000000..afdcad1b2be1 --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-preview-data/page.server.js @@ -0,0 +1,18 @@ +import { usePreviewData } from 'next/dist/client/components/hooks-server' + +export default function Page() { + const data = usePreviewData() + + const hasData = !!data && data.key === 'value' + + return ( + <> +

hello from /hooks/use-preview-data

+ {hasData ? ( +

Has preview data

+ ) : ( +

Does not have preview data

+ )} + + ) +} diff --git a/test/e2e/app-dir/app/pages/api/preview.js b/test/e2e/app-dir/app/pages/api/preview.js new file mode 100644 index 000000000000..f926b6f2319a --- /dev/null +++ b/test/e2e/app-dir/app/pages/api/preview.js @@ -0,0 +1,4 @@ +export default function handler(req, res) { + res.setPreviewData({ key: 'value' }) + res.send(200).end() +} diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index b921ca8b7b97..4509d0154ef8 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -721,6 +721,32 @@ describe('app dir', () => { expect($('#does-not-have-header').length).toBe(0) }) }) + + describe('usePreviewData', () => { + it('should return no preview data when there is none', async () => { + const browser = await webdriver(next.url, '/hooks/use-preview-data') + + try { + await browser.waitForElementByCss('#does-not-have-preview-data') + } finally { + await browser.close() + } + }) + + it('should return preview data when there is some', async () => { + const browser = await webdriver(next.url, '/api/preview') + + try { + await browser.loadPage(next.url + '/hooks/use-preview-data', { + disableCache: false, + beforePageLoad: null, + }) + await browser.waitForElementByCss('#has-preview-data') + } finally { + await browser.close() + } + }) + }) }) }) From f6445d36a77dcaaff173e3a376f85954f50ef7c6 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 11 Jul 2022 12:11:18 -0600 Subject: [PATCH 10/17] tests: added more tests for hooks and client components --- .../get-server-side-props/page.client.js | 7 ++ .../get-static-props/page.client.js | 7 ++ .../app/app/hooks/use-pathname/page.client.js | 13 ++++ .../app/app/hooks/use-router/page.client.js | 17 +++++ .../hooks/use-router/sub-page/page.client.js | 3 + .../hooks/use-search-params/page.client.js | 19 ++++++ test/e2e/app-dir/index.test.ts | 68 +++++++++++++++++++ 7 files changed, 134 insertions(+) create mode 100644 test/e2e/app-dir/app/app/client-with-errors/get-server-side-props/page.client.js create mode 100644 test/e2e/app-dir/app/app/client-with-errors/get-static-props/page.client.js create mode 100644 test/e2e/app-dir/app/app/hooks/use-pathname/page.client.js create mode 100644 test/e2e/app-dir/app/app/hooks/use-router/page.client.js create mode 100644 test/e2e/app-dir/app/app/hooks/use-router/sub-page/page.client.js create mode 100644 test/e2e/app-dir/app/app/hooks/use-search-params/page.client.js diff --git a/test/e2e/app-dir/app/app/client-with-errors/get-server-side-props/page.client.js b/test/e2e/app-dir/app/app/client-with-errors/get-server-side-props/page.client.js new file mode 100644 index 000000000000..8b4ae46ca94b --- /dev/null +++ b/test/e2e/app-dir/app/app/client-with-errors/get-server-side-props/page.client.js @@ -0,0 +1,7 @@ +export function getServerSideProps() { + return { props: {} } +} + +export default function Page() { + return null +} diff --git a/test/e2e/app-dir/app/app/client-with-errors/get-static-props/page.client.js b/test/e2e/app-dir/app/app/client-with-errors/get-static-props/page.client.js new file mode 100644 index 000000000000..5acfaee644a8 --- /dev/null +++ b/test/e2e/app-dir/app/app/client-with-errors/get-static-props/page.client.js @@ -0,0 +1,7 @@ +export function getStaticProps() { + return { props: {} } +} + +export default function Page() { + return null +} diff --git a/test/e2e/app-dir/app/app/hooks/use-pathname/page.client.js b/test/e2e/app-dir/app/app/hooks/use-pathname/page.client.js new file mode 100644 index 000000000000..8aa409b3dd0a --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-pathname/page.client.js @@ -0,0 +1,13 @@ +import { usePathname } from 'next/dist/client/components/hooks-client' + +export default function Page() { + const pathname = usePathname() + + return ( + <> +

+ hello from /hooks/use-pathname +

+ + ) +} diff --git a/test/e2e/app-dir/app/app/hooks/use-router/page.client.js b/test/e2e/app-dir/app/app/hooks/use-router/page.client.js new file mode 100644 index 000000000000..844c53fe1e4f --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-router/page.client.js @@ -0,0 +1,17 @@ +import { useRouter } from 'next/dist/client/components/hooks-client' + +export default function Page() { + const router = useRouter() + + return ( + <> +

hello from /hooks/use-router

+ + + ) +} diff --git a/test/e2e/app-dir/app/app/hooks/use-router/sub-page/page.client.js b/test/e2e/app-dir/app/app/hooks/use-router/sub-page/page.client.js new file mode 100644 index 000000000000..14c197c67f46 --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-router/sub-page/page.client.js @@ -0,0 +1,3 @@ +export default function Page() { + return

hello from /hooks/use-router/sub-page

+} diff --git a/test/e2e/app-dir/app/app/hooks/use-search-params/page.client.js b/test/e2e/app-dir/app/app/hooks/use-search-params/page.client.js new file mode 100644 index 000000000000..f16caf12cf84 --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-search-params/page.client.js @@ -0,0 +1,19 @@ +import { useSearchParams } from 'next/dist/client/components/hooks-client' + +export default function Page() { + const params = useSearchParams() + + return ( + <> +

+ hello from /hooks/use-search-params +

+ + ) +} diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 4509d0154ef8..e87dc06dfc57 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -750,6 +750,74 @@ describe('app dir', () => { }) }) + describe('client components', () => { + describe('hooks', () => { + describe('usePathname', () => { + it('should have the correct pathname', async () => { + const html = await renderViaHTTP(next.url, '/hooks/use-pathname') + const $ = cheerio.load(html) + expect($('#pathname').attr('data-pathname')).toBe( + '/hooks/use-pathname' + ) + }) + }) + + describe('useSearchParams', () => { + it('should have the correct search params', async () => { + const html = await renderViaHTTP( + next.url, + '/hooks/use-search-params?first=value&second=other%20value&third' + ) + const $ = cheerio.load(html) + const el = $('#params') + expect(el.attr('data-param-first')).toBe('value') + expect(el.attr('data-param-second')).toBe('other value') + expect(el.attr('data-param-third')).toBe('') + expect(el.attr('data-param-not-real')).toBe('N/A') + }) + }) + + describe('useRouter', () => { + it('should allow access to the router', async () => { + const browser = await webdriver(next.url, '/hooks/use-router') + + try { + // Wait for the page to load, click the button (which uses a method + // on the router) and then wait for the correct page to load. + await browser.waitForElementByCss('#router') + await browser.elementById('button-push').click() + await browser.waitForElementByCss('#router-sub-page') + + // Go back (confirming we did do a hard push), and wait for the + // correct previous page. + await browser.back() + await browser.waitForElementByCss('#router') + } finally { + await browser.close() + } + }) + }) + }) + + it('should throw an error when getStaticProps is used', async () => { + const res = await fetchViaHTTP( + next.url, + '/client-with-errors/get-static-props' + ) + expect(res.status).toBe(500) + expect(await res.text()).toContain('Internal Server Error') + }) + + it('should throw an error when getServerSideProps is used', async () => { + const res = await fetchViaHTTP( + next.url, + '/client-with-errors/get-server-side-props' + ) + expect(res.status).toBe(500) + expect(await res.text()).toContain('Internal Server Error') + }) + }) + describe('css support', () => { describe('server layouts', () => { it('should support global css inside server layouts', async () => { From 737bb9274d583bc347441f803e86178e948648b3 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 11 Jul 2022 12:37:09 -0600 Subject: [PATCH 11/17] tests: added tests for query/params handling --- .../app/app/param-and-query/[slug]/page.client.js | 15 +++++++++++++++ test/e2e/app-dir/index.test.ts | 11 +++++++++++ 2 files changed, 26 insertions(+) create mode 100644 test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js diff --git a/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js b/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js new file mode 100644 index 000000000000..4b4ae719918e --- /dev/null +++ b/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js @@ -0,0 +1,15 @@ +import { useRouter } from 'next/dist/client/components/hooks-client' + +export default function Page() { + const router = useRouter() + + return ( +

+ hello from /param-and-query/{router.params.slug}?slug={router.query.slug} +

+ ) +} diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index e87dc06dfc57..f7586b07d66d 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -796,6 +796,17 @@ describe('app dir', () => { await browser.close() } }) + + it('should have consistent query and params handling', async () => { + const html = await renderViaHTTP( + next.url, + '/param-and-query/params?slug=query' + ) + const $ = cheerio.load(html) + const el = $('#params-and-query') + expect(el.attr('data-params')).toBe('params') + expect(el.attr('data-query')).toBe('query') + }) }) }) From 228f5bcd49a269e75afae62477ad5614901358f9 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 11 Jul 2022 14:40:51 -0600 Subject: [PATCH 12/17] tests: fix tests for param/query to use props --- .../app/app/param-and-query/[slug]/page.client.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js b/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js index 4b4ae719918e..f7691ce391c8 100644 --- a/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js +++ b/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js @@ -1,15 +1,9 @@ import { useRouter } from 'next/dist/client/components/hooks-client' -export default function Page() { - const router = useRouter() - +export default function Page({ params, query }) { return ( -

- hello from /param-and-query/{router.params.slug}?slug={router.query.slug} +

+ hello from /param-and-query/{params.slug}?slug={query.slug}

) } From bbddecfeab891511a995790a75d5d78fc8126381 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 11 Jul 2022 15:34:34 -0600 Subject: [PATCH 13/17] tests: added some skipped tests for unimplemented features --- .../hooks/use-cookies/client/page.client.js | 8 ++ .../hooks/use-headers/client/page.client.js | 8 ++ .../use-layout-segments/server/page.server.js | 8 ++ .../hooks/use-params/server/page.server.js | 8 ++ .../hooks/use-pathname/server/page.server.js | 8 ++ .../use-preview-data/client/page.client.js | 8 ++ .../hooks/use-router/server/page.server.js | 8 ++ .../use-search-params/server/page.server.js | 8 ++ .../server/page.server.js | 8 ++ test/e2e/app-dir/index.test.ts | 93 +++++++++++++++++++ 10 files changed, 165 insertions(+) create mode 100644 test/e2e/app-dir/app/app/hooks/use-cookies/client/page.client.js create mode 100644 test/e2e/app-dir/app/app/hooks/use-headers/client/page.client.js create mode 100644 test/e2e/app-dir/app/app/hooks/use-layout-segments/server/page.server.js create mode 100644 test/e2e/app-dir/app/app/hooks/use-params/server/page.server.js create mode 100644 test/e2e/app-dir/app/app/hooks/use-pathname/server/page.server.js create mode 100644 test/e2e/app-dir/app/app/hooks/use-preview-data/client/page.client.js create mode 100644 test/e2e/app-dir/app/app/hooks/use-router/server/page.server.js create mode 100644 test/e2e/app-dir/app/app/hooks/use-search-params/server/page.server.js create mode 100644 test/e2e/app-dir/app/app/hooks/use-selected-layout-segment/server/page.server.js diff --git a/test/e2e/app-dir/app/app/hooks/use-cookies/client/page.client.js b/test/e2e/app-dir/app/app/hooks/use-cookies/client/page.client.js new file mode 100644 index 000000000000..36e5fbb96f9f --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-cookies/client/page.client.js @@ -0,0 +1,8 @@ +import { useCookies } from 'next/dist/client/components/hooks-server' + +export default function Page() { + // This should throw an error. + useCookies() + + return null +} diff --git a/test/e2e/app-dir/app/app/hooks/use-headers/client/page.client.js b/test/e2e/app-dir/app/app/hooks/use-headers/client/page.client.js new file mode 100644 index 000000000000..9fb9b875af8a --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-headers/client/page.client.js @@ -0,0 +1,8 @@ +import { useHeaders } from 'next/dist/client/components/hooks-server' + +export default function Page() { + // This should throw an error. + useHeaders() + + return null +} diff --git a/test/e2e/app-dir/app/app/hooks/use-layout-segments/server/page.server.js b/test/e2e/app-dir/app/app/hooks/use-layout-segments/server/page.server.js new file mode 100644 index 000000000000..24902634d214 --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-layout-segments/server/page.server.js @@ -0,0 +1,8 @@ +import { useLayoutSegments } from 'next/dist/client/components/hooks-client' + +export default function Page() { + // This should throw an error. + useLayoutSegments() + + return null +} diff --git a/test/e2e/app-dir/app/app/hooks/use-params/server/page.server.js b/test/e2e/app-dir/app/app/hooks/use-params/server/page.server.js new file mode 100644 index 000000000000..c3f5252df45f --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-params/server/page.server.js @@ -0,0 +1,8 @@ +import { useParams } from 'next/dist/client/components/hooks-client' + +export default function Page() { + // This should throw an error. + useParams() + + return null +} diff --git a/test/e2e/app-dir/app/app/hooks/use-pathname/server/page.server.js b/test/e2e/app-dir/app/app/hooks/use-pathname/server/page.server.js new file mode 100644 index 000000000000..9c4c9543406a --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-pathname/server/page.server.js @@ -0,0 +1,8 @@ +import { usePathname } from 'next/dist/client/components/hooks-client' + +export default function Page() { + // This should throw an error. + usePathname() + + return null +} diff --git a/test/e2e/app-dir/app/app/hooks/use-preview-data/client/page.client.js b/test/e2e/app-dir/app/app/hooks/use-preview-data/client/page.client.js new file mode 100644 index 000000000000..094c66773e73 --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-preview-data/client/page.client.js @@ -0,0 +1,8 @@ +import { usePreviewData } from 'next/dist/client/components/hooks-server' + +export default function Page() { + // This should throw an error. + usePreviewData() + + return null +} diff --git a/test/e2e/app-dir/app/app/hooks/use-router/server/page.server.js b/test/e2e/app-dir/app/app/hooks/use-router/server/page.server.js new file mode 100644 index 000000000000..ca3f10a333cb --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-router/server/page.server.js @@ -0,0 +1,8 @@ +import { useRouter } from 'next/dist/client/components/hooks-client' + +export default function Page() { + // This should throw an error. + useRouter() + + return null +} diff --git a/test/e2e/app-dir/app/app/hooks/use-search-params/server/page.server.js b/test/e2e/app-dir/app/app/hooks/use-search-params/server/page.server.js new file mode 100644 index 000000000000..3468f385f6a6 --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-search-params/server/page.server.js @@ -0,0 +1,8 @@ +import { useSearchParams } from 'next/dist/client/components/hooks-client' + +export default function Page() { + // This should throw an error. + useSearchParams() + + return null +} diff --git a/test/e2e/app-dir/app/app/hooks/use-selected-layout-segment/server/page.server.js b/test/e2e/app-dir/app/app/hooks/use-selected-layout-segment/server/page.server.js new file mode 100644 index 000000000000..4f9a6f42af71 --- /dev/null +++ b/test/e2e/app-dir/app/app/hooks/use-selected-layout-segment/server/page.server.js @@ -0,0 +1,8 @@ +import { useSelectedLayoutSegment } from 'next/dist/client/components/hooks-client' + +export default function Page() { + // This should throw an error. + useSelectedLayoutSegment() + + return null +} diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index f7586b07d66d..9bb53f518bce 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -747,11 +747,104 @@ describe('app dir', () => { } }) }) + + describe('useRouter', () => { + // TODO: remove skip when implemented + it.skip('should throw an error when imported', async () => { + const res = await fetchViaHTTP(next.url, '/hooks/use-router/server') + expect(res.status).toBe(500) + expect(await res.text()).toContain('Internal Server Error') + }) + }) + + describe('useParams', () => { + // TODO: remove skip when implemented + it.skip('should throw an error when imported', async () => { + const res = await fetchViaHTTP(next.url, '/hooks/use-params/server') + expect(res.status).toBe(500) + expect(await res.text()).toContain('Internal Server Error') + }) + }) + + describe('useSearchParams', () => { + // TODO: remove skip when implemented + it.skip('should throw an error when imported', async () => { + const res = await fetchViaHTTP( + next.url, + '/hooks/use-search-params/server' + ) + expect(res.status).toBe(500) + expect(await res.text()).toContain('Internal Server Error') + }) + }) + + describe('usePathname', () => { + // TODO: remove skip when implemented + it.skip('should throw an error when imported', async () => { + const res = await fetchViaHTTP(next.url, '/hooks/use-pathname/server') + expect(res.status).toBe(500) + expect(await res.text()).toContain('Internal Server Error') + }) + }) + + describe('useLayoutSegments', () => { + // TODO: remove skip when implemented + it.skip('should throw an error when imported', async () => { + const res = await fetchViaHTTP( + next.url, + '/hooks/use-layout-segments/server' + ) + expect(res.status).toBe(500) + expect(await res.text()).toContain('Internal Server Error') + }) + }) + + describe('useSelectedLayoutSegment', () => { + // TODO: remove skip when implemented + it.skip('should throw an error when imported', async () => { + const res = await fetchViaHTTP( + next.url, + '/hooks/use-selected-layout-segment/server' + ) + expect(res.status).toBe(500) + expect(await res.text()).toContain('Internal Server Error') + }) + }) }) }) describe('client components', () => { describe('hooks', () => { + describe('useCookies', () => { + // TODO: remove skip when implemented + it.skip('should throw an error when imported', async () => { + const res = await fetchViaHTTP(next.url, '/hooks/use-cookies/client') + expect(res.status).toBe(500) + expect(await res.text()).toContain('Internal Server Error') + }) + }) + + describe('usePreviewData', () => { + // TODO: remove skip when implemented + it.skip('should throw an error when imported', async () => { + const res = await fetchViaHTTP( + next.url, + '/hooks/use-preview-data/client' + ) + expect(res.status).toBe(500) + expect(await res.text()).toContain('Internal Server Error') + }) + }) + + describe('useHeaders', () => { + // TODO: remove skip when implemented + it.skip('should throw an error when imported', async () => { + const res = await fetchViaHTTP(next.url, '/hooks/use-headers/client') + expect(res.status).toBe(500) + expect(await res.text()).toContain('Internal Server Error') + }) + }) + describe('usePathname', () => { it('should have the correct pathname', async () => { const html = await renderViaHTTP(next.url, '/hooks/use-pathname') From d8239ec7b5586438e55b92a4c08c0e415cf44941 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 12 Jul 2022 12:37:24 -0600 Subject: [PATCH 14/17] tests: linting --- test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js b/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js index f7691ce391c8..cb2b99034594 100644 --- a/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js +++ b/test/e2e/app-dir/app/app/param-and-query/[slug]/page.client.js @@ -1,5 +1,3 @@ -import { useRouter } from 'next/dist/client/components/hooks-client' - export default function Page({ params, query }) { return (

From 759bc6376ea55a7e0018b10d879fcf690f453d55 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 12 Jul 2022 13:38:26 -0600 Subject: [PATCH 15/17] refactor: updated TODO -> TODO-APP --- packages/next/client/link.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/client/link.tsx b/packages/next/client/link.tsx index 607a6c1c1790..d32089a71b19 100644 --- a/packages/next/client/link.tsx +++ b/packages/next/client/link.tsx @@ -33,7 +33,7 @@ type InternalLinkProps = { replace?: boolean /** - * TODO + * TODO-APP */ soft?: boolean scroll?: boolean From e4a57e452a7fcdb43986a436017eccc8a9edccdd Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Wed, 13 Jul 2022 12:03:07 -0600 Subject: [PATCH 16/17] tests: added some more test cases --- .../app/app/hooks/use-headers/page.server.js | 3 ++ .../app-dir/app/app/navigation/page.server.js | 7 +++ test/e2e/app-dir/index.test.ts | 44 +++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/test/e2e/app-dir/app/app/hooks/use-headers/page.server.js b/test/e2e/app-dir/app/app/hooks/use-headers/page.server.js index bd2b1153eba8..2c73997ad4da 100644 --- a/test/e2e/app-dir/app/app/hooks/use-headers/page.server.js +++ b/test/e2e/app-dir/app/app/hooks/use-headers/page.server.js @@ -14,6 +14,9 @@ export default function Page() { ) : (

Does not have x-use-headers header

)} + {'referer' in headers && headers['referer'] && ( +

Has referer header

+ )} ) } diff --git a/test/e2e/app-dir/app/app/navigation/page.server.js b/test/e2e/app-dir/app/app/navigation/page.server.js index 530c16824126..1e53433733bb 100644 --- a/test/e2e/app-dir/app/app/navigation/page.server.js +++ b/test/e2e/app-dir/app/app/navigation/page.server.js @@ -1,10 +1,17 @@ import { nanoid } from 'nanoid' +import Link from 'next/link' export default function Page() { return ( <>

{nanoid()}

hello from /navigation

+ + useCookies + + + useHeaders + ) } diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 9bb53f518bce..22177cec327c 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -694,6 +694,39 @@ describe('app dir', () => { await browser.close() } }) + + it('should access cookies on navigation', async () => { + const browser = await webdriver(next.url, '/navigation') + + try { + // Click the cookies link to verify it can't see the cookie that's + // not there. + await browser.elementById('use-cookies').click() + await browser.waitForElementByCss('#does-not-have-cookie') + + // Go back and add the cookies. + await browser.back() + await browser.waitForElementByCss('#from-navigation') + browser.addCookie({ name: 'use-cookies', value: 'value' }) + + // Click the cookies link again to see that the cookie can be picked + // up again. + await browser.elementById('use-cookies').click() + await browser.waitForElementByCss('#has-cookie') + + // Go back and remove the cookies. + await browser.back() + await browser.waitForElementByCss('#from-navigation') + browser.deleteCookies() + + // Verify for the last time that after clicking the cookie link + // again, there are no cookies. + await browser.elementById('use-cookies').click() + await browser.waitForElementByCss('#does-not-have-cookie') + } finally { + await browser.close() + } + }) }) describe('useHeaders', () => { @@ -720,6 +753,17 @@ describe('app dir', () => { expect($('#has-header').length).toBe(1) expect($('#does-not-have-header').length).toBe(0) }) + + it('should access headers on navigation', async () => { + const browser = await webdriver(next.url, '/navigation') + + try { + await browser.elementById('use-headers').click() + await browser.waitForElementByCss('#has-referer') + } finally { + await browser.close() + } + }) }) describe('usePreviewData', () => { From bb3b9156343b2c24efa7af4a83679bf954310f55 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 14 Jul 2022 10:17:42 -0600 Subject: [PATCH 17/17] tests: skipped failing test --- test/e2e/app-dir/index.test.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 22177cec327c..757d5e6a10b2 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -427,7 +427,8 @@ describe('app dir', () => { } }) - it('should allow linking from app page to pages page', async () => { + // TODO-APP: should enable when implemented + it.skip('should allow linking from app page to pages page', async () => { const browser = await webdriver(next.url, '/pages-linking') try { @@ -793,7 +794,7 @@ describe('app dir', () => { }) describe('useRouter', () => { - // TODO: remove skip when implemented + // TODO-APP: should enable when implemented it.skip('should throw an error when imported', async () => { const res = await fetchViaHTTP(next.url, '/hooks/use-router/server') expect(res.status).toBe(500) @@ -802,7 +803,7 @@ describe('app dir', () => { }) describe('useParams', () => { - // TODO: remove skip when implemented + // TODO-APP: should enable when implemented it.skip('should throw an error when imported', async () => { const res = await fetchViaHTTP(next.url, '/hooks/use-params/server') expect(res.status).toBe(500) @@ -811,7 +812,7 @@ describe('app dir', () => { }) describe('useSearchParams', () => { - // TODO: remove skip when implemented + // TODO-APP: should enable when implemented it.skip('should throw an error when imported', async () => { const res = await fetchViaHTTP( next.url, @@ -823,7 +824,7 @@ describe('app dir', () => { }) describe('usePathname', () => { - // TODO: remove skip when implemented + // TODO-APP: should enable when implemented it.skip('should throw an error when imported', async () => { const res = await fetchViaHTTP(next.url, '/hooks/use-pathname/server') expect(res.status).toBe(500) @@ -832,7 +833,7 @@ describe('app dir', () => { }) describe('useLayoutSegments', () => { - // TODO: remove skip when implemented + // TODO-APP: should enable when implemented it.skip('should throw an error when imported', async () => { const res = await fetchViaHTTP( next.url, @@ -844,7 +845,7 @@ describe('app dir', () => { }) describe('useSelectedLayoutSegment', () => { - // TODO: remove skip when implemented + // TODO-APP: should enable when implemented it.skip('should throw an error when imported', async () => { const res = await fetchViaHTTP( next.url, @@ -860,7 +861,7 @@ describe('app dir', () => { describe('client components', () => { describe('hooks', () => { describe('useCookies', () => { - // TODO: remove skip when implemented + // TODO-APP: should enable when implemented it.skip('should throw an error when imported', async () => { const res = await fetchViaHTTP(next.url, '/hooks/use-cookies/client') expect(res.status).toBe(500) @@ -869,7 +870,7 @@ describe('app dir', () => { }) describe('usePreviewData', () => { - // TODO: remove skip when implemented + // TODO-APP: should enable when implemented it.skip('should throw an error when imported', async () => { const res = await fetchViaHTTP( next.url, @@ -881,7 +882,7 @@ describe('app dir', () => { }) describe('useHeaders', () => { - // TODO: remove skip when implemented + // TODO-APP: should enable when implemented it.skip('should throw an error when imported', async () => { const res = await fetchViaHTTP(next.url, '/hooks/use-headers/client') expect(res.status).toBe(500)