Skip to content

Commit f45782e

Browse files
authored
chore: roll to v1.49.0 (#2660)
1 parent 569d7c0 commit f45782e

27 files changed

+854
-189
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ Playwright is a Python library to automate [Chromium](https://www.chromium.org/H
44

55
| | Linux | macOS | Windows |
66
| :--- | :---: | :---: | :---: |
7-
| Chromium <!-- GEN:chromium-version -->130.0.6723.31<!-- GEN:stop --> ||||
8-
| WebKit <!-- GEN:webkit-version -->18.0<!-- GEN:stop --> ||||
9-
| Firefox <!-- GEN:firefox-version -->131.0<!-- GEN:stop --> ||||
7+
| Chromium <!-- GEN:chromium-version -->131.0.6778.33<!-- GEN:stop --> ||||
8+
| WebKit <!-- GEN:webkit-version -->18.2<!-- GEN:stop --> ||||
9+
| Firefox <!-- GEN:firefox-version -->132.0<!-- GEN:stop --> ||||
1010

1111
## Documentation
1212

playwright/_impl/_api_structures.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,3 +291,9 @@ class FrameExpectResult(TypedDict):
291291
"treegrid",
292292
"treeitem",
293293
]
294+
295+
296+
class TracingGroupLocation(TypedDict):
297+
file: str
298+
line: Optional[int]
299+
column: Optional[int]

playwright/_impl/_assertions.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,23 @@ async def not_to_have_role(self, role: AriaRole, timeout: float = None) -> None:
783783
__tracebackhide__ = True
784784
await self._not.to_have_role(role, timeout)
785785

786+
async def to_match_aria_snapshot(
787+
self, expected: str, timeout: float = None
788+
) -> None:
789+
__tracebackhide__ = True
790+
await self._expect_impl(
791+
"to.match.aria",
792+
FrameExpectOptions(expectedValue=expected, timeout=timeout),
793+
expected,
794+
"Locator expected to match Aria snapshot",
795+
)
796+
797+
async def not_to_match_aria_snapshot(
798+
self, expected: str, timeout: float = None
799+
) -> None:
800+
__tracebackhide__ = True
801+
await self._not.to_match_aria_snapshot(expected, timeout)
802+
786803

787804
class APIResponseAssertions:
788805
def __init__(

playwright/_impl/_browser_context.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
RouteHandlerCallback,
6262
TimeoutSettings,
6363
URLMatch,
64-
URLMatcher,
6564
WebSocketRouteHandlerCallback,
6665
async_readfile,
6766
async_writefile,
@@ -416,7 +415,8 @@ async def route(
416415
self._routes.insert(
417416
0,
418417
RouteHandler(
419-
URLMatcher(self._options.get("baseURL"), url),
418+
self._options.get("baseURL"),
419+
url,
420420
handler,
421421
True if self._dispatcher_fiber else False,
422422
times,
@@ -430,7 +430,7 @@ async def unroute(
430430
removed = []
431431
remaining = []
432432
for route in self._routes:
433-
if route.matcher.match != url or (handler and route.handler != handler):
433+
if route.url != url or (handler and route.handler != handler):
434434
remaining.append(route)
435435
else:
436436
removed.append(route)
@@ -453,9 +453,7 @@ async def route_web_socket(
453453
) -> None:
454454
self._web_socket_routes.insert(
455455
0,
456-
WebSocketRouteHandler(
457-
URLMatcher(self._options.get("baseURL"), url), handler
458-
),
456+
WebSocketRouteHandler(self._options.get("baseURL"), url, handler),
459457
)
460458
await self._update_web_socket_interception_patterns()
461459

playwright/_impl/_frame.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@
4545
Literal,
4646
MouseButton,
4747
URLMatch,
48-
URLMatcher,
4948
async_readfile,
5049
locals_to_params,
5150
monotonic_time,
51+
url_matches,
5252
)
5353
from playwright._impl._js_handle import (
5454
JSHandle,
@@ -185,18 +185,17 @@ def expect_navigation(
185185

186186
to_url = f' to "{url}"' if url else ""
187187
waiter.log(f"waiting for navigation{to_url} until '{waitUntil}'")
188-
matcher = (
189-
URLMatcher(self._page._browser_context._options.get("baseURL"), url)
190-
if url
191-
else None
192-
)
193188

194189
def predicate(event: Any) -> bool:
195190
# Any failed navigation results in a rejection.
196191
if event.get("error"):
197192
return True
198193
waiter.log(f' navigated to "{event["url"]}"')
199-
return not matcher or matcher.matches(event["url"])
194+
return url_matches(
195+
cast("Page", self._page)._browser_context._options.get("baseURL"),
196+
event["url"],
197+
url,
198+
)
200199

201200
waiter.wait_for_event(
202201
self._event_emitter,
@@ -226,8 +225,9 @@ async def wait_for_url(
226225
timeout: float = None,
227226
) -> None:
228227
assert self._page
229-
matcher = URLMatcher(self._page._browser_context._options.get("baseURL"), url)
230-
if matcher.matches(self.url):
228+
if url_matches(
229+
self._page._browser_context._options.get("baseURL"), self.url, url
230+
):
231231
await self._wait_for_load_state_impl(state=waitUntil, timeout=timeout)
232232
return
233233
async with self.expect_navigation(

playwright/_impl/_helper.py

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -142,27 +142,26 @@ class FrameNavigatedEvent(TypedDict):
142142
Env = Dict[str, Union[str, float, bool]]
143143

144144

145-
class URLMatcher:
146-
def __init__(self, base_url: Union[str, None], match: URLMatch) -> None:
147-
self._callback: Optional[Callable[[str], bool]] = None
148-
self._regex_obj: Optional[Pattern[str]] = None
149-
if isinstance(match, str):
150-
if base_url and not match.startswith("*"):
151-
match = urljoin(base_url, match)
152-
regex = glob_to_regex(match)
153-
self._regex_obj = re.compile(regex)
154-
elif isinstance(match, Pattern):
155-
self._regex_obj = match
156-
else:
157-
self._callback = match
158-
self.match = match
159-
160-
def matches(self, url: str) -> bool:
161-
if self._callback:
162-
return self._callback(url)
163-
if self._regex_obj:
164-
return cast(bool, self._regex_obj.search(url))
165-
return False
145+
def url_matches(
146+
base_url: Optional[str], url_string: str, match: Optional[URLMatch]
147+
) -> bool:
148+
if not match:
149+
return True
150+
if isinstance(match, str) and match[0] != "*":
151+
# Allow http(s) baseURL to match ws(s) urls.
152+
if (
153+
base_url
154+
and re.match(r"^https?://", base_url)
155+
and re.match(r"^wss?://", url_string)
156+
):
157+
base_url = re.sub(r"^http", "ws", base_url)
158+
if base_url:
159+
match = urljoin(base_url, match)
160+
if isinstance(match, str):
161+
match = glob_to_regex(match)
162+
if isinstance(match, Pattern):
163+
return bool(match.search(url_string))
164+
return match(url_string)
166165

167166

168167
class HarLookupResult(TypedDict, total=False):
@@ -271,12 +270,14 @@ def __init__(self, complete: "asyncio.Future", route: "Route") -> None:
271270
class RouteHandler:
272271
def __init__(
273272
self,
274-
matcher: URLMatcher,
273+
base_url: Optional[str],
274+
url: URLMatch,
275275
handler: RouteHandlerCallback,
276276
is_sync: bool,
277277
times: Optional[int] = None,
278278
):
279-
self.matcher = matcher
279+
self._base_url = base_url
280+
self.url = url
280281
self.handler = handler
281282
self._times = times if times else math.inf
282283
self._handled_count = 0
@@ -285,7 +286,7 @@ def __init__(
285286
self._active_invocations: Set[RouteHandlerInvocation] = set()
286287

287288
def matches(self, request_url: str) -> bool:
288-
return self.matcher.matches(request_url)
289+
return url_matches(self._base_url, request_url, self.url)
289290

290291
async def handle(self, route: "Route") -> bool:
291292
handler_invocation = RouteHandlerInvocation(
@@ -362,13 +363,13 @@ def prepare_interception_patterns(
362363
patterns = []
363364
all = False
364365
for handler in handlers:
365-
if isinstance(handler.matcher.match, str):
366-
patterns.append({"glob": handler.matcher.match})
367-
elif isinstance(handler.matcher._regex_obj, re.Pattern):
366+
if isinstance(handler.url, str):
367+
patterns.append({"glob": handler.url})
368+
elif isinstance(handler.url, re.Pattern):
368369
patterns.append(
369370
{
370-
"regexSource": handler.matcher._regex_obj.pattern,
371-
"regexFlags": escape_regex_flags(handler.matcher._regex_obj),
371+
"regexSource": handler.url.pattern,
372+
"regexFlags": escape_regex_flags(handler.url),
372373
}
373374
)
374375
else:

playwright/_impl/_locator.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,15 @@ async def screenshot(
534534
),
535535
)
536536

537+
async def aria_snapshot(self, timeout: float = None) -> str:
538+
return await self._frame._channel.send(
539+
"ariaSnapshot",
540+
{
541+
"selector": self._selector,
542+
**locals_to_params(locals()),
543+
},
544+
)
545+
537546
async def scroll_into_view_if_needed(
538547
self,
539548
timeout: float = None,

playwright/_impl/_network.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@
5353
from playwright._impl._errors import Error
5454
from playwright._impl._event_context_manager import EventContextManagerImpl
5555
from playwright._impl._helper import (
56-
URLMatcher,
56+
URLMatch,
5757
WebSocketRouteHandlerCallback,
5858
async_readfile,
5959
locals_to_params,
60+
url_matches,
6061
)
6162
from playwright._impl._str_utils import escape_regex_flags
6263
from playwright._impl._waiter import Waiter
@@ -718,8 +719,14 @@ async def _after_handle(self) -> None:
718719

719720

720721
class WebSocketRouteHandler:
721-
def __init__(self, matcher: URLMatcher, handler: WebSocketRouteHandlerCallback):
722-
self.matcher = matcher
722+
def __init__(
723+
self,
724+
base_url: Optional[str],
725+
url: URLMatch,
726+
handler: WebSocketRouteHandlerCallback,
727+
):
728+
self._base_url = base_url
729+
self.url = url
723730
self.handler = handler
724731

725732
@staticmethod
@@ -729,13 +736,13 @@ def prepare_interception_patterns(
729736
patterns = []
730737
all_urls = False
731738
for handler in handlers:
732-
if isinstance(handler.matcher.match, str):
733-
patterns.append({"glob": handler.matcher.match})
734-
elif isinstance(handler.matcher._regex_obj, re.Pattern):
739+
if isinstance(handler.url, str):
740+
patterns.append({"glob": handler.url})
741+
elif isinstance(handler.url, re.Pattern):
735742
patterns.append(
736743
{
737-
"regexSource": handler.matcher._regex_obj.pattern,
738-
"regexFlags": escape_regex_flags(handler.matcher._regex_obj),
744+
"regexSource": handler.url.pattern,
745+
"regexFlags": escape_regex_flags(handler.url),
739746
}
740747
)
741748
else:
@@ -746,7 +753,7 @@ def prepare_interception_patterns(
746753
return patterns
747754

748755
def matches(self, ws_url: str) -> bool:
749-
return self.matcher.matches(ws_url)
756+
return url_matches(self._base_url, ws_url, self.url)
750757

751758
async def handle(self, websocket_route: "WebSocketRoute") -> None:
752759
coro_or_future = self.handler(websocket_route)

0 commit comments

Comments
 (0)