Skip to content

Commit b807406

Browse files
authored
chore(roll): roll Playwright to 1.48.0-beta-1728034490000 (#2584)
1 parent ece2d01 commit b807406

24 files changed

+1759
-168
lines changed

README.md

+2-2
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 -->129.0.6668.29<!-- GEN:stop --> ||||
7+
| Chromium <!-- GEN:chromium-version -->130.0.6723.31<!-- GEN:stop --> ||||
88
| WebKit <!-- GEN:webkit-version -->18.0<!-- GEN:stop --> ||||
9-
| Firefox <!-- GEN:firefox-version -->130.0<!-- GEN:stop --> ||||
9+
| Firefox <!-- GEN:firefox-version -->131.0<!-- GEN:stop --> ||||
1010

1111
## Documentation
1212

playwright/_impl/_browser_context.py

+52-3
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,22 @@
6262
TimeoutSettings,
6363
URLMatch,
6464
URLMatcher,
65+
WebSocketRouteHandlerCallback,
6566
async_readfile,
6667
async_writefile,
6768
locals_to_params,
6869
parse_error,
6970
prepare_record_har_options,
7071
to_impl,
7172
)
72-
from playwright._impl._network import Request, Response, Route, serialize_headers
73+
from playwright._impl._network import (
74+
Request,
75+
Response,
76+
Route,
77+
WebSocketRoute,
78+
WebSocketRouteHandler,
79+
serialize_headers,
80+
)
7381
from playwright._impl._page import BindingCall, Page, Worker
7482
from playwright._impl._str_utils import escape_regex_flags
7583
from playwright._impl._tracing import Tracing
@@ -106,6 +114,7 @@ def __init__(
106114
self._browser._contexts.append(self)
107115
self._pages: List[Page] = []
108116
self._routes: List[RouteHandler] = []
117+
self._web_socket_routes: List[WebSocketRouteHandler] = []
109118
self._bindings: Dict[str, Any] = {}
110119
self._timeout_settings = TimeoutSettings(None)
111120
self._owner_page: Optional[Page] = None
@@ -132,7 +141,14 @@ def __init__(
132141
)
133142
),
134143
)
135-
144+
self._channel.on(
145+
"webSocketRoute",
146+
lambda params: self._loop.create_task(
147+
self._on_web_socket_route(
148+
from_channel(params["webSocketRoute"]),
149+
)
150+
),
151+
)
136152
self._channel.on(
137153
"backgroundPage",
138154
lambda params: self._on_background_page(from_channel(params["page"])),
@@ -244,10 +260,24 @@ async def _on_route(self, route: Route) -> None:
244260
try:
245261
# If the page is closed or unrouteAll() was called without waiting and interception disabled,
246262
# the method will throw an error - silence it.
247-
await route._internal_continue(is_internal=True)
263+
await route._inner_continue(True)
248264
except Exception:
249265
pass
250266

267+
async def _on_web_socket_route(self, web_socket_route: WebSocketRoute) -> None:
268+
route_handler = next(
269+
(
270+
route_handler
271+
for route_handler in self._web_socket_routes
272+
if route_handler.matches(web_socket_route.url)
273+
),
274+
None,
275+
)
276+
if route_handler:
277+
await route_handler.handle(web_socket_route)
278+
else:
279+
web_socket_route.connect_to_server()
280+
251281
def _on_binding(self, binding_call: BindingCall) -> None:
252282
func = self._bindings.get(binding_call._initializer["name"])
253283
if func is None:
@@ -418,6 +448,17 @@ async def _unroute_internal(
418448
return
419449
await asyncio.gather(*map(lambda router: router.stop(behavior), removed)) # type: ignore
420450

451+
async def route_web_socket(
452+
self, url: URLMatch, handler: WebSocketRouteHandlerCallback
453+
) -> None:
454+
self._web_socket_routes.insert(
455+
0,
456+
WebSocketRouteHandler(
457+
URLMatcher(self._options.get("baseURL"), url), handler
458+
),
459+
)
460+
await self._update_web_socket_interception_patterns()
461+
421462
def _dispose_har_routers(self) -> None:
422463
for router in self._har_routers:
423464
router.dispose()
@@ -488,6 +529,14 @@ async def _update_interception_patterns(self) -> None:
488529
"setNetworkInterceptionPatterns", {"patterns": patterns}
489530
)
490531

532+
async def _update_web_socket_interception_patterns(self) -> None:
533+
patterns = WebSocketRouteHandler.prepare_interception_patterns(
534+
self._web_socket_routes
535+
)
536+
await self._channel.send(
537+
"setWebSocketInterceptionPatterns", {"patterns": patterns}
538+
)
539+
491540
def expect_event(
492541
self,
493542
event: str,

playwright/_impl/_connection.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ def __init__(
132132
self._channel: Channel = Channel(self._connection, self)
133133
self._initializer = initializer
134134
self._was_collected = False
135+
self._is_internal_type = False
135136

136137
self._connection._objects[guid] = self
137138
if self._parent:
@@ -156,6 +157,9 @@ def _adopt(self, child: "ChannelOwner") -> None:
156157
self._objects[child._guid] = child
157158
child._parent = self
158159

160+
def mark_as_internal_type(self) -> None:
161+
self._is_internal_type = True
162+
159163
def _set_event_to_subscription_mapping(self, mapping: Dict[str, str]) -> None:
160164
self._event_to_subscription_mapping = mapping
161165

@@ -355,7 +359,7 @@ def _send_message_to_server(
355359
"params": self._replace_channels_with_guids(params),
356360
"metadata": metadata,
357361
}
358-
if self._tracing_count > 0 and frames and object._guid != "localUtils":
362+
if self._tracing_count > 0 and frames and not object._is_internal_type:
359363
self.local_utils.add_stack_to_tracing_no_reply(id, frames)
360364

361365
self._transport.send(message)

playwright/_impl/_fetch.py

+2-19
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import typing
1919
from pathlib import Path
2020
from typing import Any, Dict, List, Optional, Union, cast
21-
from urllib.parse import parse_qs
2221

2322
import playwright._impl._network as network
2423
from playwright._impl._api_structures import (
@@ -405,7 +404,8 @@ async def _inner_fetch(
405404
"fetch",
406405
{
407406
"url": url,
408-
"params": params_to_protocol(params),
407+
"params": object_to_array(params) if isinstance(params, dict) else None,
408+
"encodedParams": params if isinstance(params, str) else None,
409409
"method": method,
410410
"headers": serialized_headers,
411411
"postData": post_data,
@@ -430,23 +430,6 @@ async def storage_state(
430430
return result
431431

432432

433-
def params_to_protocol(params: Optional[ParamsType]) -> Optional[List[NameValue]]:
434-
if not params:
435-
return None
436-
if isinstance(params, dict):
437-
return object_to_array(params)
438-
if params.startswith("?"):
439-
params = params[1:]
440-
parsed = parse_qs(params)
441-
if not parsed:
442-
return None
443-
out = []
444-
for name, values in parsed.items():
445-
for value in values:
446-
out.append(NameValue(name=name, value=value))
447-
return out
448-
449-
450433
def file_payload_to_json(payload: FilePayload) -> ServerFilePayload:
451434
return ServerFilePayload(
452435
name=payload["name"],

playwright/_impl/_helper.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,15 @@
5050

5151
if TYPE_CHECKING: # pragma: no cover
5252
from playwright._impl._api_structures import HeadersArray
53-
from playwright._impl._network import Request, Response, Route
53+
from playwright._impl._network import Request, Response, Route, WebSocketRoute
5454

5555
URLMatch = Union[str, Pattern[str], Callable[[str], bool]]
5656
URLMatchRequest = Union[str, Pattern[str], Callable[["Request"], bool]]
5757
URLMatchResponse = Union[str, Pattern[str], Callable[["Response"], bool]]
5858
RouteHandlerCallback = Union[
5959
Callable[["Route"], Any], Callable[["Route", "Request"], Any]
6060
]
61+
WebSocketRouteHandlerCallback = Callable[["WebSocketRoute"], Any]
6162

6263
ColorScheme = Literal["dark", "light", "no-preference", "null"]
6364
ForcedColors = Literal["active", "none", "null"]

playwright/_impl/_local_utils.py

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def __init__(
2525
self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
2626
) -> None:
2727
super().__init__(parent, type, guid, initializer)
28+
self.mark_as_internal_type()
2829
self.devices = {
2930
device["name"]: parse_device_descriptor(device["descriptor"])
3031
for device in initializer["deviceDescriptors"]

0 commit comments

Comments
 (0)