Skip to content

Commit ae494b2

Browse files
authored
chore: roll Playwright to 1.64.0 (#3237)
1 parent 1764101 commit ae494b2

43 files changed

Lines changed: 2004 additions & 170 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎DRIVER_VERSION‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.63.0
1+
1.64.0

‎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 -->153.0.8010.12<!-- GEN:stop --> | ✅ | ✅ | ✅ |
8-
| WebKit <!-- GEN:webkit-version -->26.6<!-- GEN:stop --> | ✅ | ✅ | ✅ |
9-
| Firefox <!-- GEN:firefox-version -->155.0<!-- GEN:stop --> | ✅ | ✅ | ✅ |
7+
| Chromium <!-- GEN:chromium-version -->156.0.8078.4<!-- GEN:stop --> | ✅ | ✅ | ✅ |
8+
| WebKit <!-- GEN:webkit-version -->27.2<!-- GEN:stop --> | ✅ | ✅ | ✅ |
9+
| Firefox <!-- GEN:firefox-version -->157.0<!-- GEN:stop --> | ✅ | ✅ | ✅ |
1010

1111
## Documentation
1212

‎playwright/_impl/_api_structures.py‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,12 +350,32 @@ class ScreencastSize(TypedDict):
350350
height: int
351351

352352

353+
class ScreencastActionStyle(TypedDict, total=False):
354+
point: Optional[str]
355+
highlight: Optional[str]
356+
title: Optional[str]
357+
358+
353359
class VirtualCredential(TypedDict):
354360
id: str
355361
rpId: str
356362
userHandle: str
357363
privateKey: str
358364
publicKey: str
365+
signCount: int
366+
367+
368+
class WebMCPToolAnnotations(TypedDict, total=False):
369+
readOnly: Optional[bool]
370+
untrustedContent: Optional[bool]
371+
consequential: Optional[bool]
372+
373+
374+
class WebMCPTool(TypedDict, total=False):
375+
name: str
376+
description: str
377+
inputSchema: Optional[Any]
378+
annotations: Optional[WebMCPToolAnnotations]
359379

360380

361381
class ScreencastFrame(TypedDict):

‎playwright/_impl/_browser.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ async def new_context(
167167
recordHarMode: HarMode = None,
168168
recordHarContent: HarContentPolicy = None,
169169
clientCertificates: List[ClientCertificate] = None,
170+
recordVideoFps: int = None,
170171
) -> BrowserContext:
171172
params = locals_to_params(locals())
172173
assert self._browser_type is not None
@@ -221,6 +222,7 @@ async def new_page(
221222
recordHarMode: HarMode = None,
222223
recordHarContent: HarContentPolicy = None,
223224
clientCertificates: List[ClientCertificate] = None,
225+
recordVideoFps: int = None,
224226
) -> Page:
225227
params = locals_to_params(locals())
226228

‎playwright/_impl/_browser_context.py‎

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@
7878
WebSocketRoute,
7979
WebSocketRouteHandler,
8080
serialize_headers,
81+
to_clear_cookies_params,
8182
)
8283
from playwright._impl._page import BindingCall, Page, Worker
83-
from playwright._impl._str_utils import escape_regex_flags
8484
from playwright._impl._tracing import Tracing
8585
from playwright._impl._waiter import Waiter
8686
from playwright._impl._web_error import WebError
@@ -369,27 +369,7 @@ async def clear_cookies(
369369
path: Union[str, Pattern[str]] = None,
370370
) -> None:
371371
await self._channel.send(
372-
"clearCookies",
373-
None,
374-
{
375-
"name": name if isinstance(name, str) else None,
376-
"nameRegexSource": name.pattern if isinstance(name, Pattern) else None,
377-
"nameRegexFlags": (
378-
escape_regex_flags(name) if isinstance(name, Pattern) else None
379-
),
380-
"domain": domain if isinstance(domain, str) else None,
381-
"domainRegexSource": (
382-
domain.pattern if isinstance(domain, Pattern) else None
383-
),
384-
"domainRegexFlags": (
385-
escape_regex_flags(domain) if isinstance(domain, Pattern) else None
386-
),
387-
"path": path if isinstance(path, str) else None,
388-
"pathRegexSource": path.pattern if isinstance(path, Pattern) else None,
389-
"pathRegexFlags": (
390-
escape_regex_flags(path) if isinstance(path, Pattern) else None
391-
),
392-
},
372+
"clearCookies", None, to_clear_cookies_params(name, domain, path)
393373
)
394374

395375
async def grant_permissions(

‎playwright/_impl/_browser_type.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ async def launch_persistent_context(
161161
recordHarMode: HarMode = None,
162162
recordHarContent: HarContentPolicy = None,
163163
clientCertificates: List[ClientCertificate] = None,
164+
recordVideoFps: int = None,
164165
) -> BrowserContext:
165166
userDataDir = self._user_data_dir(userDataDir)
166167
params = locals_to_params(locals())
@@ -313,7 +314,10 @@ async def _prepare_browser_context_params(self, params: Dict) -> None:
313314
if "recordVideoSize" in params:
314315
params["recordVideo"]["size"] = params["recordVideoSize"]
315316
del params["recordVideoSize"]
317+
if "recordVideoFps" in params:
318+
params["recordVideo"]["fps"] = params["recordVideoFps"]
316319
del params["recordVideoDir"]
320+
params.pop("recordVideoFps", None)
317321
if "storageState" in params:
318322
storageState = params["storageState"]
319323
if not isinstance(storageState, dict):

‎playwright/_impl/_connection.py‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import contextvars
1818
import datetime
1919
import inspect
20+
import random
21+
import string
2022
import sys
2123
import traceback
2224
from pathlib import Path
@@ -250,7 +252,7 @@ def remove_listener(self, event: str, f: Any) -> None:
250252

251253
class ProtocolCallback:
252254
def __init__(
253-
self, loop: asyncio.AbstractEventLoop, id: int, no_reply: bool = False
255+
self, loop: asyncio.AbstractEventLoop, id: str, no_reply: bool = False
254256
) -> None:
255257
self.id = id
256258
self.stack_trace: traceback.StackSummary
@@ -305,9 +307,11 @@ def __init__(
305307
self._dispatcher_fiber = dispatcher_fiber
306308
self._transport = transport
307309
self._transport.on_message = lambda msg: self.dispatch(msg)
310+
# Call ids double as trace call ids, so they must be unique across connections.
311+
self._call_id_prefix = "".join(random.choices(string.ascii_lowercase, k=4))
308312
self._last_id = 0
309313
self._objects: Dict[str, ChannelOwner] = {}
310-
self._callbacks: Dict[int, ProtocolCallback] = {}
314+
self._callbacks: Dict[str, ProtocolCallback] = {}
311315
self._object_factory = object_factory
312316
self._is_sync = False
313317
self._child_ws_connections: List["Connection"] = []
@@ -403,7 +407,7 @@ def _send_message_to_server(
403407
"The object has been collected to prevent unbounded heap growth."
404408
)
405409
self._last_id += 1
406-
id = self._last_id
410+
id = f"{self._call_id_prefix}@{self._last_id}"
407411
callback = ProtocolCallback(self._loop, id, no_reply=no_reply)
408412
task = asyncio.current_task(self._loop)
409413
callback.stack_trace = cast(

‎playwright/_impl/_credentials.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ async def create(
3737
userHandle: str = None,
3838
privateKey: str = None,
3939
publicKey: str = None,
40+
signCount: int = None,
4041
) -> VirtualCredential:
4142
result = await self._browser_context._channel.send_return_as_dict(
4243
"credentialsCreate", None, locals_to_params(locals())

‎playwright/_impl/_fetch.py‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@
1818
import pathlib
1919
import typing
2020
from pathlib import Path
21-
from typing import Any, Dict, List, Optional, Sequence, Union, cast
21+
from typing import Any, Dict, List, Optional, Pattern, Sequence, Union, cast
2222

2323
import playwright._impl._network as network
2424
from playwright._impl._api_structures import (
2525
ClientCertificate,
26+
Cookie,
2627
FilePayload,
2728
FormField,
2829
Headers,
@@ -32,6 +33,7 @@
3233
ResourceTiming,
3334
SecurityDetails,
3435
ServerFilePayload,
36+
SetCookieParam,
3537
StorageState,
3638
)
3739
from playwright._impl._connection import ChannelOwner, from_channel
@@ -51,6 +53,7 @@
5153
)
5254
from playwright._impl._network import (
5355
serialize_headers,
56+
to_clear_cookies_params,
5457
to_client_certificates_protocol,
5558
to_http_credentials_protocol,
5659
)
@@ -136,6 +139,26 @@ async def dispose(self, reason: str = None) -> None:
136139
def tracing(self) -> Tracing:
137140
return self._tracing
138141

142+
async def cookies(self, urls: Union[str, Sequence[str]] = None) -> List[Cookie]:
143+
if urls is None:
144+
urls = []
145+
if isinstance(urls, str):
146+
urls = [urls]
147+
return await self._channel.send("cookies", None, dict(urls=urls))
148+
149+
async def add_cookies(self, cookies: Sequence[SetCookieParam]) -> None:
150+
await self._channel.send("addCookies", None, dict(cookies=cookies))
151+
152+
async def clear_cookies(
153+
self,
154+
name: Union[str, Pattern[str]] = None,
155+
domain: Union[str, Pattern[str]] = None,
156+
path: Union[str, Pattern[str]] = None,
157+
) -> None:
158+
await self._channel.send(
159+
"clearCookies", None, to_clear_cookies_params(name, domain, path)
160+
)
161+
139162
async def delete(
140163
self,
141164
url: str,

‎playwright/_impl/_frame.py‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
from playwright._impl._network import Response
8383
from playwright._impl._set_input_files_helpers import convert_input_files
8484
from playwright._impl._waiter import Waiter
85+
from playwright._impl._webmcp import WebMCP
8586

8687
if TYPE_CHECKING: # pragma: no cover
8788
from playwright._impl._page import Page
@@ -102,6 +103,7 @@ def __init__(
102103
self._page: Optional[Page] = None
103104
self._load_states: Set[str] = set(initializer["loadStates"])
104105
self._event_emitter = EventEmitter()
106+
self._webmcp = WebMCP(self)
105107
self._channel.on(
106108
"loadstate",
107109
lambda params: self._on_load_state(params.get("add"), params.get("remove")),
@@ -497,8 +499,8 @@ async def eval_on_selector_all(
497499
)
498500
)
499501

500-
async def content(self) -> str:
501-
return await self._channel.send("content", None)
502+
async def content(self, includeShadow: bool = None) -> str:
503+
return await self._channel.send("content", None, locals_to_params(locals()))
502504

503505
async def set_content(
504506
self,
@@ -518,6 +520,10 @@ def name(self) -> str:
518520
def url(self) -> str:
519521
return self._url or ""
520522

523+
@property
524+
def webmcp(self) -> WebMCP:
525+
return self._webmcp
526+
521527
@property
522528
def parent_frame(self) -> Optional["Frame"]:
523529
return self._parent_frame

0 commit comments

Comments
 (0)