diff --git a/test/e2e/app-dir/app-client-cache/client-cache.parallel-routes.test.ts b/test/e2e/app-dir/app-client-cache/client-cache.parallel-routes.test.ts index 9dcaf5879785f..e268d298d2bff 100644 --- a/test/e2e/app-dir/app-client-cache/client-cache.parallel-routes.test.ts +++ b/test/e2e/app-dir/app-client-cache/client-cache.parallel-routes.test.ts @@ -1,12 +1,6 @@ import { nextTestSetup } from 'e2e-utils' -import { check } from 'next-test-utils' -import { Playwright } from 'next-webdriver' -import { - browserConfigWithFixedTime, - createRequestsListener, - fastForwardTo, - getPathname, -} from './test-utils' +import { createRouterAct } from 'router-act' +import { browserConfigWithFixedTime, fastForwardTo } from './test-utils' import path from 'path' describe('app dir client cache with parallel routes', () => { @@ -21,62 +15,120 @@ describe('app dir client cache with parallel routes', () => { } describe('prefetch={true}', () => { - let browser: Playwright - - beforeEach(async () => { - browser = await next.browser('/', browserConfigWithFixedTime) - }) - it('should prefetch the full page', async () => { - const { getRequests, clearRequests } = - await createRequestsListener(browser) - await check(() => { - return getRequests().some( - ([url, didPartialPrefetch]) => - getPathname(url) === '/0' && !didPartialPrefetch - ) - ? 'success' - : 'fail' - }, 'success') - - clearRequests() - - await browser - .elementByCss('[href="/0"]') - .click() - .waitForElementByCss('#random-number') - - expect(getRequests().every(([url]) => getPathname(url) !== '/0')).toEqual( - true + let act: ReturnType + const browser = await next.browser('/', { + beforePageLoad(page) { + browserConfigWithFixedTime.beforePageLoad(page) + act = createRouterAct(page) + }, + }) + + // Reveal the link to trigger prefetch and wait for it to complete + const link = await act( + async () => { + const reveal = await browser.elementByCss( + '[data-link-accordion="/0"]' + ) + await reveal.click() + return await browser.elementByCss('[href="/0"]') + }, + { includes: 'random-number' } ) + + // Navigate to /0 - should not make additional requests + await act(async () => { + await link.click() + await browser.waitForElementByCss('#random-number') + }, 'no-requests') }) it('should re-use the cache for the full page, only for 5 mins', async () => { - const randomNumber = await browser - .elementByCss('[href="/0"]') - .click() - .waitForElementByCss('#random-number') - .text() + let act: ReturnType + const browser = await next.browser('/', { + beforePageLoad(page) { + browserConfigWithFixedTime.beforePageLoad(page) + act = createRouterAct(page) + }, + }) + + // Toggle the link, assert on the prefetch content + const link = await act( + async () => { + const reveal = await browser.elementByCss( + '[data-link-accordion="/0"]' + ) + await reveal.click() + return await browser.elementByCss('[href="/0"]') + }, + { includes: 'random-number' } + ) - await browser.elementByCss('[href="/"]').click() + // Navigate to the page, assert no requests are made + const randomNumber = await act(async () => { + await link.click() + await browser.waitForElementByCss('#random-number') + return await browser.elementByCss('#random-number').text() + }, 'no-requests') + + // Toggle the home link, assert on the homepage content + const homeLink = await act( + async () => { + const reveal = await browser.elementByCss('[data-link-accordion="/"]') + await reveal.click() + return await browser.elementByCss('[href="/"]') + }, + { includes: 'home-page' } + ) - const number = await browser - .elementByCss('[href="/0"]') - .click() - .waitForElementByCss('#random-number') - .text() + // Navigate home, assert no requests are made + await act(async () => { + await homeLink.click() + await browser.waitForElementByCss('#home-page') + }, 'no-requests') + + // Toggle the link to the other page again, navigate, assert no requests (because it's cached) + const number = await act(async () => { + const reveal = await browser.elementByCss('[data-link-accordion="/0"]') + await reveal.click() + const link = await browser.elementByCss('[href="/0"]') + await link.click() + await browser.waitForElementByCss('#random-number') + return await browser.elementByCss('#random-number').text() + }, 'no-requests') expect(number).toBe(randomNumber) + // Navigate back home + await act(async () => { + const reveal = await browser.elementByCss('[data-link-accordion="/"]') + await reveal.click() + const homeLink = await browser.elementByCss('[href="/"]') + await homeLink.click() + await browser.waitForElementByCss('#home-page') + }, 'no-requests') + + // Fast forward 5 minutes await browser.eval(fastForwardTo, 5 * 60 * 1000) - await browser.elementByCss('[href="/"]').click() + // Toggle the link to the other page again, assert on prefetch content + const linkAfterExpiry = await act( + async () => { + const reveal = await browser.elementByCss( + '[data-link-accordion="/0"]' + ) + await reveal.click() + return await browser.elementByCss('[href="/0"]') + }, + { includes: 'random-number' } + ) - const newNumber = await browser - .elementByCss('[href="/0"]') - .click() - .waitForElementByCss('#random-number') - .text() + // Navigate to the page and verify the content is fresh (different from cached) + const newNumber = await act(async () => { + await linkAfterExpiry.click() + await browser.waitForElementByCss('#random-number') + return await browser.elementByCss('#random-number').text() + }, 'no-requests') expect(newNumber).not.toBe(randomNumber) }) diff --git a/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/[id]/page.js b/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/[id]/page.js index cd2e35b1f72a6..b366e197faf64 100644 --- a/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/[id]/page.js +++ b/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/[id]/page.js @@ -1,4 +1,4 @@ -import Link from 'next/link' +import { LinkAccordion } from '../components/link-accordion' export default async function Page() { const randomNumber = await new Promise((resolve) => { @@ -8,11 +8,9 @@ export default async function Page() { }) return ( - <> -
- Back to Home -
+
+ Back to Home
{randomNumber}
- +
) } diff --git a/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/components/link-accordion.tsx b/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/components/link-accordion.tsx new file mode 100644 index 0000000000000..eeb6094873185 --- /dev/null +++ b/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/components/link-accordion.tsx @@ -0,0 +1,25 @@ +'use client' + +import Link from 'next/link' +import { useState } from 'react' + +export function LinkAccordion({ href, children, prefetch = undefined }) { + const [isVisible, setIsVisible] = useState(false) + return ( + <> + setIsVisible(!isVisible)} + data-link-accordion={href} + /> + {isVisible ? ( + + {children} + + ) : ( + <>{children} (link is hidden) + )} + + ) +} diff --git a/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/page.js b/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/page.js index 9adcd6a6d0a69..cf2a3cd5e10de 100644 --- a/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/page.js +++ b/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/page.js @@ -1,11 +1,11 @@ -import Link from 'next/link' +import { LinkAccordion } from './components/link-accordion' export default function Page() { return ( -
- +
+ To Dynamic Page - +
) }