2020
2121import pytest
2222
23- from playwright ._impl ._glob import glob_to_regex
23+ from playwright ._impl ._glob import glob_to_regex_pattern
24+ from playwright ._impl ._helper import url_matches
2425from playwright .async_api import (
2526 Browser ,
2627 BrowserContext ,
2930 Playwright ,
3031 Request ,
3132 Route ,
33+ expect ,
3234)
3335from tests .server import Server , TestServerRequest
3436from tests .utils import must
@@ -1051,17 +1053,19 @@ async def handle_request(route: Route) -> None:
10511053 assert await response .json () == {"foo" : "bar" }
10521054
10531055
1054- async def test_glob_to_regex () -> None :
1056+ async def test_should_work_with_glob () -> None :
1057+ def glob_to_regex (pattern : str ) -> re .Pattern :
1058+ return re .compile (glob_to_regex_pattern (pattern ))
1059+
10551060 assert glob_to_regex ("**/*.js" ).match ("https://localhost:8080/foo.js" )
10561061 assert not glob_to_regex ("**/*.css" ).match ("https://localhost:8080/foo.js" )
1057- assert not glob_to_regex ("*.js" ).match ("https://localhost:8080/foo.js" )
1062+ assert not glob_to_regex ("*.js" ).match (
1063+ "https://localhost:8080/foo.js"
1064+ ) # Doesn"t match path separator
10581065 assert glob_to_regex ("https://**/*.js" ).match ("https://localhost:8080/foo.js" )
10591066 assert glob_to_regex ("http://localhost:8080/simple/path.js" ).match (
10601067 "http://localhost:8080/simple/path.js"
10611068 )
1062- assert glob_to_regex ("http://localhost:8080/?imple/path.js" ).match (
1063- "http://localhost:8080/Simple/path.js"
1064- )
10651069 assert glob_to_regex ("**/{a,b}.js" ).match ("https://localhost:8080/a.js" )
10661070 assert glob_to_regex ("**/{a,b}.js" ).match ("https://localhost:8080/b.js" )
10671071 assert not glob_to_regex ("**/{a,b}.js" ).match ("https://localhost:8080/c.js" )
@@ -1081,15 +1085,119 @@ async def test_glob_to_regex() -> None:
10811085 "http://localhost:3000/signin-oidcnice"
10821086 )
10831087
1084- assert glob_to_regex ("**/three-columns/settings.html?**id=[a-z]**" ).match (
1088+ # range [] is NOT supported
1089+ assert glob_to_regex ("**/api/v[0-9]" ).fullmatch ("http://example.com/api/v[0-9]" )
1090+ assert not glob_to_regex ("**/api/v[0-9]" ).fullmatch (
1091+ "http://example.com/api/version"
1092+ )
1093+ assert not glob_to_regex ("**/api/v[0-9]" ).fullmatch (
1094+ "http://example.com/api/v1"
1095+ ) # Should not match if [] is literal
1096+
1097+ # query params
1098+ assert glob_to_regex ("**/api\\ ?param" ).match ("http://example.com/api?param" )
1099+ assert not glob_to_regex ("**/api\\ ?param" ).match ("http://example.com/api-param" )
1100+
1101+ assert glob_to_regex ("**/three-columns/settings.html\\ ?**id=settings-**" ).match (
10851102 "http://mydomain:8080/blah/blah/three-columns/settings.html?id=settings-e3c58efe-02e9-44b0-97ac-dd138100cf7c&blah"
10861103 )
10871104
1088- assert glob_to_regex ("\\ ?" ) == re .compile (r"^\?$" )
1089- assert glob_to_regex ("\\ " ) == re .compile (r"^\\$" )
1090- assert glob_to_regex ("\\ \\ " ) == re .compile (r"^\\$" )
1091- assert glob_to_regex ("\\ [" ) == re .compile (r"^\[$" )
1092- assert glob_to_regex ("[a-z]" ) == re .compile (r"^[a-z]$" )
1093- assert glob_to_regex ("$^+.\\ *()|\\ ?\\ {\\ }\\ [\\ ]" ) == re .compile (
1094- r"^\$\^\+\.\*\(\)\|\?\{\}\[\]$"
1105+ assert glob_to_regex ("\\ ?" ).pattern == r"^\?$"
1106+ assert glob_to_regex ("\\ " ).pattern == r"^\\$"
1107+ assert glob_to_regex ("\\ \\ " ).pattern == r"^\\$"
1108+ assert glob_to_regex ("\\ [" ).pattern == r"^\[$"
1109+ assert glob_to_regex ("[a-z]" ).pattern == r"^\[a-z\]$"
1110+ assert (
1111+ glob_to_regex ("$^+.\\ *()|\\ ?\\ {\\ }\\ [\\ ]" ).pattern
1112+ == r"^\$\^\+\.\*\(\)\|\?\{\}\[\]$"
1113+ )
1114+
1115+ # --- url_matches tests ---
1116+ # Basic exact and wildcard matching
1117+ assert url_matches (None , "http://playwright.dev/" , "http://playwright.dev" )
1118+ assert url_matches (None , "http://playwright.dev/?a=b" , "http://playwright.dev?a=b" )
1119+ assert url_matches (None , "http://playwright.dev/" , "h*://playwright.dev" )
1120+ assert url_matches (
1121+ None , "http://api.playwright.dev/?x=y" , "http://*.playwright.dev?x=y"
1122+ )
1123+ assert url_matches (None , "http://playwright.dev/foo/bar" , "**/foo/**" )
1124+
1125+ # Relative path matching with base URL
1126+ assert url_matches ("http://playwright.dev" , "http://playwright.dev/?x=y" , "?x=y" )
1127+ assert url_matches (
1128+ "http://playwright.dev/foo/" , "http://playwright.dev/foo/bar?x=y" , "./bar?x=y"
1129+ )
1130+
1131+ # This is not supported, we treat ? as a query separator.
1132+ assert not url_matches (
1133+ None ,
1134+ "http://localhost:8080/Simple/path.js" ,
1135+ "http://localhost:8080/?imple/path.js" ,
1136+ )
1137+ assert not url_matches (None , "http://playwright.dev/" , "http://playwright.?ev" )
1138+ assert url_matches (None , "http://playwright./?ev" , "http://playwright.?ev" )
1139+ assert not url_matches (
1140+ None , "http://playwright.dev/foo" , "http://playwright.dev/f??"
1141+ )
1142+ assert url_matches (None , "http://playwright.dev/f??" , "http://playwright.dev/f??" )
1143+ assert url_matches (
1144+ None , "http://playwright.dev/?x=y" , r"http://playwright.dev\?x=y"
1145+ )
1146+ assert url_matches (
1147+ None , "http://playwright.dev/?x=y" , r"http://playwright.dev/\?x=y"
1148+ )
1149+ assert url_matches (
1150+ "http://playwright.dev/foo" , "http://playwright.dev/foo?bar" , "?bar"
1151+ )
1152+ assert url_matches (
1153+ "http://playwright.dev/foo" , "http://playwright.dev/foo?bar" , r"\\?bar"
1154+ )
1155+ assert url_matches ("http://first.host/" , "http://second.host/foo" , "**/foo" )
1156+ assert url_matches ("http://playwright.dev/" , "http://localhost/" , "*//localhost/" )
1157+
1158+ # Added for Python implementation
1159+ assert url_matches (
1160+ None ,
1161+ "custom://example.com/foo/bar?id=123" ,
1162+ "{custom,another}://example.com/foo/bar?id=123" ,
1163+ )
1164+ assert not url_matches (
1165+ None , "custom://example.com/foo/bar?id=123" , "**example.com/foo/bar?id=123"
10951166 )
1167+
1168+
1169+ async def test_should_not_support_question_in_glob_pattern (
1170+ page : Page , playwright : Playwright , server : Server
1171+ ) -> None :
1172+ server .set_route ("/index" , lambda req : (req .write (b"index-no-hello" ), req .finish ()))
1173+ server .set_route (
1174+ "/index123hello" , lambda req : (req .write (b"index123hello" ), req .finish ())
1175+ )
1176+ server .set_route (
1177+ "/index?hello" , lambda req : (req .write (b"index?hello" ), req .finish ())
1178+ )
1179+ server .set_route (
1180+ "/index1hello" , lambda req : (req .write (b"index1hello" ), req .finish ())
1181+ )
1182+
1183+ async def handle_any_char (route : Route ) -> None :
1184+ await route .fulfill (body = "intercepted any character" )
1185+
1186+ await page .route ("**/index?hello" , handle_any_char )
1187+
1188+ async def handle_question_mark (route : Route ) -> None :
1189+ await route .fulfill (body = "intercepted question mark" )
1190+
1191+ await page .route (r"**/index\?hello" , handle_question_mark )
1192+
1193+ await page .goto (server .PREFIX + "/index?hello" )
1194+ await expect (page .locator ("body" )).to_have_text ("intercepted question mark" )
1195+
1196+ await page .goto (server .PREFIX + "/index" )
1197+ await expect (page .locator ("body" )).to_have_text ("index-no-hello" )
1198+
1199+ await page .goto (server .PREFIX + "/index1hello" )
1200+ await expect (page .locator ("body" )).to_have_text ("index1hello" )
1201+
1202+ await page .goto (server .PREFIX + "/index123hello" )
1203+ await expect (page .locator ("body" )).to_have_text ("index123hello" )
0 commit comments