-
Notifications
You must be signed in to change notification settings - Fork 5.4k
[Bug]: Incorrect behavior of '?' in the url glob pattern #34915
Description
Version
1.50.1
Steps to reproduce
Per documentation, ? in the url glob pattern matches any character except /. But the following code does not work as expected:
await page.goto('https://playwright.dev');
// notice '?' in the url pattern
await page.route('https://playwright.?ev', async route => {
console.log('captured!');
await route.continue();
});
await page.evaluate(() => fetch('https://playwright.dev'));Expected behavior
Request to https://playwright.dev will be captured.
Actual behavior
Request to https://playwright.dev is not captured.
Additional context
Outside the hostname, ? also behaves in the confusing way. For example:
await page.goto('https://playwright.dev');
// notice '?' in the url pattern
await page.route('https://jsonplaceholder.typicode.com/comments?postId=1', async route => {
console.log('captured!');
await route.continue();
});
await page.evaluate(() => fetch('https://jsonplaceholder.typicode.com/comments?postId=1'));Here, the request to https://jsonplaceholder.typicode.com/comments?postId=1 is matched. But it occurs because ? serves as any symbol, not as a query params separator.
So any of the following requests are matched:
https://jsonplaceholder.typicode.com/comments-postId=1
https://jsonplaceholder.typicode.com/comments_postId=1
https://jsonplaceholder.typicode.com/commentsXpostId=1
I've recently submitted a documentation pr, that highlights that we should escape ? to distinguish query separator from pattern symbol. But with the above example it does not help:
await page.goto('https://playwright.dev');
// notice '?' in the url pattern
await page.route('https://jsonplaceholder.typicode.com/comments\\?postId=1', async route => {
console.log('captured!');
await route.continue();
});
await page.evaluate(() => fetch('https://jsonplaceholder.typicode.com/comments?postId=1'));Request to https://jsonplaceholder.typicode.com/comments?postId=1 is not captured.
The reason: url pattern is passed through new URL() constructor, that is not aware of special meaning for ?. And given url is transformed as follows:
$ node -p 'new URL("https://jsonplaceholder.typicode.com/comments\\?postId=1").toString()'
https://jsonplaceholder.typicode.com/comments/?postId=1
Although it's a valid url, an extra / after comments breaks the comparison, because in the actual request url there is no such normalization:
final pattern: https://jsonplaceholder.typicode.com/comments/?postId=1
real req url: https://jsonplaceholder.typicode.com/comments?postId=1
The same thing happens with the original example for this bug:
$ node -p 'new URL("https://playwright.?ev").toString()'
https://playwright./?ev
Environment
System:
OS: macOS 14.7.2
CPU: (10) arm64 Apple M1 Pro
Memory: 52.31 MB / 16.00 GB
Binaries:
Node: 20.11.1 - ~/.nvm/versions/node/v20.11.1/bin/node
Yarn: 1.22.22 - ~/.nvm/versions/node/v20.11.1/bin/yarn
npm: 10.2.4 - ~/.nvm/versions/node/v20.11.1/bin/npm
pnpm: 9.15.4 - ~/.nvm/versions/node/v20.11.1/bin/pnpm
Languages:
Bash: 3.2.57 - /bin/bash
npmPackages:
@playwright/test: ^1.50.1 => 1.50.1