Skip to content

Commit

Permalink
chore(roll): roll to 1.31.0-beta-1676906983000 (#1775)
Browse files Browse the repository at this point in the history
  • Loading branch information
mxschmitt committed Feb 21, 2023
1 parent 405de18 commit 3ffc9a9
Show file tree
Hide file tree
Showing 25 changed files with 776 additions and 95 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 -->110.0.5481.38<!-- GEN:stop --> ||||
| Chromium <!-- GEN:chromium-version -->111.0.5563.19<!-- GEN:stop --> ||||
| WebKit <!-- GEN:webkit-version -->16.4<!-- GEN:stop --> ||||
| Firefox <!-- GEN:firefox-version -->108.0.2<!-- GEN:stop --> ||||
| Firefox <!-- GEN:firefox-version -->109.0<!-- GEN:stop --> ||||

## Documentation

Expand Down
2 changes: 1 addition & 1 deletion playwright/_impl/_api_structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class ExpectedTextValue(TypedDict, total=False):
class FrameExpectOptions(TypedDict, total=False):
expressionArg: Any
expectedText: Optional[List[ExpectedTextValue]]
expectedNumber: Optional[int]
expectedNumber: Optional[float]
expectedValue: Optional[Any]
useInnerText: Optional[bool]
isNot: bool
Expand Down
19 changes: 19 additions & 0 deletions playwright/_impl/_assertions.py
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,25 @@ async def not_to_be_focused(
__tracebackhide__ = True
await self._not.to_be_focused(timeout)

async def to_be_in_viewport(
self,
ratio: float = None,
timeout: float = None,
) -> None:
__tracebackhide__ = True
await self._expect_impl(
"to.be.in.viewport",
FrameExpectOptions(timeout=timeout, expectedNumber=ratio),
None,
"Locator expected to be in viewport",
)

async def not_to_be_in_viewport(
self, ratio: float = None, timeout: float = None
) -> None:
__tracebackhide__ = True
await self._not.to_be_in_viewport(ratio=ratio, timeout=timeout)


class APIResponseAssertions:
def __init__(self, response: APIResponse, is_not: bool = False) -> None:
Expand Down
21 changes: 12 additions & 9 deletions playwright/_impl/_browser_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,11 @@ async def _on_route(self, route: Route) -> None:
handled = await route_handler.handle(route)
finally:
if len(self._routes) == 0:
asyncio.create_task(self._disable_interception())
asyncio.create_task(
self._connection.wrap_api_call(
lambda: self._update_interception_patterns(), True
)
)
if handled:
return
await route._internal_continue(is_internal=True)
Expand Down Expand Up @@ -304,10 +308,7 @@ async def route(
times,
),
)
if len(self._routes) == 1:
await self._channel.send(
"setNetworkInterceptionEnabled", dict(enabled=True)
)
await self._update_interception_patterns()

async def unroute(
self, url: URLMatch, handler: Optional[RouteHandlerCallback] = None
Expand All @@ -318,8 +319,7 @@ async def unroute(
self._routes,
)
)
if len(self._routes) == 0:
await self._disable_interception()
await self._update_interception_patterns()

async def _record_into_har(
self,
Expand Down Expand Up @@ -360,8 +360,11 @@ async def route_from_har(
)
await router.add_context_route(self)

async def _disable_interception(self) -> None:
await self._channel.send("setNetworkInterceptionEnabled", dict(enabled=False))
async def _update_interception_patterns(self) -> None:
patterns = RouteHandler.prepare_interception_patterns(self._routes)
await self._channel.send(
"setNetworkInterceptionPatterns", {"patterns": patterns}
)

def expect_event(
self,
Expand Down
22 changes: 22 additions & 0 deletions playwright/_impl/_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,28 @@ def impl() -> None:
def will_expire(self) -> bool:
return self._handled_count + 1 >= self._times

@staticmethod
def prepare_interception_patterns(
handlers: List["RouteHandler"],
) -> List[Dict[str, str]]:
patterns = []
all = False
for handler in handlers:
if isinstance(handler.matcher.match, str):
patterns.append({"glob": handler.matcher.match})
elif isinstance(handler.matcher._regex_obj, re.Pattern):
patterns.append(
{
"regexSource": handler.matcher._regex_obj.pattern,
"regexFlags": escape_regex_flags(handler.matcher._regex_obj),
}
)
else:
all = True
if all:
return [{"glob": "**/*"}]
return patterns


def is_safe_close_error(error: Exception) -> bool:
message = str(error)
Expand Down
2 changes: 1 addition & 1 deletion playwright/_impl/_locator.py
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ async def _expect(
{
"selector": self._selector,
"expression": expression,
**options,
**({k: v for k, v in options.items() if v is not None}),
},
)
if result.get("received"):
Expand Down
63 changes: 37 additions & 26 deletions playwright/_impl/_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,11 @@ async def _actual_headers(self) -> "RawHeaders":
self._all_headers_future.set_result(RawHeaders(headers))
return await self._all_headers_future

def _target_closed_future(self) -> asyncio.Future:
if not hasattr(self.frame, "_page"):
return asyncio.Future()
return self.frame._page._closed_or_crashed_future


class Route(ChannelOwner):
def __init__(
Expand Down Expand Up @@ -348,10 +353,11 @@ async def fetch(
method: str = None,
headers: Dict[str, str] = None,
postData: Union[Any, str, bytes] = None,
maxRedirects: int = None,
) -> "APIResponse":
page = self.request.frame._page
return await page.context.request._inner_fetch(
self.request, url, method, headers, postData
self.request, url, method, headers, postData, maxRedirects=maxRedirects
)

async def fallback(
Expand Down Expand Up @@ -419,30 +425,22 @@ async def _redirected_navigation_request(self, url: str) -> None:
self._report_handled(True)

async def _race_with_page_close(self, future: Coroutine) -> None:
if hasattr(self.request.frame, "_page"):
page = self.request.frame._page
# When page closes or crashes, we catch any potential rejects from this Route.
# Note that page could be missing when routing popup's initial request that
# does not have a Page initialized just yet.
fut = asyncio.create_task(future)
# Rewrite the user's stack to the new task which runs in the background.
setattr(
fut,
"__pw_stack__",
getattr(
asyncio.current_task(self._loop), "__pw_stack__", inspect.stack()
),
)
await asyncio.wait(
[fut, page._closed_or_crashed_future],
return_when=asyncio.FIRST_COMPLETED,
)
if fut.done() and fut.exception():
raise cast(BaseException, fut.exception())
if page._closed_or_crashed_future.done():
await asyncio.gather(fut, return_exceptions=True)
else:
await future
fut = asyncio.create_task(future)
# Rewrite the user's stack to the new task which runs in the background.
setattr(
fut,
"__pw_stack__",
getattr(asyncio.current_task(self._loop), "__pw_stack__", inspect.stack()),
)
target_closed_future = self.request._target_closed_future()
await asyncio.wait(
[fut, target_closed_future],
return_when=asyncio.FIRST_COMPLETED,
)
if fut.done() and fut.exception():
raise cast(BaseException, fut.exception())
if target_closed_future.done():
await asyncio.gather(fut, return_exceptions=True)


class Response(ChannelOwner):
Expand Down Expand Up @@ -522,7 +520,20 @@ async def security_details(self) -> Optional[SecurityDetails]:
return await self._channel.send("securityDetails")

async def finished(self) -> None:
await self._finished_future
async def on_finished() -> None:
await self._request._target_closed_future()
raise Error("Target closed")

on_finished_task = asyncio.create_task(on_finished())
await asyncio.wait(
cast(
List[Union[asyncio.Task, asyncio.Future]],
[self._finished_future, on_finished_task],
),
return_when=asyncio.FIRST_COMPLETED,
)
if on_finished_task.done():
await on_finished_task

async def body(self) -> bytes:
binary = await self._channel.send("body")
Expand Down
21 changes: 12 additions & 9 deletions playwright/_impl/_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,11 @@ async def _on_route(self, route: Route) -> None:
handled = await route_handler.handle(route)
finally:
if len(self._routes) == 0:
asyncio.create_task(self._disable_interception())
asyncio.create_task(
self._connection.wrap_api_call(
lambda: self._update_interception_patterns(), True
)
)
if handled:
return
await self._browser_context._on_route(route)
Expand Down Expand Up @@ -594,10 +598,7 @@ async def route(
times,
),
)
if len(self._routes) == 1:
await self._channel.send(
"setNetworkInterceptionEnabled", dict(enabled=True)
)
await self._update_interception_patterns()

async def unroute(
self, url: URLMatch, handler: Optional[RouteHandlerCallback] = None
Expand All @@ -608,8 +609,7 @@ async def unroute(
self._routes,
)
)
if len(self._routes) == 0:
await self._disable_interception()
await self._update_interception_patterns()

async def route_from_har(
self,
Expand All @@ -629,8 +629,11 @@ async def route_from_har(
)
await router.add_page_route(self)

async def _disable_interception(self) -> None:
await self._channel.send("setNetworkInterceptionEnabled", dict(enabled=False))
async def _update_interception_patterns(self) -> None:
patterns = RouteHandler.prepare_interception_patterns(self._routes)
await self._channel.send(
"setNetworkInterceptionPatterns", {"patterns": patterns}
)

async def screenshot(
self,
Expand Down
12 changes: 10 additions & 2 deletions playwright/_impl/_str_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,13 @@ def escape_for_text_selector(


def escape_for_attribute_selector(value: str, exact: bool = None) -> str:
suffix = "" if exact else "i"
return '"' + value.replace('"', '\\"') + '"' + suffix
# TODO: this should actually be
# cssEscape(value).replace(/\\ /g, ' ')
# However, our attribute selectors do not conform to CSS parsing spec,
# so we escape them differently.
return (
'"'
+ value.replace("\\", "\\\\").replace('"', '\\"')
+ '"'
+ ("s" if exact else "i")
)
Loading

0 comments on commit 3ffc9a9

Please sign in to comment.