Skip to content

Commit 5c82385

Browse files
committed
Bumped to 1.53.0-beta-1749221468000 due to selector bug
2 parents a626c55 + 1a85b74 commit 5c82385

21 files changed

+253
-151
lines changed

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 -->137.0.7151.27<!-- GEN:stop --> ||||
8-
| WebKit <!-- GEN:webkit-version -->18.4<!-- GEN:stop --> ||||
9-
| Firefox <!-- GEN:firefox-version -->137.0<!-- GEN:stop --> ||||
7+
| Chromium <!-- GEN:chromium-version -->138.0.7204.15<!-- GEN:stop --> ||||
8+
| WebKit <!-- GEN:webkit-version -->18.5<!-- GEN:stop --> ||||
9+
| Firefox <!-- GEN:firefox-version -->139.0<!-- GEN:stop --> ||||
1010

1111
## Documentation
1212

playwright/_impl/_api_structures.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ class Cookie(TypedDict, total=False):
3434
sameSite: Literal["Lax", "None", "Strict"]
3535

3636

37-
class PartitionedCookie(Cookie):
38-
partitionKey: Optional[str]
39-
40-
4137
# TODO: We are waiting for PEP705 so SetCookieParam can be readonly and matches Cookie.
4238
class SetCookieParam(TypedDict, total=False):
4339
name: str
@@ -49,7 +45,6 @@ class SetCookieParam(TypedDict, total=False):
4945
httpOnly: Optional[bool]
5046
secure: Optional[bool]
5147
sameSite: Optional[Literal["Lax", "None", "Strict"]]
52-
partitionKey: Optional[str]
5348

5449

5550
class FloatRect(TypedDict):
@@ -106,11 +101,6 @@ class StorageState(TypedDict, total=False):
106101
origins: List[OriginState]
107102

108103

109-
class PartitionedStorageState(TypedDict, total=False):
110-
cookies: List[PartitionedCookie]
111-
origins: List[OriginState]
112-
113-
114104
class ClientCertificate(TypedDict, total=False):
115105
origin: str
116106
certPath: Optional[Union[str, Path]]

playwright/_impl/_assertions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ async def _expect_impl(
5151
expect_options: FrameExpectOptions,
5252
expected: Any,
5353
message: str,
54+
# title: str,
5455
) -> None:
5556
__tracebackhide__ = True
5657
expect_options["isNot"] = self._is_not
@@ -60,6 +61,7 @@ async def _expect_impl(
6061
message = message.replace("expected to", "expected not to")
6162
if "useInnerText" in expect_options and expect_options["useInnerText"] is None:
6263
del expect_options["useInnerText"]
64+
# result = await self._actual_locator._expect(expression, expect_options, title)
6365
result = await self._actual_locator._expect(expression, expect_options)
6466
if result["matches"] == self._is_not:
6567
actual = result.get("received")
@@ -123,7 +125,10 @@ async def to_have_url(
123125
base_url = self._actual_page.context._options.get("baseURL")
124126
if isinstance(urlOrRegExp, str) and base_url:
125127
urlOrRegExp = urljoin(base_url, urlOrRegExp)
128+
print("Changed", urlOrRegExp)
129+
print("Expecting URL", urlOrRegExp)
126130
expected_text = to_expected_text_values([urlOrRegExp], ignoreCase=ignoreCase)
131+
print("Expected text", expected_text)
127132
await self._expect_impl(
128133
"to.have.url",
129134
FrameExpectOptions(expectedText=expected_text, timeout=timeout),

playwright/_impl/_browser.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,43 @@ def __init__(
6565
self._cr_tracing_path: Optional[str] = None
6666

6767
self._contexts: List[BrowserContext] = []
68+
self._traces_dir: Optional[str] = None
69+
self._channel.on(
70+
"context",
71+
lambda params: self._did_create_context(
72+
cast(BrowserContext, from_channel(params["context"]))
73+
),
74+
)
6875
self._channel.on("close", lambda _: self._on_close())
6976
self._close_reason: Optional[str] = None
7077

7178
def __repr__(self) -> str:
7279
return f"<Browser type={self._browser_type} version={self.version}>"
7380

81+
def _connect_to_browser_type(
82+
self,
83+
browserType: "BrowserType",
84+
tracesDir: Optional[str] = None,
85+
) -> None:
86+
# Note: when using connect(), `browserType` is different from `this.parent`.
87+
# This is why browser type is not wired up in the constructor, and instead this separate method is called later on.
88+
self._browser_type = browserType
89+
self._traces_dir = tracesDir
90+
for context in self._contexts:
91+
self._setup_browser_context(context)
92+
93+
def _did_create_context(self, context: BrowserContext) -> None:
94+
context._browser = self
95+
self._contexts.append(context)
96+
# Note: when connecting to a browser, initial contexts arrive before `_browserType` is set,
97+
# and will be configured later in `ConnectToBrowserType`.
98+
if self._browser_type:
99+
self._setup_browser_context(context)
100+
101+
def _setup_browser_context(self, context: BrowserContext) -> None:
102+
context._tracing._traces_dir = self._traces_dir
103+
self._browser_type._playwright.selectors._contextsForSelectors.append(context)
104+
74105
def _on_close(self) -> None:
75106
self._is_connected = False
76107
self.emit(Browser.Events.Disconnected, self)
@@ -130,7 +161,15 @@ async def new_context(
130161

131162
channel = await self._channel.send("newContext", params)
132163
context = cast(BrowserContext, from_channel(channel))
133-
self._browser_type._did_create_context(context, params, {})
164+
await context._initialize_har_from_options(
165+
{
166+
"recordHarPath": recordHarPath,
167+
"recordHarContent": recordHarContent,
168+
"recordHarOmitContent": recordHarOmitContent,
169+
"recordHarUrlFilter": recordHarUrlFilter,
170+
"recordHarMode": recordHarMode,
171+
}
172+
)
134173
return context
135174

136175
async def new_page(
@@ -181,6 +220,7 @@ async def inner() -> Page:
181220
context._owner_page = page
182221
return page
183222

223+
# TODO: Args
184224
return await self._connection.wrap_api_call(inner)
185225

186226
async def close(self, reason: str = None) -> None:

playwright/_impl/_browser_context.py

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@
3232
)
3333

3434
from playwright._impl._api_structures import (
35+
Cookie,
3536
Geolocation,
36-
PartitionedCookie,
37-
PartitionedStorageState,
3837
SetCookieParam,
38+
StorageState,
3939
)
4040
from playwright._impl._artifact import Artifact
4141
from playwright._impl._cdp_session import CDPSession
@@ -66,7 +66,6 @@
6666
async_writefile,
6767
locals_to_params,
6868
parse_error,
69-
prepare_record_har_options,
7069
to_impl,
7170
)
7271
from playwright._impl._network import (
@@ -106,6 +105,7 @@ def __init__(
106105
self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
107106
) -> None:
108107
super().__init__(parent, type, guid, initializer)
108+
# Browser is null for browser contexts created outside of normal browser, e.g. android or electron.
109109
# circular import workaround:
110110
self._browser: Optional["Browser"] = None
111111
if parent.__class__.__name__ == "Browser":
@@ -220,7 +220,7 @@ def __init__(
220220
BrowserContext.Events.RequestFailed: "requestFailed",
221221
}
222222
)
223-
self._close_was_called = False
223+
self._closing_or_closed = False
224224

225225
def __repr__(self) -> str:
226226
return f"<BrowserContext browser={self.browser}>"
@@ -237,7 +237,7 @@ async def _on_route(self, route: Route) -> None:
237237
route_handlers = self._routes.copy()
238238
for route_handler in route_handlers:
239239
# If the page or the context was closed we stall all requests right away.
240-
if (page and page._close_was_called) or self._close_was_called:
240+
if (page and page._close_was_called) or self._closing_or_closed:
241241
return
242242
if not route_handler.matches(route.request.url):
243243
continue
@@ -312,14 +312,29 @@ def _set_options(self, context_options: Dict, browser_options: Dict) -> None:
312312
}
313313
self._tracing._traces_dir = browser_options.get("tracesDir")
314314

315+
async def _initialize_har_from_options(self, options: Dict) -> None:
316+
record_har_path = str(options["recordHarPath"])
317+
if not record_har_path or len(record_har_path) == 0:
318+
return
319+
default_policy = "attach" if record_har_path.endswith(".zip") else "embed"
320+
content_policy = options.get(
321+
"recordHarContent",
322+
"omit" if options["recordHarOmitContent"] is True else default_policy,
323+
)
324+
await self._record_into_har(
325+
har=record_har_path,
326+
page=None,
327+
url=options["recordHarUrlFilter"],
328+
update_content=content_policy,
329+
update_mode=options.get("recordHarMode", "full"),
330+
)
331+
315332
async def new_page(self) -> Page:
316333
if self._owner_page:
317334
raise Error("Please use browser.new_context()")
318335
return from_channel(await self._channel.send("newPage"))
319336

320-
async def cookies(
321-
self, urls: Union[str, Sequence[str]] = None
322-
) -> List[PartitionedCookie]:
337+
async def cookies(self, urls: Union[str, Sequence[str]] = None) -> List[Cookie]:
323338
if urls is None:
324339
urls = []
325340
if isinstance(urls, str):
@@ -471,22 +486,25 @@ async def _record_into_har(
471486
update_content: HarContentPolicy = None,
472487
update_mode: HarMode = None,
473488
) -> None:
489+
update_content = update_content or "attach"
474490
params: Dict[str, Any] = {
475-
"options": prepare_record_har_options(
476-
{
477-
"recordHarPath": har,
478-
"recordHarContent": update_content or "attach",
479-
"recordHarMode": update_mode or "minimal",
480-
"recordHarUrlFilter": url,
481-
}
482-
)
491+
"options": {
492+
"zip": str(har).endswith(".zip"),
493+
"content": update_content,
494+
"urlGlob": url if isinstance(url, str) else None,
495+
"urlRegexSource": url.pattern if isinstance(url, Pattern) else None,
496+
"urlRegexFlags": (
497+
escape_regex_flags(url) if isinstance(url, Pattern) else None
498+
),
499+
"mode": update_mode or "minimal",
500+
}
483501
}
484502
if page:
485503
params["page"] = page._channel
486504
har_id = await self._channel.send("harStart", params)
487505
self._har_recorders[har_id] = {
488506
"path": str(har),
489-
"content": update_content or "attach",
507+
"content": update_content,
490508
}
491509

492510
async def route_from_har(
@@ -550,22 +568,30 @@ def expect_event(
550568
return EventContextManagerImpl(waiter.result())
551569

552570
def _on_close(self) -> None:
571+
self._closing_or_closed = True
553572
if self._browser:
554-
self._browser._contexts.remove(self)
573+
try:
574+
self._browser._contexts.remove(self)
575+
except ValueError:
576+
pass
577+
try:
578+
self._browser._browser_type._playwright.selectors._contextsForSelectors.remove(
579+
self
580+
)
581+
except ValueError:
582+
pass
555583

556584
self._dispose_har_routers()
557585
self._tracing._reset_stack_counter()
558586
self.emit(BrowserContext.Events.Close, self)
559587

560588
async def close(self, reason: str = None) -> None:
561-
if self._close_was_called:
589+
if self._closing_or_closed:
562590
return
563591
self._close_reason = reason
564-
self._close_was_called = True
592+
self._closing_or_closed = True
565593

566-
await self._channel._connection.wrap_api_call(
567-
lambda: self.request.dispose(reason=reason), True
568-
)
594+
await self.request.dispose(reason=reason)
569595

570596
async def _inner_close() -> None:
571597
for har_id, params in self._har_recorders.items():
@@ -596,7 +622,7 @@ async def _inner_close() -> None:
596622

597623
async def storage_state(
598624
self, path: Union[str, Path] = None, indexedDB: bool = None
599-
) -> PartitionedStorageState:
625+
) -> StorageState:
600626
result = await self._channel.send_return_as_dict(
601627
"storageState", {"indexedDB": indexedDB}
602628
)

0 commit comments

Comments
 (0)