From b0067948fe87e8ab0e59a855c736a1424a7fac21 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Thu, 24 Sep 2026 14:12:48 -0700 Subject: [PATCH] fix(route): do not drop requests matching case-insensitive URLPattern Fixes: https://github.com/microsoft/playwright/issues/42918 --- packages/isomorphic/urlMatch.ts | 4 +++- tests/library/browsercontext-route.spec.ts | 20 ++++++++++++++++++++ tests/page/page-route.spec.ts | 20 ++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/isomorphic/urlMatch.ts b/packages/isomorphic/urlMatch.ts index a054f1476f65c..02bbcbe2d8420 100644 --- a/packages/isomorphic/urlMatch.ts +++ b/packages/isomorphic/urlMatch.ts @@ -147,6 +147,8 @@ function deserializeURLPattern(v: ReturnType): URLPa if (typeof globalThis.URLPattern !== 'function') return () => true; + // URLPattern does not expose ignoreCase, so match case-insensitively on the server + // to avoid false negatives. The client filters again with the original pattern. // @ts-ignore URLPattern is not in @types/node yet // eslint-disable-next-line no-restricted-globals return new globalThis.URLPattern({ @@ -158,7 +160,7 @@ function deserializeURLPattern(v: ReturnType): URLPa protocol: v.protocol, search: v.search, username: v.username, - }); + }, { ignoreCase: true }); } export function deserializeURLMatch(match: { glob?: string, regexSource?: string, regexFlags?: string, urlPattern?: ReturnType }): URLMatch { diff --git a/tests/library/browsercontext-route.spec.ts b/tests/library/browsercontext-route.spec.ts index 565d82f63b82a..24ced54d014a9 100644 --- a/tests/library/browsercontext-route.spec.ts +++ b/tests/library/browsercontext-route.spec.ts @@ -431,3 +431,23 @@ it('should fulfill popup main request using alias', async ({ page, server, isEle ]); await expect(popup.locator('body')).toHaveText('hello'); }); + +it('should respect URLPattern ignoreCase', async ({ context, page, server }) => { + it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/42918' }); + it.skip(globalThis.URLPattern === undefined, 'URLPattern is not supported in this environment'); + + const intercepted: string[] = []; + // @ts-ignore URLPattern is not in @types/node yet + await context.route(new URLPattern(server.PREFIX + '/EMPTY.html', { ignoreCase: true }), route => { + intercepted.push('ignoreCase'); + return route.fulfill({ body: 'mock' }); + }); + // @ts-ignore URLPattern is not in @types/node yet + await context.route(new URLPattern(server.PREFIX + '/EMPTY.html'), route => { + intercepted.push('caseSensitive'); + return route.fulfill({ body: 'mock' }); + }); + const response = await page.goto(server.EMPTY_PAGE); + expect(await response!.text()).toBe('mock'); + expect(intercepted).toEqual(['ignoreCase']); +}); diff --git a/tests/page/page-route.spec.ts b/tests/page/page-route.spec.ts index da4b533d32f1f..87fa568010106 100644 --- a/tests/page/page-route.spec.ts +++ b/tests/page/page-route.spec.ts @@ -1138,3 +1138,23 @@ it('should be able to intercept every navigation to a page controlled by service await page.goto(URL); expect(interceptions).toBe(2); }); + +it('should respect URLPattern ignoreCase', async ({ page, server }) => { + it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/42918' }); + it.skip(globalThis.URLPattern === undefined, 'URLPattern is not supported in this environment'); + + const intercepted: string[] = []; + // @ts-ignore URLPattern is not in @types/node yet + await page.route(new URLPattern(server.PREFIX + '/EMPTY.html', { ignoreCase: true }), route => { + intercepted.push('ignoreCase'); + return route.fulfill({ body: 'mock' }); + }); + // @ts-ignore URLPattern is not in @types/node yet + await page.route(new URLPattern(server.PREFIX + '/EMPTY.html'), route => { + intercepted.push('caseSensitive'); + return route.fulfill({ body: 'mock' }); + }); + const response = await page.goto(server.EMPTY_PAGE); + expect(await response!.text()).toBe('mock'); + expect(intercepted).toEqual(['ignoreCase']); +});