diff --git a/test/e2e/app-dir/use-selected-layout-segment-s/app/layout.tsx b/test/e2e/app-dir/use-selected-layout-segment-s/app/layout.tsx new file mode 100644 index 000000000000..4013c87af92f --- /dev/null +++ b/test/e2e/app-dir/use-selected-layout-segment-s/app/layout.tsx @@ -0,0 +1,29 @@ +import Link from 'next/link' +import RenderValues from './render-values' + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + + + + + + Change static + + + Change param + + + Change param + + {children} + + + ) +} diff --git a/test/e2e/app-dir/use-selected-layout-segment-s/app/render-values.tsx b/test/e2e/app-dir/use-selected-layout-segment-s/app/render-values.tsx new file mode 100644 index 000000000000..cb2cc8ddbfdb --- /dev/null +++ b/test/e2e/app-dir/use-selected-layout-segment-s/app/render-values.tsx @@ -0,0 +1,19 @@ +'use client' + +import { + useSelectedLayoutSegment, + useSelectedLayoutSegments, +} from 'next/navigation' + +export default function RenderValues({ prefix }: { prefix: string }) { + return ( +
+
+ {JSON.stringify(useSelectedLayoutSegments())} +
+
+ {JSON.stringify(useSelectedLayoutSegment())} +
+
+ ) +} diff --git a/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/different-segment/page.tsx b/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/different-segment/page.tsx new file mode 100644 index 000000000000..c17431379f96 --- /dev/null +++ b/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/different-segment/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return null +} diff --git a/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/layout.tsx b/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/layout.tsx new file mode 100644 index 000000000000..fd9a887f558b --- /dev/null +++ b/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/layout.tsx @@ -0,0 +1,10 @@ +import RenderValues from '../../render-values' + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + <> + + {children} + + ) +} diff --git a/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/segment-name2/[param2]/[...catchall]/layout.tsx b/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/segment-name2/[param2]/[...catchall]/layout.tsx new file mode 100644 index 000000000000..0cc7c3bd980c --- /dev/null +++ b/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/segment-name2/[param2]/[...catchall]/layout.tsx @@ -0,0 +1,10 @@ +import RenderValues from '../../../../../render-values' + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + <> + + {children} + + ) +} diff --git a/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/segment-name2/[param2]/[...catchall]/page.tsx b/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/segment-name2/[param2]/[...catchall]/page.tsx new file mode 100644 index 000000000000..c17431379f96 --- /dev/null +++ b/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/segment-name2/[param2]/[...catchall]/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return null +} diff --git a/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/segment-name2/[param2]/layout.tsx b/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/segment-name2/[param2]/layout.tsx new file mode 100644 index 000000000000..1b27aa42497f --- /dev/null +++ b/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/segment-name2/[param2]/layout.tsx @@ -0,0 +1,10 @@ +import RenderValues from '../../../../render-values' + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + <> + + {children} + + ) +} diff --git a/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/segment-name2/layout.tsx b/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/segment-name2/layout.tsx new file mode 100644 index 000000000000..a256a87f595f --- /dev/null +++ b/test/e2e/app-dir/use-selected-layout-segment-s/app/segment-name/[param1]/segment-name2/layout.tsx @@ -0,0 +1,10 @@ +import RenderValues from '../../../render-values' + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + <> + + {children} + + ) +} diff --git a/test/e2e/app-dir/use-selected-layout-segment-s/next.config.js b/test/e2e/app-dir/use-selected-layout-segment-s/next.config.js new file mode 100644 index 000000000000..cfa3ac3d7aa9 --- /dev/null +++ b/test/e2e/app-dir/use-selected-layout-segment-s/next.config.js @@ -0,0 +1,5 @@ +module.exports = { + experimental: { + appDir: true, + }, +} diff --git a/test/e2e/app-dir/use-selected-layout-segment-s/use-selected-layout-segment-s.test.ts b/test/e2e/app-dir/use-selected-layout-segment-s/use-selected-layout-segment-s.test.ts new file mode 100644 index 000000000000..12410ceb089b --- /dev/null +++ b/test/e2e/app-dir/use-selected-layout-segment-s/use-selected-layout-segment-s.test.ts @@ -0,0 +1,141 @@ +import { createNext, FileRef } from 'e2e-utils' +import { NextInstance } from 'test/lib/next-modes/base' +import webdriver from 'next-webdriver' +import { waitFor } from 'next-test-utils' + +describe('useSelectedLayoutSegment(s)', () => { + let next: NextInstance + + beforeAll(async () => { + next = await createNext({ + files: new FileRef(__dirname), + dependencies: { + react: 'latest', + 'react-dom': 'latest', + typescript: 'latest', + '@types/react': 'latest', + '@types/node': 'latest', + }, + }) + }) + afterAll(() => next.destroy()) + + let browser: Awaited> + beforeEach(async () => { + browser = await webdriver( + next.url, + '/segment-name/value1/segment-name2/value2/value3/value4' + ) + }) + + it('should return correct values for root layout', async () => { + expect( + await browser.elementByCss('#root > .segments').text() + ).toMatchInlineSnapshot( + `"[\\"segment-name\\",\\"value1\\",\\"segment-name2\\",\\"value2\\",\\"value3/value4\\"]"` + ) + + expect( + await browser.elementByCss('#root > .segment').text() + ).toMatchInlineSnapshot(`"\\"segment-name\\""`) + }) + + it('should return correct values in layout before static segment', async () => { + expect( + await browser.elementByCss('#before-static > .segments').text() + ).toMatchInlineSnapshot( + `"[\\"segment-name2\\",\\"value2\\",\\"value3/value4\\"]"` + ) + + expect( + await browser.elementByCss('#before-static > .segment').text() + ).toMatchInlineSnapshot(`"\\"segment-name2\\""`) + }) + + it('should return correct values in layout before param segment', async () => { + expect( + await browser.elementByCss('#before-param > .segments').text() + ).toMatchInlineSnapshot(`"[\\"value2\\",\\"value3/value4\\"]"`) + + expect( + await browser.elementByCss('#before-param > .segment').text() + ).toMatchInlineSnapshot(`"\\"value2\\""`) + }) + + it('should return correct values in layout before catchall segment', async () => { + expect( + await browser.elementByCss('#before-catchall > .segments').text() + ).toMatchInlineSnapshot(`"[\\"value3/value4\\"]"`) + + expect( + await browser.elementByCss('#before-catchall > .segment').text() + ).toMatchInlineSnapshot(`"\\"value3/value4\\""`) + }) + + it('should return correct values in layout after last segment', async () => { + expect( + await browser.elementByCss('#final > .segments').text() + ).toMatchInlineSnapshot(`"[]"`) + + expect( + await browser.elementByCss('#final > .segment').text() + ).toMatchInlineSnapshot(`"null"`) + }) + + it('should correctly update when changing static segment', async () => { + browser.elementById('change-static').click() + await waitFor(100) + + expect( + await browser.elementByCss('#root > .segments').text() + ).toMatchInlineSnapshot( + `"[\\"segment-name\\",\\"param1\\",\\"different-segment\\"]"` + ) + + expect( + await browser.elementByCss('#before-static > .segments').text() + ).toMatchInlineSnapshot(`"[\\"different-segment\\"]"`) + + expect( + await browser.elementByCss('#before-static > .segment').text() + ).toMatchInlineSnapshot(`"\\"different-segment\\""`) + }) + + it('should correctly update when changing param segment', async () => { + browser.elementById('change-param').click() + await waitFor(100) + + expect( + await browser.elementByCss('#root > .segments').text() + ).toMatchInlineSnapshot( + `"[\\"segment-name\\",\\"param1\\",\\"segment-name2\\",\\"different-value\\",\\"value3/value4'\\"]"` + ) + + expect( + await browser.elementByCss('#before-param > .segments').text() + ).toMatchInlineSnapshot(`"[\\"different-value\\",\\"value3/value4'\\"]"`) + + expect( + await browser.elementByCss('#before-param > .segment').text() + ).toMatchInlineSnapshot(`"\\"different-value\\""`) + }) + + it('should correctly update when changing catchall segment', async () => { + browser.elementById('change-catchall').click() + await waitFor(100) + + expect( + await browser.elementByCss('#root > .segments').text() + ).toMatchInlineSnapshot( + `"[\\"segment-name\\",\\"param1\\",\\"segment-name2\\",\\"value2\\",\\"different/random/paths'\\"]"` + ) + + expect( + await browser.elementByCss('#before-catchall > .segments').text() + ).toMatchInlineSnapshot(`"[\\"different/random/paths'\\"]"`) + + expect( + await browser.elementByCss('#before-catchall > .segment').text() + ).toMatchInlineSnapshot(`"\\"different/random/paths'\\""`) + }) +})