import { nextTestSetup } from 'e2e-utils' import { createRouterAct } from 'router-act' import path from 'path' import { Playwright } from 'next-webdriver' import type { Page as PlaywrightPage } from 'playwright' describe('app dir client cache with parallel routes', () => { const { next, isNextDev } = nextTestSetup({ files: path.join(__dirname, 'fixtures', 'parallel-routes'), }) if (isNextDev) { // dev doesn't support prefetch={true} it('should skip dev', () => {}) return } async function reveal(browser: Playwright, href: string) { // Get the reveal element and scroll it into view. const reveal = await browser.elementByCss(`[data-link-accordion="${href}"]`) await reveal.scrollIntoViewIfNeeded() // Click the reveal element to reveal the content. await reveal.click() // Return the anchor link element. return browser.elementByCss(`a[href="${href}"]`) } describe('prefetch={true}', () => { it('should prefetch the full page', async () => { let page: PlaywrightPage const browser = await next.browser('/', { async beforePageLoad(p) { page = p await page.clock.install() }, }) const act = createRouterAct(page) // Reveal the link to trigger prefetch and wait for it to complete const link = await act( async () => { return reveal(browser, '/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 () => { let page: PlaywrightPage const browser = await next.browser('/', { async beforePageLoad(p) { page = p await page.clock.install() }, }) const act = createRouterAct(page) // Toggle the link, assert on the prefetch content const link = await act( async () => { await reveal(browser, '/0') return browser.elementByCss('[href="/0"]') }, { includes: 'random-number' } ) // Navigate to the page, assert no requests are made const randomNumber = await act(async () => { await link.click() await browser.waitForElementByCss('#random-number') return browser.elementByCss('#random-number').text() }, 'no-requests') // Toggle the home link, assert on the homepage content const homeLink = await act( async () => { return reveal(browser, '/') }, { includes: 'home-page' } ) // 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 link = await reveal(browser, '/0') await link.click() await browser.waitForElementByCss('#random-number') return browser.elementByCss('#random-number').text() }, 'no-requests') expect(number).toBe(randomNumber) // Navigate back home await act(async () => { const link = await reveal(browser, '/') await link.click() await browser.waitForElementByCss('#home-page') }, 'no-requests') // Fast forward 5 minutes await page.clock.fastForward(5 * 60 * 1000) // Toggle the link to the other page again, assert on prefetch content const linkAfterExpiry = await act( async () => { return reveal(browser, '/0') }, { includes: 'random-number' } ) // 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 browser.elementByCss('#random-number').text() }, 'no-requests') expect(newNumber).not.toBe(randomNumber) }) }) })