Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(roll): roll Playwright to 1.48.0-beta-1728034490000 #2584

Merged
merged 6 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Playwright is a Python library to automate [Chromium](https://www.chromium.org/H

| | Linux | macOS | Windows |
| :--- | :---: | :---: | :---: |
| Chromium <!-- GEN:chromium-version -->129.0.6668.29<!-- GEN:stop --> | ✅ | ✅ | ✅ |
| Chromium <!-- GEN:chromium-version -->130.0.6723.31<!-- GEN:stop --> | ✅ | ✅ | ✅ |
| WebKit <!-- GEN:webkit-version -->18.0<!-- GEN:stop --> | ✅ | ✅ | ✅ |
| Firefox <!-- GEN:firefox-version -->130.0<!-- GEN:stop --> | ✅ | ✅ | ✅ |
| Firefox <!-- GEN:firefox-version -->131.0<!-- GEN:stop --> | ✅ | ✅ | ✅ |

## Documentation

Expand Down
55 changes: 52 additions & 3 deletions playwright/_impl/_browser_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,22 @@
TimeoutSettings,
URLMatch,
URLMatcher,
WebSocketRouteHandlerCallback,
async_readfile,
async_writefile,
locals_to_params,
parse_error,
prepare_record_har_options,
to_impl,
)
from playwright._impl._network import Request, Response, Route, serialize_headers
from playwright._impl._network import (
Request,
Response,
Route,
WebSocketRoute,
WebSocketRouteHandler,
serialize_headers,
)
from playwright._impl._page import BindingCall, Page, Worker
from playwright._impl._str_utils import escape_regex_flags
from playwright._impl._tracing import Tracing
Expand Down Expand Up @@ -106,6 +114,7 @@ def __init__(
self._browser._contexts.append(self)
self._pages: List[Page] = []
self._routes: List[RouteHandler] = []
mxschmitt marked this conversation as resolved.
Show resolved Hide resolved
self._web_socket_routes: List[WebSocketRouteHandler] = []
self._bindings: Dict[str, Any] = {}
self._timeout_settings = TimeoutSettings(None)
self._owner_page: Optional[Page] = None
Expand All @@ -132,7 +141,14 @@ def __init__(
)
),
)

self._channel.on(
"webSocketRoute",
lambda params: self._loop.create_task(
self._on_web_socket_route(
from_channel(params["webSocketRoute"]),
)
),
)
self._channel.on(
"backgroundPage",
lambda params: self._on_background_page(from_channel(params["page"])),
Expand Down Expand Up @@ -244,10 +260,24 @@ async def _on_route(self, route: Route) -> None:
try:
# If the page is closed or unrouteAll() was called without waiting and interception disabled,
# the method will throw an error - silence it.
await route._internal_continue(is_internal=True)
await route._inner_continue(True)
except Exception:
pass

async def _on_web_socket_route(self, web_socket_route: WebSocketRoute) -> None:
route_handler = next(
(
route_handler
for route_handler in self._web_socket_routes
if route_handler.matches(web_socket_route.url)
),
None,
)
if route_handler:
await route_handler.handle(web_socket_route)
else:
web_socket_route.connect_to_server()

def _on_binding(self, binding_call: BindingCall) -> None:
func = self._bindings.get(binding_call._initializer["name"])
if func is None:
Expand Down Expand Up @@ -418,6 +448,17 @@ async def _unroute_internal(
return
await asyncio.gather(*map(lambda router: router.stop(behavior), removed)) # type: ignore

async def route_web_socket(
self, url: URLMatch, handler: WebSocketRouteHandlerCallback
) -> None:
self._web_socket_routes.insert(
0,
WebSocketRouteHandler(
URLMatcher(self._options.get("baseURL"), url), handler
),
)
await self._update_web_socket_interception_patterns()

def _dispose_har_routers(self) -> None:
for router in self._har_routers:
router.dispose()
Expand Down Expand Up @@ -488,6 +529,14 @@ async def _update_interception_patterns(self) -> None:
"setNetworkInterceptionPatterns", {"patterns": patterns}
)

async def _update_web_socket_interception_patterns(self) -> None:
patterns = WebSocketRouteHandler.prepare_interception_patterns(
self._web_socket_routes
)
await self._channel.send(
"setWebSocketInterceptionPatterns", {"patterns": patterns}
)

def expect_event(
self,
event: str,
Expand Down
6 changes: 5 additions & 1 deletion playwright/_impl/_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ def __init__(
self._channel: Channel = Channel(self._connection, self)
self._initializer = initializer
self._was_collected = False
self._is_internal_type = False

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

def mark_as_internal_type(self) -> None:
self._is_internal_type = True

def _set_event_to_subscription_mapping(self, mapping: Dict[str, str]) -> None:
self._event_to_subscription_mapping = mapping

Expand Down Expand Up @@ -355,7 +359,7 @@ def _send_message_to_server(
"params": self._replace_channels_with_guids(params),
"metadata": metadata,
}
if self._tracing_count > 0 and frames and object._guid != "localUtils":
if self._tracing_count > 0 and frames and not object._is_internal_type:
self.local_utils.add_stack_to_tracing_no_reply(id, frames)

self._transport.send(message)
Expand Down
21 changes: 2 additions & 19 deletions playwright/_impl/_fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import typing
from pathlib import Path
from typing import Any, Dict, List, Optional, Union, cast
from urllib.parse import parse_qs

import playwright._impl._network as network
from playwright._impl._api_structures import (
Expand Down Expand Up @@ -405,7 +404,8 @@ async def _inner_fetch(
"fetch",
{
"url": url,
"params": params_to_protocol(params),
"params": object_to_array(params) if isinstance(params, dict) else None,
"encodedParams": params if isinstance(params, str) else None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen this change in .net or java roll for some reason. Could you please double check?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Java we don't allow passing query params as strings while in JS/Python/.NET we do. There is no .NET roll yet for this release after we moved the merge logic to the server side.

In Java we have:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather not do it in the ports to keep the API surface smaller, especially if there is no user request for this.

mxschmitt marked this conversation as resolved.
Show resolved Hide resolved
"method": method,
"headers": serialized_headers,
"postData": post_data,
Expand All @@ -430,23 +430,6 @@ async def storage_state(
return result


def params_to_protocol(params: Optional[ParamsType]) -> Optional[List[NameValue]]:
if not params:
return None
if isinstance(params, dict):
return object_to_array(params)
if params.startswith("?"):
params = params[1:]
parsed = parse_qs(params)
if not parsed:
return None
out = []
for name, values in parsed.items():
for value in values:
out.append(NameValue(name=name, value=value))
return out


def file_payload_to_json(payload: FilePayload) -> ServerFilePayload:
return ServerFilePayload(
name=payload["name"],
Expand Down
3 changes: 2 additions & 1 deletion playwright/_impl/_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,15 @@

if TYPE_CHECKING: # pragma: no cover
from playwright._impl._api_structures import HeadersArray
from playwright._impl._network import Request, Response, Route
from playwright._impl._network import Request, Response, Route, WebSocketRoute

URLMatch = Union[str, Pattern[str], Callable[[str], bool]]
URLMatchRequest = Union[str, Pattern[str], Callable[["Request"], bool]]
URLMatchResponse = Union[str, Pattern[str], Callable[["Response"], bool]]
RouteHandlerCallback = Union[
Callable[["Route"], Any], Callable[["Route", "Request"], Any]
]
WebSocketRouteHandlerCallback = Callable[["WebSocketRoute"], Any]

ColorScheme = Literal["dark", "light", "no-preference", "null"]
ForcedColors = Literal["active", "none", "null"]
Expand Down
1 change: 1 addition & 0 deletions playwright/_impl/_local_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def __init__(
self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
) -> None:
super().__init__(parent, type, guid, initializer)
self.mark_as_internal_type()
self.devices = {
device["name"]: parse_device_descriptor(device["descriptor"])
for device in initializer["deviceDescriptors"]
Expand Down
Loading
Loading