diff --git a/e2e/pages.spec.ts b/e2e/pages.spec.ts index 330dfa97e..b74c30bab 100644 --- a/e2e/pages.spec.ts +++ b/e2e/pages.spec.ts @@ -106,6 +106,93 @@ const testCases: TestsCase[] = [ }, ], }, + { + name: 'GitBook Site (Navigation when switching variant)', + baseUrl: 'https://gitbook-open-e2e-sites.gitbook.io/', + tests: [ + { + name: 'Keep navigation path/route when switching variant (Public)', + url: 'api-multi-versions/reference/api-reference/pets', + screenshot: false, + run: async (page) => { + const spaceDrowpdown = await page.waitForSelector( + '[data-testid="space-dropdown-button"]', + ); + await spaceDrowpdown.click(); + + // Click the second variant in the dropdown + await page + .getByRole('link', { + name: '2.0', + }) + .click(); + + // It should keep the current page path, i.e "reference/api-reference/pets" when navigating to the new variant + await page.waitForURL( + 'https://gitbook-open-e2e-sites.gitbook.io/api-multi-versions/v/2.0/reference/api-reference/pets', + ); + }, + }, + { + name: 'Keep navigation path/route when switching variant (Share link)', + url: 'api-multi-versions-share-links/bRfQbzwsK8rbN1GRxx7K/reference/api-reference/pets', + screenshot: false, + run: async (page) => { + const spaceDrowpdown = await page.waitForSelector( + '[data-testid="space-dropdown-button"]', + ); + await spaceDrowpdown.click(); + + // Click the second variant in the dropdown + await page + .getByRole('link', { + name: '2.0', + }) + .click(); + + // It should keep the current page path, i.e "reference/api-reference/pets" when navigating to the new variant + await page.waitForURL( + 'https://gitbook-open-e2e-sites.gitbook.io/api-multi-versions-share-links/bRfQbzwsK8rbN1GRxx7K/v/2.0/reference/api-reference/pets', + ); + }, + }, + { + name: 'Keep navigation path/route when switching variant (VA)', + screenshot: false, + url: (() => { + const privateKey = 'c26190fc-74b2-4b54-9fc7-df9941104953'; + const token = jwt.sign( + { + name: 'gitbook-open-tests', + }, + privateKey, + { + expiresIn: '24h', + }, + ); + return `api-multi-versions-va/reference/api-reference/pets?jwt_token=${token}`; + })(), + run: async (page) => { + const spaceDrowpdown = await page.waitForSelector( + '[data-testid="space-dropdown-button"]', + ); + await spaceDrowpdown.click(); + + // Click the second variant in the dropdown + await page + .getByRole('link', { + name: '2.0', + }) + .click(); + + // It should keep the current page path, i.e "reference/api-reference/pets" when navigating to the new variant + await page.waitForURL( + 'https://gitbook-open-e2e-sites.gitbook.io/api-multi-versions-va/v/2.0/reference/api-reference/pets', + ); + }, + }, + ], + }, { name: 'GitBook', baseUrl: 'https://docs.gitbook.com', diff --git a/src/components/Header/SpacesDropdown.tsx b/src/components/Header/SpacesDropdown.tsx index 19743fc22..6b5434abd 100644 --- a/src/components/Header/SpacesDropdown.tsx +++ b/src/components/Header/SpacesDropdown.tsx @@ -1,8 +1,9 @@ -import { Collection, Space } from '@gitbook/api'; +import { Space } from '@gitbook/api'; import { tcls } from '@/lib/tailwind'; -import { Dropdown, DropdownChevron, DropdownMenu, DropdownMenuItem } from './Dropdown'; +import { Dropdown, DropdownChevron, DropdownMenu } from './Dropdown'; +import { SpacesDropdownMenuItem } from './SpacesDropdownMenuItem'; export function SpacesDropdown(props: { space: Space; spaces: Space[] }) { const { space, spaces } = props; @@ -29,14 +30,12 @@ export function SpacesDropdown(props: { space: Space; spaces: Space[] }) { )} > - {spaces.map((otherSpace) => ( - - {otherSpace.title} - + {spaces.map((otherSpace, index) => ( + ))} diff --git a/src/components/Header/SpacesDropdownMenuItem.tsx b/src/components/Header/SpacesDropdownMenuItem.tsx new file mode 100644 index 000000000..fd07b0543 --- /dev/null +++ b/src/components/Header/SpacesDropdownMenuItem.tsx @@ -0,0 +1,30 @@ +'use client'; + +import { Space } from '@gitbook/api'; +import { useSelectedLayoutSegment } from 'next/navigation'; + +import { DropdownMenuItem } from './Dropdown'; + +function useVariantSpaceHref(variantSpace: Space) { + const currentPathname = useSelectedLayoutSegment() ?? ''; + const targetUrl = new URL(variantSpace.urls.published ?? variantSpace.urls.app); + targetUrl.pathname += `/${currentPathname}`; + targetUrl.pathname = targetUrl.pathname.replace(/\/{2,}/g, '/').replace(/\/$/, ''); + + return targetUrl.toString(); +} + +export function SpacesDropdownMenuItem(props: { variantSpace: Space; currentSpace: Space }) { + const { variantSpace, currentSpace } = props; + const variantHref = useVariantSpaceHref(variantSpace); + + return ( + + {variantSpace.title} + + ); +}