Skip to content

Commit

Permalink
chore(roll): roll Playwright to 1.45.0-alpha-2024-06-14 (#2464)
Browse files Browse the repository at this point in the history
  • Loading branch information
mxschmitt committed Jun 21, 2024
1 parent b331b8e commit c6cc4c9
Show file tree
Hide file tree
Showing 29 changed files with 2,055 additions and 122 deletions.
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 -->125.0.6422.26<!-- GEN:stop --> ||||
| Chromium <!-- GEN:chromium-version -->127.0.6533.5<!-- GEN:stop --> ||||
| WebKit <!-- GEN:webkit-version -->17.4<!-- GEN:stop --> ||||
| Firefox <!-- GEN:firefox-version -->125.0.1<!-- GEN:stop --> ||||
| Firefox <!-- GEN:firefox-version -->127.0<!-- GEN:stop --> ||||

## Documentation

Expand Down
1 change: 1 addition & 0 deletions playwright/_impl/_api_structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class HttpCredentials(TypedDict, total=False):
username: str
password: str
origin: Optional[str]
send: Optional[Literal["always", "unauthorized"]]


class LocalStorageEntry(TypedDict):
Expand Down
10 changes: 10 additions & 0 deletions playwright/_impl/_browser_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
)
from playwright._impl._artifact import Artifact
from playwright._impl._cdp_session import CDPSession
from playwright._impl._clock import Clock
from playwright._impl._connection import (
ChannelOwner,
from_channel,
Expand Down Expand Up @@ -114,6 +115,7 @@ def __init__(
self._tracing = cast(Tracing, from_channel(initializer["tracing"]))
self._har_recorders: Dict[str, HarRecordingMetadata] = {}
self._request: APIRequestContext = from_channel(initializer["requestContext"])
self._clock = Clock(self)
self._channel.on(
"bindingCall",
lambda params: self._on_binding(from_channel(params["binding"])),
Expand Down Expand Up @@ -519,6 +521,10 @@ async def close(self, reason: str = None) -> None:
self._close_reason = reason
self._close_was_called = True

await self._channel._connection.wrap_api_call(
lambda: self.request.dispose(reason=reason), True
)

async def _inner_close() -> None:
for har_id, params in self._har_recorders.items():
har = cast(
Expand Down Expand Up @@ -679,3 +685,7 @@ def tracing(self) -> Tracing:
@property
def request(self) -> "APIRequestContext":
return self._request

@property
def clock(self) -> Clock:
return self._clock
84 changes: 84 additions & 0 deletions playwright/_impl/_clock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Copyright (c) Microsoft Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import datetime
from typing import TYPE_CHECKING, Dict, Union

if TYPE_CHECKING:
from playwright._impl._browser_context import BrowserContext


class Clock:
def __init__(self, browser_context: "BrowserContext") -> None:
self._browser_context = browser_context
self._loop = browser_context._loop
self._dispatcher_fiber = browser_context._dispatcher_fiber

async def install(self, time: Union[int, str, datetime.datetime] = None) -> None:
await self._browser_context._channel.send(
"clockInstall", parse_time(time) if time is not None else {}
)

async def fast_forward(
self,
ticks: Union[int, str],
) -> None:
await self._browser_context._channel.send(
"clockFastForward", parse_ticks(ticks)
)

async def pause_at(
self,
time: Union[int, str, datetime.datetime],
) -> None:
await self._browser_context._channel.send("clockPauseAt", parse_time(time))

async def resume(
self,
) -> None:
await self._browser_context._channel.send("clockResume")

async def run_for(
self,
ticks: Union[int, str],
) -> None:
await self._browser_context._channel.send("clockRunFor", parse_ticks(ticks))

async def set_fixed_time(
self,
time: Union[int, str, datetime.datetime],
) -> None:
await self._browser_context._channel.send("clockSetFixedTime", parse_time(time))

async def set_system_time(
self,
time: Union[int, str, datetime.datetime],
) -> None:
await self._browser_context._channel.send(
"clockSetSystemTime", parse_time(time)
)


def parse_time(time: Union[int, str, datetime.datetime]) -> Dict[str, Union[int, str]]:
if isinstance(time, int):
return {"timeNumber": time}
if isinstance(time, str):
return {"timeString": time}
return {"timeNumber": int(time.timestamp())}


def parse_ticks(ticks: Union[int, str]) -> Dict[str, Union[int, str]]:
if isinstance(ticks, int):
return {"ticksNumber": ticks}
return {"ticksString": ticks}
14 changes: 12 additions & 2 deletions playwright/_impl/_fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from playwright._impl._helper import (
Error,
NameValue,
TargetClosedError,
async_readfile,
async_writefile,
is_file_payload,
Expand Down Expand Up @@ -93,9 +94,16 @@ def __init__(
) -> None:
super().__init__(parent, type, guid, initializer)
self._tracing: Tracing = from_channel(initializer["tracing"])
self._close_reason: Optional[str] = None

async def dispose(self) -> None:
await self._channel.send("dispose")
async def dispose(self, reason: str = None) -> None:
self._close_reason = reason
try:
await self._channel.send("dispose", {"reason": reason})
except Error as e:
if is_target_closed_error(e):
return
raise e
self._tracing._reset_stack_counter()

async def delete(
Expand Down Expand Up @@ -313,6 +321,8 @@ async def _inner_fetch(
ignoreHTTPSErrors: bool = None,
maxRedirects: int = None,
) -> "APIResponse":
if self._close_reason:
raise TargetClosedError(self._close_reason)
assert (
(1 if data else 0) + (1 if form else 0) + (1 if multipart else 0)
) <= 1, "Only one of 'data', 'form' or 'multipart' can be specified"
Expand Down
16 changes: 15 additions & 1 deletion playwright/_impl/_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@
from urllib.parse import urljoin

from playwright._impl._api_structures import NameValue
from playwright._impl._errors import Error, TargetClosedError, TimeoutError
from playwright._impl._errors import (
Error,
TargetClosedError,
TimeoutError,
is_target_closed_error,
rewrite_error,
)
from playwright._impl._glob import glob_to_regex
from playwright._impl._greenlets import RouteGreenlet
from playwright._impl._str_utils import escape_regex_flags
Expand Down Expand Up @@ -287,6 +293,14 @@ async def handle(self, route: "Route") -> bool:
# If the handler was stopped (without waiting for completion), we ignore all exceptions.
if self._ignore_exception:
return False
if is_target_closed_error(e):
# We are failing in the handler because the target has closed.
# Give user a hint!
optional_async_prefix = "await " if not self._is_sync else ""
raise rewrite_error(
e,
f"\"{str(e)}\" while running route callback.\nConsider awaiting `{optional_async_prefix}page.unroute_all(behavior='ignoreErrors')`\nbefore the end of the test to ignore remaining routes in flight.",
)
raise e
finally:
handler_invocation.complete.set_result(None)
Expand Down
20 changes: 11 additions & 9 deletions playwright/_impl/_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,6 @@ def __init__(
self._fallback_overrides: SerializedFallbackOverrides = (
SerializedFallbackOverrides()
)
base64_post_data = initializer.get("postData")
if base64_post_data is not None:
self._fallback_overrides.post_data_buffer = base64.b64decode(
base64_post_data
)

def __repr__(self) -> str:
return f"<Request url={self.url!r} method={self.method!r}>"
Expand Down Expand Up @@ -159,9 +154,12 @@ async def sizes(self) -> RequestSizes:
@property
def post_data(self) -> Optional[str]:
data = self._fallback_overrides.post_data_buffer
if not data:
return None
return data.decode()
if data:
return data.decode()
base64_post_data = self._initializer.get("postData")
if base64_post_data is not None:
return base64.b64decode(base64_post_data).decode()
return None

@property
def post_data_json(self) -> Optional[Any]:
Expand All @@ -178,7 +176,11 @@ def post_data_json(self) -> Optional[Any]:

@property
def post_data_buffer(self) -> Optional[bytes]:
return self._fallback_overrides.post_data_buffer
if self._fallback_overrides.post_data_buffer:
return self._fallback_overrides.post_data_buffer
if self._initializer.get("postData"):
return base64.b64decode(self._initializer["postData"])
return None

async def response(self) -> Optional["Response"]:
return from_nullable_channel(await self._channel.send("response"))
Expand Down
5 changes: 5 additions & 0 deletions playwright/_impl/_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
ViewportSize,
)
from playwright._impl._artifact import Artifact
from playwright._impl._clock import Clock
from playwright._impl._connection import (
ChannelOwner,
from_channel,
Expand Down Expand Up @@ -336,6 +337,10 @@ def _on_video(self, params: Any) -> None:
def context(self) -> "BrowserContext":
return self._browser_context

@property
def clock(self) -> Clock:
return self._browser_context.clock

async def opener(self) -> Optional["Page"]:
if self._opener and self._opener.is_closed():
return None
Expand Down
Loading

0 comments on commit c6cc4c9

Please sign in to comment.