From 4e8f147acb4e84c4e5a6f25933a77fdb57e6f127 Mon Sep 17 00:00:00 2001 From: m5r Date: Fri, 13 Dec 2024 11:11:58 +0100 Subject: [PATCH 01/11] expand prefetch hover behavior to react on touchstart, focus, and blur --- packages/react/src/Link.ts | 13 +++++++++---- packages/svelte/src/link.ts | 27 ++++++++++++++++++--------- packages/vue3/src/link.ts | 13 +++++++++---- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/packages/react/src/Link.ts b/packages/react/src/Link.ts index 86b21aec4..2ad63ebf4 100755 --- a/packages/react/src/Link.ts +++ b/packages/react/src/Link.ts @@ -165,7 +165,7 @@ const Link = forwardRef( }, prefetchModes) const regularEvents = { - onClick: (event) => { + onClick: (event: Parameters[0]) => { onClick(event) if (shouldIntercept(event)) { @@ -174,9 +174,6 @@ const Link = forwardRef( router.visit(href, visitParams) } }, - } - - const prefetchHoverEvents = { onMouseEnter: () => { hoverTimeout.current = window.setTimeout(() => { doPrefetch() @@ -185,6 +182,14 @@ const Link = forwardRef( onMouseLeave: () => { clearTimeout(hoverTimeout.current) }, + } + + const prefetchHoverEvents = { + onMouseEnter: regularEvents.onMouseEnter, + onMouseLeave: regularEvents.onMouseLeave, + onTouchStart: regularEvents.onMouseEnter, + onFocus: regularEvents.onMouseEnter, + onBlur: regularEvents.onMouseLeave, onClick: regularEvents.onClick, } diff --git a/packages/svelte/src/link.ts b/packages/svelte/src/link.ts index 76c3365bf..406266d79 100644 --- a/packages/svelte/src/link.ts +++ b/packages/svelte/src/link.ts @@ -54,22 +54,31 @@ function link( let baseParams: VisitOptions let visitParams: VisitOptions - const regularEvents: ActionEventHandlers = { + const regularEvents = { click: (event) => { if (shouldIntercept(event)) { event.preventDefault() router.visit(href, visitParams) } }, - } - - const prefetchHoverEvents: ActionEventHandlers = { - mouseenter: () => (hoverTimeout = setTimeout(() => prefetch(), 75)), - mouseleave: () => clearTimeout(hoverTimeout), + mouseenter: () => { + hoverTimeout = setTimeout(() => prefetch(), 75) + }, + mouseleave: () => { + clearTimeout(hoverTimeout) + }, + } satisfies ActionEventHandlers + + const prefetchHoverEvents = { + mouseenter: regularEvents.mouseenter, + mouseleave: regularEvents.mouseleave, + touchstart: regularEvents.mouseenter, + focus: regularEvents.mouseenter, + blur: regularEvents.mouseleave, click: regularEvents.click, - } + } satisfies ActionEventHandlers - const prefetchClickEvents: ActionEventHandlers = { + const prefetchClickEvents = { mousedown: (event) => { if (shouldIntercept(event)) { event.preventDefault() @@ -86,7 +95,7 @@ function link( event.preventDefault() } }, - } + } satisfies ActionEventHandlers function update({ cacheFor = 0, prefetch = false, ...params }: ActionParameters) { prefetchModes = (() => { diff --git a/packages/vue3/src/link.ts b/packages/vue3/src/link.ts index 085498fb0..2e66b94d9 100755 --- a/packages/vue3/src/link.ts +++ b/packages/vue3/src/link.ts @@ -227,15 +227,12 @@ const Link: InertiaLink = defineComponent({ } const regularEvents = { - onClick: (event) => { + onClick: (event: Parameters[0]) => { if (shouldIntercept(event)) { event.preventDefault() router.visit(href.value, visitParams) } }, - } - - const prefetchHoverEvents = { onMouseenter: () => { hoverTimeout.value = setTimeout(() => { prefetch() @@ -244,6 +241,14 @@ const Link: InertiaLink = defineComponent({ onMouseleave: () => { clearTimeout(hoverTimeout.value) }, + } + + const prefetchHoverEvents = { + onMouseenter: regularEvents.onMouseenter, + onMouseleave: regularEvents.onMouseleave, + onTouchstart: regularEvents.onMouseenter, + onFocus: regularEvents.onMouseenter, + onBlur: regularEvents.onMouseleave, onClick: regularEvents.onClick, } From 61b1cf68d48970ffd5b755caa35a96b40122bd7a Mon Sep 17 00:00:00 2001 From: m5r Date: Fri, 13 Dec 2024 11:30:40 +0100 Subject: [PATCH 02/11] update shouldIntercept parameter type --- packages/core/src/shouldIntercept.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/shouldIntercept.ts b/packages/core/src/shouldIntercept.ts index c46b9b5c2..6d5bf9f67 100644 --- a/packages/core/src/shouldIntercept.ts +++ b/packages/core/src/shouldIntercept.ts @@ -1,9 +1,9 @@ -export default function shouldIntercept(event: MouseEvent | KeyboardEvent): boolean { +export default function shouldIntercept(event: MouseEvent | KeyboardEvent | import('react').MouseEvent): boolean { const isLink = (event.currentTarget as HTMLElement).tagName.toLowerCase() === 'a' return !( (event.target && (event?.target as HTMLElement).isContentEditable) || event.defaultPrevented || - (isLink && event.which > 1) || + (isLink && 'which' in event && event.which > 1) || (isLink && event.altKey) || (isLink && event.ctrlKey) || (isLink && event.metaKey) || From bd0fd319cdff9ad19978c2f0034518e62d846141 Mon Sep 17 00:00:00 2001 From: m5r Date: Fri, 13 Dec 2024 11:34:26 +0100 Subject: [PATCH 03/11] remove unnecessary `await`s --- tests/prefetch.spec.ts | 54 +++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/tests/prefetch.spec.ts b/tests/prefetch.spec.ts index cff16d9bc..376f43d87 100644 --- a/tests/prefetch.spec.ts +++ b/tests/prefetch.spec.ts @@ -33,7 +33,7 @@ test('will not prefetch current page', async ({ page }) => { await page.getByRole('link', { name: 'On Hover (Default)' }).hover() await page.waitForTimeout(100) // This is the page we're already on, so it shouldn't make a request - await expect(requests.requests.length).toBe(0) + expect(requests.requests.length).toBe(0) }) test('can prefetch using link props', async ({ page }) => { @@ -51,11 +51,11 @@ test('can prefetch using link props', async ({ page }) => { await page.getByRole('link', { name: 'On Mount' }).click() await isPrefetchPage(page, 2) - await expect(requests.requests.length).toBe(0) + expect(requests.requests.length).toBe(0) await page.getByRole('link', { name: 'On Hover + Mount' }).click() await isPrefetchPage(page, 4) - await expect(requests.requests.length).toBe(0) + expect(requests.requests.length).toBe(0) await page.getByRole('link', { name: 'On Click' }).hover() await page.mouse.down() @@ -64,13 +64,13 @@ test('can prefetch using link props', async ({ page }) => { requests.listen(page) await page.mouse.up() await isPrefetchPage(page, 3) - await expect(requests.requests.length).toBe(0) + expect(requests.requests.length).toBe(0) requests.listen(page) await page.getByRole('link', { name: 'On Hover (Default)' }).hover() await page.getByRole('link', { name: 'On Click' }).hover() // If they just do a quick hover, it shouldn't make the request - await expect(requests.requests.length).toBe(0) + expect(requests.requests.length).toBe(0) await page.getByRole('link', { name: 'On Hover (Default)' }).hover() await page.waitForResponse('prefetch/1') @@ -79,7 +79,7 @@ test('can prefetch using link props', async ({ page }) => { requests.listen(page) await page.getByRole('link', { name: 'On Hover (Default)' }).click() await isPrefetchPage(page, 1) - await expect(requests.requests.length).toBe(0) + expect(requests.requests.length).toBe(0) // Wait for the cache to timeout on the combo link await page.waitForTimeout(1200) @@ -91,7 +91,7 @@ test('can prefetch using link props', async ({ page }) => { requests.listen(page) await page.getByRole('link', { name: 'On Hover + Mount' }).click() await isPrefetchPage(page, 4) - await expect(requests.requests.length).toBe(0) + expect(requests.requests.length).toBe(0) }) test('can cache links with single cache value', async ({ page }) => { @@ -101,27 +101,27 @@ test('can cache links with single cache value', async ({ page }) => { // Click back and forth a couple of times to ensure no requests go out await hoverAndClick(page, '1s Expired (Number)', 3) - await expect(requests.requests.length).toBe(1) + expect(requests.requests.length).toBe(1) const lastLoaded1 = await page.locator('#last-loaded').textContent() await hoverAndClick(page, '1s Expired', 2) await isPrefetchSwrPage(page, 2) - await expect(requests.requests.length).toBe(2) + expect(requests.requests.length).toBe(2) const lastLoaded2 = await page.locator('#last-loaded').textContent() requests.listen(page) await page.getByRole('link', { exact: true, name: '1s Expired (Number)' }).click() await isPrefetchSwrPage(page, 3) - await expect(requests.requests.length).toBe(0) + expect(requests.requests.length).toBe(0) const lastLoaded1New = await page.locator('#last-loaded').textContent() - await expect(lastLoaded1).toBe(lastLoaded1New) + expect(lastLoaded1).toBe(lastLoaded1New) await page.getByRole('link', { exact: true, name: '1s Expired' }).click() await isPrefetchSwrPage(page, 2) - await expect(requests.requests.length).toBe(0) + expect(requests.requests.length).toBe(0) const lastLoaded2New = await page.locator('#last-loaded').textContent() - await expect(lastLoaded2).toBe(lastLoaded2New) + expect(lastLoaded2).toBe(lastLoaded2New) // Wait for cache to expire await page.waitForTimeout(1200) @@ -129,14 +129,14 @@ test('can cache links with single cache value', async ({ page }) => { requests.listenForFinished(page) await hoverAndClick(page, '1s Expired (Number)', 3) - await expect(requests.finished.length).toBe(1) + expect(requests.finished.length).toBe(1) const lastLoaded1Fresh = await page.locator('#last-loaded').textContent() - await expect(lastLoaded1).not.toBe(lastLoaded1Fresh) + expect(lastLoaded1).not.toBe(lastLoaded1Fresh) await hoverAndClick(page, '1s Expired', 2) - await expect(requests.finished.length).toBe(2) + expect(requests.finished.length).toBe(2) const lastLoaded2Fresh = await page.locator('#last-loaded').textContent() - await expect(lastLoaded2).not.toBe(lastLoaded2Fresh) + expect(lastLoaded2).not.toBe(lastLoaded2Fresh) }) test.skip('can do SWR when the link cacheFor prop has two values', async ({ page }) => { @@ -145,11 +145,11 @@ test.skip('can do SWR when the link cacheFor prop has two values', async ({ page requests.listen(page) await hoverAndClick(page, '1s Stale, 2s Expired (Number)', 5) - await expect(requests.requests.length).toBe(1) + expect(requests.requests.length).toBe(1) const lastLoaded1 = await page.locator('#last-loaded').textContent() await hoverAndClick(page, '1s Stale, 2s Expired', 4) - await expect(requests.requests.length).toBe(2) + expect(requests.requests.length).toBe(2) const lastLoaded2 = await page.locator('#last-loaded').textContent() requests.listen(page) @@ -157,15 +157,15 @@ test.skip('can do SWR when the link cacheFor prop has two values', async ({ page // Click back and forth a couple of times to ensure no requests go out await page.getByRole('link', { exact: true, name: '1s Stale, 2s Expired (Number)' }).click() await isPrefetchSwrPage(page, 5) - await expect(requests.requests.length).toBe(0) + expect(requests.requests.length).toBe(0) const lastLoaded1New = await page.locator('#last-loaded').textContent() - await expect(lastLoaded1).toBe(lastLoaded1New) + expect(lastLoaded1).toBe(lastLoaded1New) await page.getByRole('link', { exact: true, name: '1s Stale, 2s Expired' }).click() await isPrefetchSwrPage(page, 4) - await expect(requests.requests.length).toBe(0) + expect(requests.requests.length).toBe(0) const lastLoaded2New = await page.locator('#last-loaded').textContent() - await expect(lastLoaded2).toBe(lastLoaded2New) + expect(lastLoaded2).toBe(lastLoaded2New) // Wait for stale time to pass await page.waitForTimeout(1200) @@ -178,23 +178,23 @@ test.skip('can do SWR when the link cacheFor prop has two values', async ({ page await page.getByRole('link', { exact: true, name: '1s Stale, 2s Expired (Number)' }).click() await isPrefetchSwrPage(page, 5) const lastLoaded1Stale = await page.locator('#last-loaded').textContent() - await expect(lastLoaded1).toBe(lastLoaded1Stale) + expect(lastLoaded1).toBe(lastLoaded1Stale) await promiseFor5 // await expect(requests.finished.length).toBe(1) await page.waitForTimeout(600) const lastLoaded1Fresh = await page.locator('#last-loaded').textContent() - await expect(lastLoaded1).not.toBe(lastLoaded1Fresh) + expect(lastLoaded1).not.toBe(lastLoaded1Fresh) const promiseFor4 = page.waitForResponse('prefetch/swr/4') await page.getByRole('link', { exact: true, name: '1s Stale, 2s Expired' }).click() await isPrefetchSwrPage(page, 4) const lastLoaded2Stale = await page.locator('#last-loaded').textContent() - await expect(lastLoaded2).toBe(lastLoaded2Stale) + expect(lastLoaded2).toBe(lastLoaded2Stale) await promiseFor4 // await expect(requests.finished.length).toBe(2) await page.waitForTimeout(100) const lastLoaded2Fresh = await page.locator('#last-loaded').textContent() - await expect(lastLoaded2).not.toBe(lastLoaded2Fresh) + expect(lastLoaded2).not.toBe(lastLoaded2Fresh) }) From fb758200a46a526fb40c5d73d5856223c507dadf Mon Sep 17 00:00:00 2001 From: m5r Date: Fri, 13 Dec 2024 11:36:04 +0100 Subject: [PATCH 04/11] wip --- tests/prefetch.spec.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/prefetch.spec.ts b/tests/prefetch.spec.ts index 376f43d87..84064a2d6 100644 --- a/tests/prefetch.spec.ts +++ b/tests/prefetch.spec.ts @@ -18,6 +18,11 @@ const hoverAndClick = async (page: Page, buttonText: string, id: number) => { await isPrefetchSwrPage(page, id) } +test.fixme('prefetch touchstart/focus/blur', async ({ page }) => { + // TODO next + expect(true).toBe(false); +}); + test('will not prefetch current page', async ({ page }) => { // These two prefetch requests should be made on mount const prefetch2 = page.waitForResponse('prefetch/2') From 7a892480e705673bac98b7c54b3129c61e838e21 Mon Sep 17 00:00:00 2001 From: m5r Date: Fri, 13 Dec 2024 19:05:54 +0100 Subject: [PATCH 05/11] test prefetch focus/blur/touchstart behavior --- tests/prefetch.spec.ts | 52 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/tests/prefetch.spec.ts b/tests/prefetch.spec.ts index 84064a2d6..b390e8c1a 100644 --- a/tests/prefetch.spec.ts +++ b/tests/prefetch.spec.ts @@ -18,11 +18,6 @@ const hoverAndClick = async (page: Page, buttonText: string, id: number) => { await isPrefetchSwrPage(page, id) } -test.fixme('prefetch touchstart/focus/blur', async ({ page }) => { - // TODO next - expect(true).toBe(false); -}); - test('will not prefetch current page', async ({ page }) => { // These two prefetch requests should be made on mount const prefetch2 = page.waitForResponse('prefetch/2') @@ -41,7 +36,7 @@ test('will not prefetch current page', async ({ page }) => { expect(requests.requests.length).toBe(0) }) -test('can prefetch using link props', async ({ page }) => { +test('can prefetch using link props', async ({ page, browser, context }) => { // These two prefetch requests should be made on mount const prefetch2 = page.waitForResponse('prefetch/2') const prefetch4 = page.waitForResponse('prefetch/4') @@ -97,6 +92,51 @@ test('can prefetch using link props', async ({ page }) => { await page.getByRole('link', { name: 'On Hover + Mount' }).click() await isPrefetchPage(page, 4) expect(requests.requests.length).toBe(0) + + // Create a new page without the cache populated by previous tests + const page2 = await context.newPage() + await page2.goto('prefetch/2') + requests.listen(page2) + // If they just do a quick focus, it shouldn't make the request + await page2.getByRole('link', { exact: true, name: 'On Hover (Default)' }).focus() + await page2.getByRole('link', { exact: true, name: 'On Hover (Default)' }).blur() + expect(requests.requests.length).toBe(0) + + await page2.getByRole('link', { exact: true, name: 'On Hover (Default)' }).focus() + await page2.waitForTimeout(80) + expect(requests.requests.length).toBe(1) + await isPrefetchPage(page2, 2) + await page2.keyboard.down('Enter') + await isPrefetchPage(page2, 1) + expect(requests.requests.length).toBe(1) + + await page2.close() + + // Create a new context to simulate touchscreen + const context2 = await browser.newContext({ hasTouch: true }) + const page3 = await context2.newPage() + + // These two prefetch requests should be made on mount + const page3Prefetch2 = page3.waitForResponse('prefetch/2') + const page3Prefetch4 = page3.waitForResponse('prefetch/4') + + await page3.goto('prefetch/2') + + // These two prefetch requests should be made on mount + await page3Prefetch2 + await page3Prefetch4 + + requests.listen(page3) + + const link = page3.getByRole('link', { exact: true, name: 'On Hover (Default)' }) + const box = await link.boundingBox() + expect(box).not.toBeNull() + page3.touchscreen.tap(box!.x, box!.y) + await page3.waitForTimeout(75) + expect(requests.requests.length).toBe(1) + await isPrefetchPage(page3, 1) + + await context.close() }) test('can cache links with single cache value', async ({ page }) => { From 93daf3dd603caeb45bc48e3d1f3dcf038adee4b5 Mon Sep 17 00:00:00 2001 From: m5r Date: Fri, 13 Dec 2024 19:15:19 +0100 Subject: [PATCH 06/11] fix test prefetch --- tests/prefetch.spec.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/prefetch.spec.ts b/tests/prefetch.spec.ts index b390e8c1a..ff9e92f5c 100644 --- a/tests/prefetch.spec.ts +++ b/tests/prefetch.spec.ts @@ -36,7 +36,7 @@ test('will not prefetch current page', async ({ page }) => { expect(requests.requests.length).toBe(0) }) -test('can prefetch using link props', async ({ page, browser, context }) => { +test('can prefetch using link props', async ({ page, browser }) => { // These two prefetch requests should be made on mount const prefetch2 = page.waitForResponse('prefetch/2') const prefetch4 = page.waitForResponse('prefetch/4') @@ -93,8 +93,9 @@ test('can prefetch using link props', async ({ page, browser, context }) => { await isPrefetchPage(page, 4) expect(requests.requests.length).toBe(0) - // Create a new page without the cache populated by previous tests - const page2 = await context.newPage() + // Create a new context to test the focus/blur behavior without the cache populated by previous tests + const context2 = await browser.newContext() + const page2 = await context2.newPage() await page2.goto('prefetch/2') requests.listen(page2) // If they just do a quick focus, it shouldn't make the request @@ -109,12 +110,11 @@ test('can prefetch using link props', async ({ page, browser, context }) => { await page2.keyboard.down('Enter') await isPrefetchPage(page2, 1) expect(requests.requests.length).toBe(1) - - await page2.close() + await context2.close() // Create a new context to simulate touchscreen - const context2 = await browser.newContext({ hasTouch: true }) - const page3 = await context2.newPage() + const context3 = await browser.newContext({ hasTouch: true }) + const page3 = await context3.newPage() // These two prefetch requests should be made on mount const page3Prefetch2 = page3.waitForResponse('prefetch/2') @@ -135,8 +135,7 @@ test('can prefetch using link props', async ({ page, browser, context }) => { await page3.waitForTimeout(75) expect(requests.requests.length).toBe(1) await isPrefetchPage(page3, 1) - - await context.close() + await context3.close() }) test('can cache links with single cache value', async ({ page }) => { From 5b8a12d5adc9ae28e77f67664b511a8edc630d10 Mon Sep 17 00:00:00 2001 From: m5r Date: Fri, 13 Dec 2024 20:12:25 +0100 Subject: [PATCH 07/11] does increasing the timeout help CI go green? --- tests/prefetch.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/prefetch.spec.ts b/tests/prefetch.spec.ts index ff9e92f5c..ff980b7b0 100644 --- a/tests/prefetch.spec.ts +++ b/tests/prefetch.spec.ts @@ -104,7 +104,7 @@ test('can prefetch using link props', async ({ page, browser }) => { expect(requests.requests.length).toBe(0) await page2.getByRole('link', { exact: true, name: 'On Hover (Default)' }).focus() - await page2.waitForTimeout(80) + await page2.waitForTimeout(100) expect(requests.requests.length).toBe(1) await isPrefetchPage(page2, 2) await page2.keyboard.down('Enter') From ae8043622937f8d75f371b26367da9f135465afa Mon Sep 17 00:00:00 2001 From: m5r Date: Fri, 13 Dec 2024 20:35:59 +0100 Subject: [PATCH 08/11] making it its own test case should do it for sure --- tests/prefetch.spec.ts | 50 ++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/tests/prefetch.spec.ts b/tests/prefetch.spec.ts index ff980b7b0..834cf55a4 100644 --- a/tests/prefetch.spec.ts +++ b/tests/prefetch.spec.ts @@ -92,50 +92,48 @@ test('can prefetch using link props', async ({ page, browser }) => { await page.getByRole('link', { name: 'On Hover + Mount' }).click() await isPrefetchPage(page, 4) expect(requests.requests.length).toBe(0) +}) - // Create a new context to test the focus/blur behavior without the cache populated by previous tests - const context2 = await browser.newContext() - const page2 = await context2.newPage() - await page2.goto('prefetch/2') - requests.listen(page2) +test('can prefetch link on focus', async ({ page, browser }) => { + await page.goto('prefetch/2') + requests.listen(page) // If they just do a quick focus, it shouldn't make the request - await page2.getByRole('link', { exact: true, name: 'On Hover (Default)' }).focus() - await page2.getByRole('link', { exact: true, name: 'On Hover (Default)' }).blur() + await page.getByRole('link', { exact: true, name: 'On Hover (Default)' }).focus() + await page.getByRole('link', { exact: true, name: 'On Hover (Default)' }).blur() expect(requests.requests.length).toBe(0) - await page2.getByRole('link', { exact: true, name: 'On Hover (Default)' }).focus() - await page2.waitForTimeout(100) + await page.getByRole('link', { exact: true, name: 'On Hover (Default)' }).focus() + await page.waitForTimeout(80) expect(requests.requests.length).toBe(1) - await isPrefetchPage(page2, 2) - await page2.keyboard.down('Enter') - await isPrefetchPage(page2, 1) + await isPrefetchPage(page, 2) + await page.keyboard.down('Enter') + await isPrefetchPage(page, 1) expect(requests.requests.length).toBe(1) - await context2.close() // Create a new context to simulate touchscreen - const context3 = await browser.newContext({ hasTouch: true }) - const page3 = await context3.newPage() + const context2 = await browser.newContext({ hasTouch: true }) + const page2 = await context2.newPage() // These two prefetch requests should be made on mount - const page3Prefetch2 = page3.waitForResponse('prefetch/2') - const page3Prefetch4 = page3.waitForResponse('prefetch/4') + const prefetch2 = page2.waitForResponse('prefetch/2') + const prefetch4 = page2.waitForResponse('prefetch/4') - await page3.goto('prefetch/2') + await page2.goto('prefetch/2') // These two prefetch requests should be made on mount - await page3Prefetch2 - await page3Prefetch4 + await prefetch2 + await prefetch4 - requests.listen(page3) + requests.listen(page2) - const link = page3.getByRole('link', { exact: true, name: 'On Hover (Default)' }) + const link = page2.getByRole('link', { exact: true, name: 'On Hover (Default)' }) const box = await link.boundingBox() expect(box).not.toBeNull() - page3.touchscreen.tap(box!.x, box!.y) - await page3.waitForTimeout(75) + page2.touchscreen.tap(box!.x, box!.y) + await page2.waitForTimeout(75) expect(requests.requests.length).toBe(1) - await isPrefetchPage(page3, 1) - await context3.close() + await isPrefetchPage(page2, 1) + await context2.close() }) test('can cache links with single cache value', async ({ page }) => { From 5700d4896cce079252980d31dfd68956ca276624 Mon Sep 17 00:00:00 2001 From: m5r Date: Fri, 13 Dec 2024 20:41:28 +0100 Subject: [PATCH 09/11] poor man's CI re-run --- tests/prefetch.spec.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/prefetch.spec.ts b/tests/prefetch.spec.ts index 834cf55a4..0f11582de 100644 --- a/tests/prefetch.spec.ts +++ b/tests/prefetch.spec.ts @@ -98,11 +98,12 @@ test('can prefetch link on focus', async ({ page, browser }) => { await page.goto('prefetch/2') requests.listen(page) // If they just do a quick focus, it shouldn't make the request - await page.getByRole('link', { exact: true, name: 'On Hover (Default)' }).focus() - await page.getByRole('link', { exact: true, name: 'On Hover (Default)' }).blur() + const link = page.getByRole('link', { exact: true, name: 'On Hover (Default)' }) + await link.focus() + await link.blur() expect(requests.requests.length).toBe(0) - await page.getByRole('link', { exact: true, name: 'On Hover (Default)' }).focus() + await link.focus() await page.waitForTimeout(80) expect(requests.requests.length).toBe(1) await isPrefetchPage(page, 2) @@ -126,8 +127,7 @@ test('can prefetch link on focus', async ({ page, browser }) => { requests.listen(page2) - const link = page2.getByRole('link', { exact: true, name: 'On Hover (Default)' }) - const box = await link.boundingBox() + const box = await page2.getByRole('link', { exact: true, name: 'On Hover (Default)' }).boundingBox() expect(box).not.toBeNull() page2.touchscreen.tap(box!.x, box!.y) await page2.waitForTimeout(75) From b88cac3fc7b214a2216dbc496406978c35fc9021 Mon Sep 17 00:00:00 2001 From: m5r Date: Fri, 13 Dec 2024 21:00:42 +0100 Subject: [PATCH 10/11] less flaky with react --- tests/prefetch.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/prefetch.spec.ts b/tests/prefetch.spec.ts index 0f11582de..cbe9fd4f6 100644 --- a/tests/prefetch.spec.ts +++ b/tests/prefetch.spec.ts @@ -96,6 +96,7 @@ test('can prefetch using link props', async ({ page, browser }) => { test('can prefetch link on focus', async ({ page, browser }) => { await page.goto('prefetch/2') + await isPrefetchPage(page, 2) requests.listen(page) // If they just do a quick focus, it shouldn't make the request const link = page.getByRole('link', { exact: true, name: 'On Hover (Default)' }) From c9e0aa220889dfaa35870fb23891617761b10206 Mon Sep 17 00:00:00 2001 From: m5r Date: Fri, 13 Dec 2024 21:09:53 +0100 Subject: [PATCH 11/11] remove unused parameter --- tests/prefetch.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/prefetch.spec.ts b/tests/prefetch.spec.ts index cbe9fd4f6..abfd042f2 100644 --- a/tests/prefetch.spec.ts +++ b/tests/prefetch.spec.ts @@ -36,7 +36,7 @@ test('will not prefetch current page', async ({ page }) => { expect(requests.requests.length).toBe(0) }) -test('can prefetch using link props', async ({ page, browser }) => { +test('can prefetch using link props', async ({ page }) => { // These two prefetch requests should be made on mount const prefetch2 = page.waitForResponse('prefetch/2') const prefetch4 = page.waitForResponse('prefetch/4')