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,119 @@ 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
+ 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"
1095
1166
)
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