From 92b27e9c9253cea3d00f1f81223de19ff75c2c74 Mon Sep 17 00:00:00 2001 From: Oskar Baumann <62597223+panwauu@users.noreply.github.com> Date: Fri, 7 Oct 2022 16:13:51 +0200 Subject: [PATCH] [@astrojs/prefetch]: Prevent prefetching current page (#5009) * Check that removal of url.hash breaks no tests * test if status-quo is as expected * Adapt tests to fail * Adapt the shouldPreload function to skip same path * Add changeset --- .changeset/cold-colts-laugh.md | 5 +++ packages/integrations/prefetch/src/client.ts | 2 +- .../prefetch/test/basic-prefetch.test.js | 38 ++++++++++--------- .../prefetch/test/custom-selectors.test.js | 32 ++++++++++------ .../basic-prefetch/src/pages/index.astro | 3 ++ 5 files changed, 49 insertions(+), 31 deletions(-) create mode 100644 .changeset/cold-colts-laugh.md diff --git a/.changeset/cold-colts-laugh.md b/.changeset/cold-colts-laugh.md new file mode 100644 index 000000000..8d2e29e88 --- /dev/null +++ b/.changeset/cold-colts-laugh.md @@ -0,0 +1,5 @@ +--- +'@astrojs/prefetch': patch +--- + +Prevents prefetching the current page diff --git a/packages/integrations/prefetch/src/client.ts b/packages/integrations/prefetch/src/client.ts index 50df858cb..0b37946ee 100644 --- a/packages/integrations/prefetch/src/client.ts +++ b/packages/integrations/prefetch/src/client.ts @@ -11,7 +11,7 @@ function shouldPreload({ href }: { href: string }) { const url = new URL(href); return ( window.location.origin === url.origin && - window.location.pathname !== url.hash && + window.location.pathname !== url.pathname && !preloaded.has(href) ); } catch {} diff --git a/packages/integrations/prefetch/test/basic-prefetch.test.js b/packages/integrations/prefetch/test/basic-prefetch.test.js index 0dbb571be..576bd19bd 100644 --- a/packages/integrations/prefetch/test/basic-prefetch.test.js +++ b/packages/integrations/prefetch/test/basic-prefetch.test.js @@ -17,23 +17,24 @@ test.describe('Basic prefetch', () => { test.describe('prefetches rel="prefetch" links', () => { test('skips /admin', async ({ page, astro }) => { - const requests = new Set(); + const requests = []; - page.on('request', async (request) => requests.add(request.url())); + page.on('request', async (request) => requests.push(request.url())); await page.goto(astro.resolveUrl('/')); await page.waitForLoadState('networkidle'); - await expect( - requests.has(astro.resolveUrl('/about')), - '/about was prefetched' - ).toBeTruthy(); - await expect( - requests.has(astro.resolveUrl('/contact')), + expect(requests.includes(astro.resolveUrl('/about')), '/about was prefetched').toBeTruthy(); + expect( + requests.includes(astro.resolveUrl('/contact')), '/contact was prefetched' ).toBeTruthy(); - await expect(requests.has(astro.resolveUrl('/admin')), '/admin was skipped').toBeFalsy(); + expect(requests.includes(astro.resolveUrl('/admin')), '/admin was skipped').toBeFalsy(); + expect( + requests.filter((r) => r === astro.resolveUrl('/')).length === 1, + '/ was skipped by prefetch and only queried once' + ).toBeTruthy(); }); }); }); @@ -53,23 +54,24 @@ test.describe('Basic prefetch', () => { test.describe('prefetches rel="prefetch" links', () => { test('skips /admin', async ({ page, astro }) => { - const requests = new Set(); + const requests = []; - page.on('request', async (request) => requests.add(request.url())); + page.on('request', async (request) => requests.push(request.url())); await page.goto(astro.resolveUrl('/')); await page.waitForLoadState('networkidle'); - await expect( - requests.has(astro.resolveUrl('/about')), - '/about was prefetched' - ).toBeTruthy(); - await expect( - requests.has(astro.resolveUrl('/contact')), + expect(requests.includes(astro.resolveUrl('/about')), '/about was prefetched').toBeTruthy(); + expect( + requests.includes(astro.resolveUrl('/contact')), '/contact was prefetched' ).toBeTruthy(); - await expect(requests.has(astro.resolveUrl('/admin')), '/admin was skipped').toBeFalsy(); + expect(requests.includes(astro.resolveUrl('/admin')), '/admin was skipped').toBeFalsy(); + expect( + requests.filter((r) => r === astro.resolveUrl('/')).length === 1, + '/ was skipped by prefetch and only queried once' + ).toBeTruthy(); }); }); }); diff --git a/packages/integrations/prefetch/test/custom-selectors.test.js b/packages/integrations/prefetch/test/custom-selectors.test.js index 64ac5fc63..d57ac3b90 100644 --- a/packages/integrations/prefetch/test/custom-selectors.test.js +++ b/packages/integrations/prefetch/test/custom-selectors.test.js @@ -25,20 +25,24 @@ test.describe('Custom prefetch selectors', () => { test.describe('prefetches links by custom selector', () => { test('only prefetches /contact', async ({ page, astro }) => { - const requests = new Set(); + const requests = []; - page.on('request', async (request) => requests.add(request.url())); + page.on('request', async (request) => requests.push(request.url())); await page.goto(astro.resolveUrl('/')); await page.waitForLoadState('networkidle'); - await expect(requests.has(astro.resolveUrl('/about')), '/about was skipped').toBeFalsy(); - await expect( - requests.has(astro.resolveUrl('/contact')), + expect(requests.includes(astro.resolveUrl('/about')), '/about was skipped').toBeFalsy(); + expect( + requests.includes(astro.resolveUrl('/contact')), '/contact was prefetched' ).toBeTruthy(); - await expect(requests.has(astro.resolveUrl('/admin')), '/admin was skipped').toBeFalsy(); + expect(requests.includes(astro.resolveUrl('/admin')), '/admin was skipped').toBeFalsy(); + expect( + requests.filter((r) => r === astro.resolveUrl('/')).length === 1, + '/ was skipped by prefetch and only queried once' + ).toBeTruthy(); }); }); }); @@ -58,20 +62,24 @@ test.describe('Custom prefetch selectors', () => { test.describe('prefetches links by custom selector', () => { test('only prefetches /contact', async ({ page, astro }) => { - const requests = new Set(); + const requests = []; - page.on('request', async (request) => requests.add(request.url())); + page.on('request', async (request) => requests.push(request.url())); await page.goto(astro.resolveUrl('/')); await page.waitForLoadState('networkidle'); - await expect(requests.has(astro.resolveUrl('/about')), '/about was skipped').toBeFalsy(); - await expect( - requests.has(astro.resolveUrl('/contact')), + expect(requests.includes(astro.resolveUrl('/about')), '/about was skipped').toBeFalsy(); + expect( + requests.includes(astro.resolveUrl('/contact')), '/contact was prefetched' ).toBeTruthy(); - await expect(requests.has(astro.resolveUrl('/admin')), '/admin was skipped').toBeFalsy(); + expect(requests.includes(astro.resolveUrl('/admin')), '/admin was skipped').toBeFalsy(); + expect( + requests.filter((r) => r === astro.resolveUrl('/')).length === 1, + '/ was skipped by prefetch and only queried once' + ).toBeTruthy(); }); }); }); diff --git a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/index.astro b/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/index.astro index d2c674ebc..58a864552 100644 --- a/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/index.astro +++ b/packages/integrations/prefetch/test/fixtures/basic-prefetch/src/pages/index.astro @@ -10,6 +10,9 @@