Skip to content

Commit 54b4bdf

Browse files
authored
chore: roll Playwright to 1.19.0 (#1157)
1 parent c98fda5 commit 54b4bdf

31 files changed

+505
-89
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Playwright is a Python library to automate [Chromium](https://www.chromium.org/H
44

55
| | Linux | macOS | Windows |
66
| :--- | :---: | :---: | :---: |
7-
| Chromium <!-- GEN:chromium-version -->99.0.4837.0<!-- GEN:stop --> ||||
7+
| Chromium <!-- GEN:chromium-version -->100.0.4863.0<!-- GEN:stop --> ||||
88
| WebKit <!-- GEN:webkit-version -->15.4<!-- GEN:stop --> ||||
99
| Firefox <!-- GEN:firefox-version -->96.0.1<!-- GEN:stop --> ||||
1010

playwright/_impl/_assertions.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,15 @@ async def _expect_impl(
4646
del expect_options["useInnerText"]
4747
result = await self._actual_locator._expect(expression, expect_options)
4848
if result["matches"] == self._is_not:
49+
actual = result.get("received")
4950
log = "\n".join(result.get("log", "")).strip()
5051
if log:
5152
log = "\nCall log:\n" + log
5253
if expected is not None:
53-
raise AssertionError(f"{message} '{expected}' {log}")
54-
raise AssertionError(f"{message} {log}")
54+
raise AssertionError(
55+
f"{message} '{expected}'\nActual value: {actual} {log}"
56+
)
57+
raise AssertionError(f"{message}\nActual value: {actual} {log}")
5558

5659

5760
class PageAssertions(AssertionsBase):

playwright/_impl/_browser_context.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,13 @@ def _on_page(self, page: Page) -> None:
159159
def _on_route(self, route: Route, request: Request) -> None:
160160
for handler_entry in self._routes:
161161
if handler_entry.matches(request.url):
162-
if handler_entry.handle(route, request):
163-
self._routes.remove(handler_entry)
164-
if not len(self._routes) == 0:
165-
asyncio.create_task(self._disable_interception())
162+
try:
163+
handler_entry.handle(route, request)
164+
finally:
165+
if not handler_entry.is_active:
166+
self._routes.remove(handler_entry)
167+
if not len(self._routes) == 0:
168+
asyncio.create_task(self._disable_interception())
166169
break
167170
route._internal_continue()
168171

playwright/_impl/_driver.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ def compute_driver_executable() -> Path:
4848

4949
def get_driver_env() -> dict:
5050
env = os.environ.copy()
51-
env["PW_CLI_TARGET_LANG"] = "python"
52-
env[
53-
"PW_CLI_TARGET_LANG_VERSION"
54-
] = f"{sys.version_info.major}.{sys.version_info.minor}"
51+
env["PW_LANG_NAME"] = "python"
52+
env["PW_LANG_NAME_VERSION"] = f"{sys.version_info.major}.{sys.version_info.minor}"
5553
env["PW_CLI_DISPLAY_VERSION"] = version
5654
return env

playwright/_impl/_fetch.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ async def body(self) -> bytes:
377377
result = await self._request._channel.send_return_as_dict(
378378
"fetchResponseBody",
379379
{
380-
"fetchUid": self._fetch_uid(),
380+
"fetchUid": self._fetch_uid,
381381
},
382382
)
383383
if result is None:
@@ -400,18 +400,19 @@ async def dispose(self) -> None:
400400
await self._request._channel.send(
401401
"disposeAPIResponse",
402402
{
403-
"fetchUid": self._fetch_uid(),
403+
"fetchUid": self._fetch_uid,
404404
},
405405
)
406406

407+
@property
407408
def _fetch_uid(self) -> str:
408409
return self._initializer["fetchUid"]
409410

410411
async def _fetch_log(self) -> List[str]:
411412
return await self._request._channel.send(
412413
"fetchLog",
413414
{
414-
"fetchUid": self._fetch_uid(),
415+
"fetchUid": self._fetch_uid,
415416
},
416417
)
417418

playwright/_impl/_frame.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -498,8 +498,10 @@ async def fill(
498498
) -> None:
499499
await self._channel.send("fill", locals_to_params(locals()))
500500

501-
def locator(self, selector: str, has_text: Union[str, Pattern] = None) -> Locator:
502-
return Locator(self, selector, has_text=has_text)
501+
def locator(
502+
self, selector: str, has_text: Union[str, Pattern] = None, has: Locator = None
503+
) -> Locator:
504+
return Locator(self, selector, has_text=has_text, has=has)
503505

504506
def frame_locator(self, selector: str) -> FrameLocator:
505507
return FrameLocator(self, selector)

playwright/_impl/_helper.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -218,16 +218,17 @@ def __init__(
218218
def matches(self, request_url: str) -> bool:
219219
return self.matcher.matches(request_url)
220220

221-
def handle(self, route: "Route", request: "Request") -> bool:
222-
try:
223-
result = cast(
224-
Callable[["Route", "Request"], Union[Coroutine, Any]], self.handler
225-
)(route, request)
226-
if inspect.iscoroutine(result):
227-
asyncio.create_task(result)
228-
finally:
229-
self._handled_count += 1
230-
return self._handled_count >= self._times
221+
def handle(self, route: "Route", request: "Request") -> None:
222+
self._handled_count += 1
223+
result = cast(
224+
Callable[["Route", "Request"], Union[Coroutine, Any]], self.handler
225+
)(route, request)
226+
if inspect.iscoroutine(result):
227+
asyncio.create_task(result)
228+
229+
@property
230+
def is_active(self) -> bool:
231+
return self._handled_count < self._times
231232

232233

233234
def is_safe_close_error(error: Exception) -> bool:

playwright/_impl/_locator.py

+25-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import json
1516
import pathlib
1617
import sys
1718
from typing import (
@@ -53,13 +54,18 @@
5354
if TYPE_CHECKING: # pragma: no cover
5455
from playwright._impl._frame import Frame
5556
from playwright._impl._js_handle import JSHandle
57+
from playwright._impl._page import Page
5658

5759
T = TypeVar("T")
5860

5961

6062
class Locator:
6163
def __init__(
62-
self, frame: "Frame", selector: str, has_text: Union[str, Pattern] = None
64+
self,
65+
frame: "Frame",
66+
selector: str,
67+
has_text: Union[str, Pattern] = None,
68+
has: "Locator" = None,
6369
) -> None:
6470
self._frame = frame
6571
self._selector = selector
@@ -75,6 +81,11 @@ def __init__(
7581
escaped = escape_with_quotes(has_text, '"')
7682
self._selector += f" >> :scope:has-text({escaped})"
7783

84+
if has:
85+
if has._frame != frame:
86+
raise Error('Inner "has" locator must belong to the same frame.')
87+
self._selector += " >> has=" + json.dumps(has._selector)
88+
7889
def __repr__(self) -> str:
7990
return f"<Locator frame={self._frame!r} selector={self._selector!r}>"
8091

@@ -96,6 +107,10 @@ async def _with_element(
96107
finally:
97108
await handle.dispose()
98109

110+
@property
111+
def page(self) -> "Page":
112+
return self._frame.page
113+
99114
async def bounding_box(self, timeout: float = None) -> Optional[FloatRect]:
100115
return await self._with_element(
101116
lambda h, _: h.bounding_box(),
@@ -184,9 +199,13 @@ def locator(
184199
self,
185200
selector: str,
186201
has_text: Union[str, Pattern] = None,
202+
has: "Locator" = None,
187203
) -> "Locator":
188204
return Locator(
189-
self._frame, f"{self._selector} >> {selector}", has_text=has_text
205+
self._frame,
206+
f"{self._selector} >> {selector}",
207+
has_text=has_text,
208+
has=has,
190209
)
191210

192211
def frame_locator(self, selector: str) -> "FrameLocator":
@@ -538,11 +557,14 @@ def __init__(self, frame: "Frame", frame_selector: str) -> None:
538557
self._dispatcher_fiber = frame._connection._dispatcher_fiber
539558
self._frame_selector = frame_selector
540559

541-
def locator(self, selector: str, has_text: Union[str, Pattern] = None) -> Locator:
560+
def locator(
561+
self, selector: str, has_text: Union[str, Pattern] = None, has: "Locator" = None
562+
) -> Locator:
542563
return Locator(
543564
self._frame,
544565
f"{self._frame_selector} >> control=enter-frame >> {selector}",
545566
has_text=has_text,
567+
has=has,
546568
)
547569

548570
def frame_locator(self, selector: str) -> "FrameLocator":

playwright/_impl/_network.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
from playwright._impl._wait_helper import WaitHelper
5252

5353
if TYPE_CHECKING: # pragma: no cover
54+
from playwright._impl._fetch import APIResponse
5455
from playwright._impl._frame import Frame
5556

5657

@@ -124,7 +125,7 @@ def post_data_json(self) -> Optional[Any]:
124125
@property
125126
def post_data_buffer(self) -> Optional[bytes]:
126127
b64_content = self._initializer.get("postData")
127-
if not b64_content:
128+
if b64_content is None:
128129
return None
129130
return base64.b64decode(b64_content)
130131

@@ -200,8 +201,25 @@ async def fulfill(
200201
body: Union[str, bytes] = None,
201202
path: Union[str, Path] = None,
202203
contentType: str = None,
204+
response: "APIResponse" = None,
203205
) -> None:
204206
params = locals_to_params(locals())
207+
if response:
208+
del params["response"]
209+
params["status"] = (
210+
params["status"] if params.get("status") else response.status
211+
)
212+
params["headers"] = (
213+
params["headers"] if params.get("headers") else response.headers
214+
)
215+
from playwright._impl._fetch import APIResponse
216+
217+
if body is None and path is None and isinstance(response, APIResponse):
218+
if response._request._connection is self._connection:
219+
params["fetchResponseUid"] = response._fetch_uid
220+
else:
221+
body = await response.body()
222+
205223
length = 0
206224
if isinstance(body, str):
207225
params["body"] = body

playwright/_impl/_page.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,13 @@ def _on_frame_detached(self, frame: Frame) -> None:
232232
def _on_route(self, route: Route, request: Request) -> None:
233233
for handler_entry in self._routes:
234234
if handler_entry.matches(request.url):
235-
if handler_entry.handle(route, request):
236-
self._routes.remove(handler_entry)
237-
if len(self._routes) == 0:
238-
asyncio.create_task(self._disable_interception())
235+
try:
236+
handler_entry.handle(route, request)
237+
finally:
238+
if not handler_entry.is_active:
239+
self._routes.remove(handler_entry)
240+
if len(self._routes) == 0:
241+
asyncio.create_task(self._disable_interception())
239242
return
240243
self._browser_context._on_route(route, request)
241244

@@ -686,8 +689,9 @@ def locator(
686689
self,
687690
selector: str,
688691
has_text: Union[str, Pattern] = None,
692+
has: "Locator" = None,
689693
) -> "Locator":
690-
return self._main_frame.locator(selector, has_text=has_text)
694+
return self._main_frame.locator(selector, has_text=has_text, has=has)
691695

692696
def frame_locator(self, selector: str) -> "FrameLocator":
693697
return self.main_frame.frame_locator(selector)

0 commit comments

Comments
 (0)