From 8c58d6ab34445a736ad45913d09b11e5120e6329 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Wed, 13 Aug 2025 11:29:28 -0700 Subject: [PATCH 1/2] fix: hostname match is case insensitive --- .../src/utils/isomorphic/urlMatch.ts | 23 +++++++++++++++---- tests/page/interception.spec.ts | 4 ++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/playwright-core/src/utils/isomorphic/urlMatch.ts b/packages/playwright-core/src/utils/isomorphic/urlMatch.ts index 3741303c83d4e..27003c25e9b16 100644 --- a/packages/playwright-core/src/utils/isomorphic/urlMatch.ts +++ b/packages/playwright-core/src/utils/isomorphic/urlMatch.ts @@ -148,9 +148,12 @@ function resolveGlobBase(baseURL: string | undefined, match: string): string { const newSuffix = mapToken(token.substring(questionIndex), `?$_${index}_$`); return newPrefix + newSuffix; }).join('/'); - let resolved = constructURLBasedOnBaseURL(baseURL, relativePath); - for (const [token, original] of tokenMap) - resolved = resolved.replace(token, original); + const result = resolveBaseURL(baseURL, relativePath); + let resolved = result.resolved; + for (const [token, original] of tokenMap) { + const normalize = result.caseInsensitivePart?.includes(token); + resolved = resolved.replace(token, normalize ? original.toLowerCase() : original); + } match = resolved; } return match; @@ -166,8 +169,20 @@ function parseURL(url: string): URL | null { export function constructURLBasedOnBaseURL(baseURL: string | undefined, givenURL: string): string { try { - return (new URL(givenURL, baseURL)).toString(); + return resolveBaseURL(baseURL, givenURL).resolved; } catch (e) { return givenURL; } } + +function resolveBaseURL(baseURL: string | undefined, givenURL: string) { + try { + const url = new URL(givenURL, baseURL); + const resolved = url.toString(); + // Schema and domain are case-insensitive. + const caseInsensitivePrefix = url.origin; + return { resolved, caseInsensitivePart: caseInsensitivePrefix }; + } catch (e) { + return { resolved: givenURL }; + } +} diff --git a/tests/page/interception.spec.ts b/tests/page/interception.spec.ts index 5b677aeb35d0b..6123d302e7f9a 100644 --- a/tests/page/interception.spec.ts +++ b/tests/page/interception.spec.ts @@ -116,6 +116,10 @@ it('should work with glob', async () => { expect(urlMatches('http://playwright.dev', 'http://playwright.dev/?x=y', '?x=y')).toBeTruthy(); expect(urlMatches('http://playwright.dev/foo/', 'http://playwright.dev/foo/bar?x=y', './bar?x=y')).toBeTruthy(); + // Case insensitive matching + expect(urlMatches(undefined, 'https://playwright.dev/fooBAR', 'HtTpS://pLaYwRiGhT.dEv/fooBAR')).toBeTruthy(); + expect(urlMatches('http://ignored', 'https://playwright.dev/fooBAR', 'HtTpS://pLaYwRiGhT.dEv/fooBAR')).toBeTruthy(); + // This is not supported, we treat ? as a query separator. expect(globToRegex('http://localhost:8080/?imple/path.js').test('http://localhost:8080/Simple/path.js')).toBeFalsy(); expect(urlMatches(undefined, 'http://playwright.dev/', 'http://playwright.?ev')).toBeFalsy(); From bfbf805df5295af92b2330d135f6c711bc3edfa3 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Wed, 13 Aug 2025 12:20:24 -0700 Subject: [PATCH 2/2] more tests --- tests/page/interception.spec.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/page/interception.spec.ts b/tests/page/interception.spec.ts index 6123d302e7f9a..08c502e9e1a85 100644 --- a/tests/page/interception.spec.ts +++ b/tests/page/interception.spec.ts @@ -119,6 +119,9 @@ it('should work with glob', async () => { // Case insensitive matching expect(urlMatches(undefined, 'https://playwright.dev/fooBAR', 'HtTpS://pLaYwRiGhT.dEv/fooBAR')).toBeTruthy(); expect(urlMatches('http://ignored', 'https://playwright.dev/fooBAR', 'HtTpS://pLaYwRiGhT.dEv/fooBAR')).toBeTruthy(); + // Path and search query are case-sensitive + expect(urlMatches(undefined, 'https://playwright.dev/foobar', 'https://playwright.dev/fooBAR')).toBeFalsy(); + expect(urlMatches(undefined, 'https://playwright.dev/foobar?a=b', 'https://playwright.dev/foobar?A=B')).toBeFalsy(); // This is not supported, we treat ? as a query separator. expect(globToRegex('http://localhost:8080/?imple/path.js').test('http://localhost:8080/Simple/path.js')).toBeFalsy();