20
20
21
21
import pytest
22
22
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
24
25
from playwright .async_api import (
25
26
Browser ,
26
27
BrowserContext ,
29
30
Playwright ,
30
31
Request ,
31
32
Route ,
33
+ expect ,
32
34
)
33
35
from tests .server import Server , TestServerRequest
34
36
from tests .utils import must
@@ -1051,17 +1053,19 @@ async def handle_request(route: Route) -> None:
1051
1053
assert await response .json () == {"foo" : "bar" }
1052
1054
1053
1055
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
+
1055
1060
assert glob_to_regex ("**/*.js" ).match ("https://localhost:8080/foo.js" )
1056
1061
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
1058
1065
assert glob_to_regex ("https://**/*.js" ).match ("https://localhost:8080/foo.js" )
1059
1066
assert glob_to_regex ("http://localhost:8080/simple/path.js" ).match (
1060
1067
"http://localhost:8080/simple/path.js"
1061
1068
)
1062
- assert glob_to_regex ("http://localhost:8080/?imple/path.js" ).match (
1063
- "http://localhost:8080/Simple/path.js"
1064
- )
1065
1069
assert glob_to_regex ("**/{a,b}.js" ).match ("https://localhost:8080/a.js" )
1066
1070
assert glob_to_regex ("**/{a,b}.js" ).match ("https://localhost:8080/b.js" )
1067
1071
assert not glob_to_regex ("**/{a,b}.js" ).match ("https://localhost:8080/c.js" )
@@ -1081,15 +1085,110 @@ async def test_glob_to_regex() -> None:
1081
1085
"http://localhost:3000/signin-oidcnice"
1082
1086
)
1083
1087
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 (
1085
1102
"http://mydomain:8080/blah/blah/three-columns/settings.html?id=settings-e3c58efe-02e9-44b0-97ac-dd138100cf7c&blah"
1086
1103
)
1087
1104
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
+ print (glob_to_regex ("\\ ?" ).pattern )
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 ("\\ [" ).pattern == r"^\[$"
1110
+ assert glob_to_regex ("[a-z]" ).pattern == r"^\[a-z\]$"
1111
+ assert (
1112
+ glob_to_regex ("$^+.\\ *()|\\ ?\\ {\\ }\\ [\\ ]" ).pattern
1113
+ == r"^\$\^\+\.\*\(\)\|\?\{\}\[\]$"
1114
+ )
1115
+
1116
+ # --- url_matches tests ---
1117
+ # Basic exact and wildcard matching
1118
+ assert url_matches (None , "http://playwright.dev/" , "http://playwright.dev" )
1119
+ assert url_matches (None , "http://playwright.dev/?a=b" , "http://playwright.dev?a=b" )
1120
+ assert url_matches (None , "http://playwright.dev/" , "h*://playwright.dev" )
1121
+ assert url_matches (
1122
+ None , "http://api.playwright.dev/?x=y" , "http://*.playwright.dev?x=y"
1123
+ )
1124
+ assert url_matches (None , "http://playwright.dev/foo/bar" , "**/foo/**" )
1125
+
1126
+ # Relative path matching with base URL
1127
+ assert url_matches ("http://playwright.dev" , "http://playwright.dev/?x=y" , "?x=y" )
1128
+ assert url_matches (
1129
+ "http://playwright.dev/foo/" , "http://playwright.dev/foo/bar?x=y" , "./bar?x=y"
1130
+ )
1131
+
1132
+ # This is not supported, we treat ? as a query separator.
1133
+ assert not url_matches (
1134
+ None ,
1135
+ "http://localhost:8080/Simple/path.js" ,
1136
+ "http://localhost:8080/?imple/path.js" ,
1137
+ )
1138
+ assert not url_matches (None , "http://playwright.dev/" , "http://playwright.?ev" )
1139
+ assert url_matches (None , "http://playwright./?ev" , "http://playwright.?ev" )
1140
+ assert not url_matches (
1141
+ None , "http://playwright.dev/foo" , "http://playwright.dev/f??"
1142
+ )
1143
+ assert url_matches (None , "http://playwright.dev/f??" , "http://playwright.dev/f??" )
1144
+ assert url_matches (
1145
+ None , "http://playwright.dev/?x=y" , r"http://playwright.dev\?x=y"
1095
1146
)
1147
+ assert url_matches (
1148
+ None , "http://playwright.dev/?x=y" , r"http://playwright.dev/\?x=y"
1149
+ )
1150
+ assert url_matches (
1151
+ "http://playwright.dev/foo" , "http://playwright.dev/foo?bar" , "?bar"
1152
+ )
1153
+ assert url_matches (
1154
+ "http://playwright.dev/foo" , "http://playwright.dev/foo?bar" , r"\\?bar"
1155
+ )
1156
+ assert url_matches ("http://first.host/" , "http://second.host/foo" , "**/foo" )
1157
+ assert url_matches ("http://playwright.dev/" , "http://localhost/" , "*//localhost/" )
1158
+
1159
+
1160
+ async def test_should_not_support_question_in_glob_pattern (
1161
+ page : Page , playwright : Playwright , server : Server
1162
+ ) -> None :
1163
+ server .set_route ("/index" , lambda req : (req .write (b"index-no-hello" ), req .finish ()))
1164
+ server .set_route (
1165
+ "/index123hello" , lambda req : (req .write (b"index123hello" ), req .finish ())
1166
+ )
1167
+ server .set_route (
1168
+ "/index?hello" , lambda req : (req .write (b"index?hello" ), req .finish ())
1169
+ )
1170
+ server .set_route (
1171
+ "/index1hello" , lambda req : (req .write (b"index1hello" ), req .finish ())
1172
+ )
1173
+
1174
+ async def handle_any_char (route : Route ) -> None :
1175
+ await route .fulfill (body = "intercepted any character" )
1176
+
1177
+ await page .route ("**/index?hello" , handle_any_char )
1178
+
1179
+ async def handle_question_mark (route : Route ) -> None :
1180
+ await route .fulfill (body = "intercepted question mark" )
1181
+
1182
+ await page .route (r"**/index\?hello" , handle_question_mark )
1183
+
1184
+ await page .goto (server .PREFIX + "/index?hello" )
1185
+ await expect (page .locator ("body" )).to_have_text ("intercepted question mark" )
1186
+
1187
+ await page .goto (server .PREFIX + "/index" )
1188
+ await expect (page .locator ("body" )).to_have_text ("index-no-hello" )
1189
+
1190
+ await page .goto (server .PREFIX + "/index1hello" )
1191
+ await expect (page .locator ("body" )).to_have_text ("index1hello" )
1192
+
1193
+ await page .goto (server .PREFIX + "/index123hello" )
1194
+ await expect (page .locator ("body" )).to_have_text ("index123hello" )
0 commit comments