Skip to content

Commit c6cc4c9

Browse files
authored
chore(roll): roll Playwright to 1.45.0-alpha-2024-06-14 (microsoft#2464)
1 parent b331b8e commit c6cc4c9

29 files changed

+2055
-122
lines changed

README.md

Lines changed: 2 additions & 2 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 -->125.0.6422.26<!-- GEN:stop --> ||||
7+
| Chromium <!-- GEN:chromium-version -->127.0.6533.5<!-- GEN:stop --> ||||
88
| WebKit <!-- GEN:webkit-version -->17.4<!-- GEN:stop --> ||||
9-
| Firefox <!-- GEN:firefox-version -->125.0.1<!-- GEN:stop --> ||||
9+
| Firefox <!-- GEN:firefox-version -->127.0<!-- GEN:stop --> ||||
1010

1111
## Documentation
1212

playwright/_impl/_api_structures.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class HttpCredentials(TypedDict, total=False):
6363
username: str
6464
password: str
6565
origin: Optional[str]
66+
send: Optional[Literal["always", "unauthorized"]]
6667

6768

6869
class LocalStorageEntry(TypedDict):

playwright/_impl/_browser_context.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
)
4040
from playwright._impl._artifact import Artifact
4141
from playwright._impl._cdp_session import CDPSession
42+
from playwright._impl._clock import Clock
4243
from playwright._impl._connection import (
4344
ChannelOwner,
4445
from_channel,
@@ -114,6 +115,7 @@ def __init__(
114115
self._tracing = cast(Tracing, from_channel(initializer["tracing"]))
115116
self._har_recorders: Dict[str, HarRecordingMetadata] = {}
116117
self._request: APIRequestContext = from_channel(initializer["requestContext"])
118+
self._clock = Clock(self)
117119
self._channel.on(
118120
"bindingCall",
119121
lambda params: self._on_binding(from_channel(params["binding"])),
@@ -519,6 +521,10 @@ async def close(self, reason: str = None) -> None:
519521
self._close_reason = reason
520522
self._close_was_called = True
521523

524+
await self._channel._connection.wrap_api_call(
525+
lambda: self.request.dispose(reason=reason), True
526+
)
527+
522528
async def _inner_close() -> None:
523529
for har_id, params in self._har_recorders.items():
524530
har = cast(
@@ -679,3 +685,7 @@ def tracing(self) -> Tracing:
679685
@property
680686
def request(self) -> "APIRequestContext":
681687
return self._request
688+
689+
@property
690+
def clock(self) -> Clock:
691+
return self._clock

playwright/_impl/_clock.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Copyright (c) Microsoft Corporation.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import datetime
16+
from typing import TYPE_CHECKING, Dict, Union
17+
18+
if TYPE_CHECKING:
19+
from playwright._impl._browser_context import BrowserContext
20+
21+
22+
class Clock:
23+
def __init__(self, browser_context: "BrowserContext") -> None:
24+
self._browser_context = browser_context
25+
self._loop = browser_context._loop
26+
self._dispatcher_fiber = browser_context._dispatcher_fiber
27+
28+
async def install(self, time: Union[int, str, datetime.datetime] = None) -> None:
29+
await self._browser_context._channel.send(
30+
"clockInstall", parse_time(time) if time is not None else {}
31+
)
32+
33+
async def fast_forward(
34+
self,
35+
ticks: Union[int, str],
36+
) -> None:
37+
await self._browser_context._channel.send(
38+
"clockFastForward", parse_ticks(ticks)
39+
)
40+
41+
async def pause_at(
42+
self,
43+
time: Union[int, str, datetime.datetime],
44+
) -> None:
45+
await self._browser_context._channel.send("clockPauseAt", parse_time(time))
46+
47+
async def resume(
48+
self,
49+
) -> None:
50+
await self._browser_context._channel.send("clockResume")
51+
52+
async def run_for(
53+
self,
54+
ticks: Union[int, str],
55+
) -> None:
56+
await self._browser_context._channel.send("clockRunFor", parse_ticks(ticks))
57+
58+
async def set_fixed_time(
59+
self,
60+
time: Union[int, str, datetime.datetime],
61+
) -> None:
62+
await self._browser_context._channel.send("clockSetFixedTime", parse_time(time))
63+
64+
async def set_system_time(
65+
self,
66+
time: Union[int, str, datetime.datetime],
67+
) -> None:
68+
await self._browser_context._channel.send(
69+
"clockSetSystemTime", parse_time(time)
70+
)
71+
72+
73+
def parse_time(time: Union[int, str, datetime.datetime]) -> Dict[str, Union[int, str]]:
74+
if isinstance(time, int):
75+
return {"timeNumber": time}
76+
if isinstance(time, str):
77+
return {"timeString": time}
78+
return {"timeNumber": int(time.timestamp())}
79+
80+
81+
def parse_ticks(ticks: Union[int, str]) -> Dict[str, Union[int, str]]:
82+
if isinstance(ticks, int):
83+
return {"ticksNumber": ticks}
84+
return {"ticksString": ticks}

playwright/_impl/_fetch.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from playwright._impl._helper import (
3535
Error,
3636
NameValue,
37+
TargetClosedError,
3738
async_readfile,
3839
async_writefile,
3940
is_file_payload,
@@ -93,9 +94,16 @@ def __init__(
9394
) -> None:
9495
super().__init__(parent, type, guid, initializer)
9596
self._tracing: Tracing = from_channel(initializer["tracing"])
97+
self._close_reason: Optional[str] = None
9698

97-
async def dispose(self) -> None:
98-
await self._channel.send("dispose")
99+
async def dispose(self, reason: str = None) -> None:
100+
self._close_reason = reason
101+
try:
102+
await self._channel.send("dispose", {"reason": reason})
103+
except Error as e:
104+
if is_target_closed_error(e):
105+
return
106+
raise e
99107
self._tracing._reset_stack_counter()
100108

101109
async def delete(
@@ -313,6 +321,8 @@ async def _inner_fetch(
313321
ignoreHTTPSErrors: bool = None,
314322
maxRedirects: int = None,
315323
) -> "APIResponse":
324+
if self._close_reason:
325+
raise TargetClosedError(self._close_reason)
316326
assert (
317327
(1 if data else 0) + (1 if form else 0) + (1 if multipart else 0)
318328
) <= 1, "Only one of 'data', 'form' or 'multipart' can be specified"

playwright/_impl/_helper.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@
3737
from urllib.parse import urljoin
3838

3939
from playwright._impl._api_structures import NameValue
40-
from playwright._impl._errors import Error, TargetClosedError, TimeoutError
40+
from playwright._impl._errors import (
41+
Error,
42+
TargetClosedError,
43+
TimeoutError,
44+
is_target_closed_error,
45+
rewrite_error,
46+
)
4147
from playwright._impl._glob import glob_to_regex
4248
from playwright._impl._greenlets import RouteGreenlet
4349
from playwright._impl._str_utils import escape_regex_flags
@@ -287,6 +293,14 @@ async def handle(self, route: "Route") -> bool:
287293
# If the handler was stopped (without waiting for completion), we ignore all exceptions.
288294
if self._ignore_exception:
289295
return False
296+
if is_target_closed_error(e):
297+
# We are failing in the handler because the target has closed.
298+
# Give user a hint!
299+
optional_async_prefix = "await " if not self._is_sync else ""
300+
raise rewrite_error(
301+
e,
302+
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.",
303+
)
290304
raise e
291305
finally:
292306
handler_invocation.complete.set_result(None)

playwright/_impl/_network.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,6 @@ def __init__(
111111
self._fallback_overrides: SerializedFallbackOverrides = (
112112
SerializedFallbackOverrides()
113113
)
114-
base64_post_data = initializer.get("postData")
115-
if base64_post_data is not None:
116-
self._fallback_overrides.post_data_buffer = base64.b64decode(
117-
base64_post_data
118-
)
119114

120115
def __repr__(self) -> str:
121116
return f"<Request url={self.url!r} method={self.method!r}>"
@@ -159,9 +154,12 @@ async def sizes(self) -> RequestSizes:
159154
@property
160155
def post_data(self) -> Optional[str]:
161156
data = self._fallback_overrides.post_data_buffer
162-
if not data:
163-
return None
164-
return data.decode()
157+
if data:
158+
return data.decode()
159+
base64_post_data = self._initializer.get("postData")
160+
if base64_post_data is not None:
161+
return base64.b64decode(base64_post_data).decode()
162+
return None
165163

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

179177
@property
180178
def post_data_buffer(self) -> Optional[bytes]:
181-
return self._fallback_overrides.post_data_buffer
179+
if self._fallback_overrides.post_data_buffer:
180+
return self._fallback_overrides.post_data_buffer
181+
if self._initializer.get("postData"):
182+
return base64.b64decode(self._initializer["postData"])
183+
return None
182184

183185
async def response(self) -> Optional["Response"]:
184186
return from_nullable_channel(await self._channel.send("response"))

playwright/_impl/_page.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
ViewportSize,
4444
)
4545
from playwright._impl._artifact import Artifact
46+
from playwright._impl._clock import Clock
4647
from playwright._impl._connection import (
4748
ChannelOwner,
4849
from_channel,
@@ -336,6 +337,10 @@ def _on_video(self, params: Any) -> None:
336337
def context(self) -> "BrowserContext":
337338
return self._browser_context
338339

340+
@property
341+
def clock(self) -> Clock:
342+
return self._browser_context.clock
343+
339344
async def opener(self) -> Optional["Page"]:
340345
if self._opener and self._opener.is_closed():
341346
return None

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy