Skip to content

Commit ab7502c

Browse files
authored
feat(roll): roll Playwright 1.15.0-next-1630006646000 (microsoft#871)
1 parent 5981155 commit ab7502c

14 files changed

+192
-60
lines changed

playwright/_impl/_browser_context.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
from playwright._impl._api_structures import Cookie, Geolocation, StorageState
2323
from playwright._impl._api_types import Error
24+
from playwright._impl._artifact import Artifact
2425
from playwright._impl._cdp_session import CDPSession
2526
from playwright._impl._connection import (
2627
ChannelOwner,
@@ -31,7 +32,7 @@
3132
from playwright._impl._frame import Frame
3233
from playwright._impl._helper import (
3334
RouteHandler,
34-
RouteHandlerEntry,
35+
RouteHandlerCallback,
3536
TimeoutSettings,
3637
URLMatch,
3738
URLMatcher,
@@ -68,7 +69,7 @@ def __init__(
6869
) -> None:
6970
super().__init__(parent, type, guid, initializer)
7071
self._pages: List[Page] = []
71-
self._routes: List[RouteHandlerEntry] = []
72+
self._routes: List[RouteHandler] = []
7273
self._bindings: Dict[str, Any] = {}
7374
self._timeout_settings = TimeoutSettings(None)
7475
self._browser: Optional["Browser"] = None
@@ -146,8 +147,8 @@ def _on_page(self, page: Page) -> None:
146147

147148
def _on_route(self, route: Route, request: Request) -> None:
148149
for handler_entry in self._routes:
149-
if handler_entry.matcher.matches(request.url):
150-
result = cast(Any, handler_entry.handler)(route, request)
150+
if handler_entry.matches(request.url):
151+
result = handler_entry.handle(route, request)
151152
if inspect.iscoroutine(result):
152153
asyncio.create_task(result)
153154
return
@@ -241,17 +242,20 @@ async def expose_binding(
241242
async def expose_function(self, name: str, callback: Callable) -> None:
242243
await self.expose_binding(name, lambda source, *args: callback(*args))
243244

244-
async def route(self, url: URLMatch, handler: RouteHandler) -> None:
245+
async def route(
246+
self, url: URLMatch, handler: RouteHandlerCallback, times: int = None
247+
) -> None:
245248
self._routes.insert(
246-
0, RouteHandlerEntry(URLMatcher(self._options.get("baseURL"), url), handler)
249+
0,
250+
RouteHandler(URLMatcher(self._options.get("baseURL"), url), handler, times),
247251
)
248252
if len(self._routes) == 1:
249253
await self._channel.send(
250254
"setNetworkInterceptionEnabled", dict(enabled=True)
251255
)
252256

253257
async def unroute(
254-
self, url: URLMatch, handler: Optional[RouteHandler] = None
258+
self, url: URLMatch, handler: Optional[RouteHandlerCallback] = None
255259
) -> None:
256260
self._routes = list(
257261
filter(
@@ -291,6 +295,16 @@ def _on_close(self) -> None:
291295

292296
async def close(self) -> None:
293297
try:
298+
if self._options.get("recordHar"):
299+
har = cast(
300+
Artifact, from_channel(await self._channel.send("harExport"))
301+
)
302+
if self.browser and self.browser._is_remote:
303+
har._is_remote = True
304+
await har.save_as(
305+
cast(Dict[str, str], self._options["recordHar"])["path"]
306+
)
307+
await har.delete()
294308
await self._channel.send("close")
295309
await self._closed_future
296310
except Exception as e:

playwright/_impl/_element_handle.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ async def wait_for_selector(
315315
selector: str,
316316
state: Literal["attached", "detached", "hidden", "visible"] = None,
317317
timeout: float = None,
318+
strict: bool = None,
318319
) -> Optional["ElementHandle"]:
319320
return from_nullable_channel(
320321
await self._channel.send("waitForSelector", locals_to_params(locals()))

playwright/_impl/_helper.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
TYPE_CHECKING,
2626
Any,
2727
Callable,
28+
Coroutine,
2829
Dict,
2930
List,
3031
Optional,
@@ -49,7 +50,9 @@
4950
URLMatch = Union[str, Pattern, Callable[[str], bool]]
5051
URLMatchRequest = Union[str, Pattern, Callable[["Request"], bool]]
5152
URLMatchResponse = Union[str, Pattern, Callable[["Response"], bool]]
52-
RouteHandler = Union[Callable[["Route"], Any], Callable[["Route", "Request"], Any]]
53+
RouteHandlerCallback = Union[
54+
Callable[["Route"], Any], Callable[["Route", "Request"], Any]
55+
]
5356

5457
ColorScheme = Literal["dark", "light", "no-preference"]
5558
ReducedMotion = Literal["no-preference", "reduce"]
@@ -199,10 +202,28 @@ def monotonic_time() -> int:
199202
return math.floor(time.monotonic() * 1000)
200203

201204

202-
class RouteHandlerEntry:
203-
def __init__(self, matcher: URLMatcher, handler: RouteHandler):
205+
class RouteHandler:
206+
def __init__(
207+
self,
208+
matcher: URLMatcher,
209+
handler: RouteHandlerCallback,
210+
times: Optional[int],
211+
):
204212
self.matcher = matcher
205213
self.handler = handler
214+
self._times = times
215+
self._handled_count = 0
216+
217+
def matches(self, request_url: str) -> bool:
218+
if self._times and self._handled_count >= self._times:
219+
return False
220+
return self.matcher.matches(request_url)
221+
222+
def handle(self, route: "Route", request: "Request") -> Union[Coroutine, Any]:
223+
self._handled_count += 1
224+
return cast(
225+
Callable[["Route", "Request"], Union[Coroutine, Any]], self.handler
226+
)(route, request)
206227

207228

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

playwright/_impl/_page.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
MouseButton,
5050
ReducedMotion,
5151
RouteHandler,
52-
RouteHandlerEntry,
52+
RouteHandlerCallback,
5353
TimeoutSettings,
5454
URLMatch,
5555
URLMatcher,
@@ -130,7 +130,7 @@ def __init__(
130130
self._is_closed = False
131131
self._workers: List["Worker"] = []
132132
self._bindings: Dict[str, Any] = {}
133-
self._routes: List[RouteHandlerEntry] = []
133+
self._routes: List[RouteHandler] = []
134134
self._owned_context: Optional["BrowserContext"] = None
135135
self._timeout_settings: TimeoutSettings = TimeoutSettings(
136136
self._browser_context._timeout_settings
@@ -211,8 +211,8 @@ def _on_frame_detached(self, frame: Frame) -> None:
211211

212212
def _on_route(self, route: Route, request: Request) -> None:
213213
for handler_entry in self._routes:
214-
if handler_entry.matcher.matches(request.url):
215-
result = cast(Any, handler_entry.handler)(route, request)
214+
if handler_entry.matches(request.url):
215+
result = handler_entry.handle(route, request)
216216
if inspect.iscoroutine(result):
217217
asyncio.create_task(result)
218218
return
@@ -536,11 +536,15 @@ async def add_init_script(
536536
raise Error("Either path or script parameter must be specified")
537537
await self._channel.send("addInitScript", dict(source=script))
538538

539-
async def route(self, url: URLMatch, handler: RouteHandler) -> None:
539+
async def route(
540+
self, url: URLMatch, handler: RouteHandlerCallback, times: int = None
541+
) -> None:
540542
self._routes.insert(
541543
0,
542-
RouteHandlerEntry(
543-
URLMatcher(self._browser_context._options.get("baseURL"), url), handler
544+
RouteHandler(
545+
URLMatcher(self._browser_context._options.get("baseURL"), url),
546+
handler,
547+
times,
544548
),
545549
)
546550
if len(self._routes) == 1:
@@ -549,7 +553,7 @@ async def route(self, url: URLMatch, handler: RouteHandler) -> None:
549553
)
550554

551555
async def unroute(
552-
self, url: URLMatch, handler: Optional[RouteHandler] = None
556+
self, url: URLMatch, handler: Optional[RouteHandlerCallback] = None
553557
) -> None:
554558
self._routes = list(
555559
filter(

playwright/async_api/_generated.py

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2467,7 +2467,8 @@ async def wait_for_selector(
24672467
selector: str,
24682468
*,
24692469
state: Literal["attached", "detached", "hidden", "visible"] = None,
2470-
timeout: float = None
2470+
timeout: float = None,
2471+
strict: bool = None
24712472
) -> typing.Optional["ElementHandle"]:
24722473
"""ElementHandle.wait_for_selector
24732474
@@ -2503,6 +2504,9 @@ async def wait_for_selector(
25032504
timeout : Union[float, NoneType]
25042505
Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
25052506
using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods.
2507+
strict : Union[bool, NoneType]
2508+
When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
2509+
element, the call throws an exception.
25062510
25072511
Returns
25082512
-------
@@ -2513,7 +2517,7 @@ async def wait_for_selector(
25132517
await self._async(
25142518
"element_handle.wait_for_selector",
25152519
self._impl_obj.wait_for_selector(
2516-
selector=selector, state=state, timeout=timeout
2520+
selector=selector, state=state, timeout=timeout, strict=strict
25172521
),
25182522
)
25192523
)
@@ -3339,8 +3343,8 @@ async def is_hidden(
33393343
When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
33403344
element, the call throws an exception.
33413345
timeout : Union[float, NoneType]
3342-
Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
3343-
using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods.
3346+
**DEPRECATED** This option is ignored. `frame.is_hidden()` does not wait for the element to become hidden and
3347+
returns immediately.
33443348
33453349
Returns
33463350
-------
@@ -3373,8 +3377,8 @@ async def is_visible(
33733377
When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
33743378
element, the call throws an exception.
33753379
timeout : Union[float, NoneType]
3376-
Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
3377-
using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods.
3380+
**DEPRECATED** This option is ignored. `frame.is_visible()` does not wait for the element to become visible and
3381+
returns immediately.
33783382
33793383
Returns
33803384
-------
@@ -5790,8 +5794,8 @@ async def is_hidden(
57905794
When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
57915795
element, the call throws an exception.
57925796
timeout : Union[float, NoneType]
5793-
Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
5794-
using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods.
5797+
**DEPRECATED** This option is ignored. `page.is_hidden()` does not wait for the element to become hidden and
5798+
returns immediately.
57955799
57965800
Returns
57975801
-------
@@ -5824,8 +5828,8 @@ async def is_visible(
58245828
When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
58255829
element, the call throws an exception.
58265830
timeout : Union[float, NoneType]
5827-
Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
5828-
using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods.
5831+
**DEPRECATED** This option is ignored. `page.is_visible()` does not wait for the element to become visible and
5832+
returns immediately.
58295833
58305834
Returns
58315835
-------
@@ -6865,6 +6869,8 @@ async def route(
68656869
typing.Callable[["Route"], typing.Any],
68666870
typing.Callable[["Route", "Request"], typing.Any],
68676871
],
6872+
*,
6873+
times: int = None
68686874
) -> NoneType:
68696875
"""Page.route
68706876
@@ -6873,6 +6879,9 @@ async def route(
68736879
Once routing is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted.
68746880
68756881
> NOTE: The handler will only be called for the first url if the response is a redirect.
6882+
> NOTE: `page.route()` will not intercept requests intercepted by Service Worker. See
6883+
[this](https://github.com/microsoft/playwright/issues/1090) issue. We recommend disabling Service Workers when using
6884+
request interception. Via `await context.addInitScript(() => delete window.navigator.serviceWorker);`
68766885
68776886
An example of a naive handler that aborts all image requests:
68786887
@@ -6919,13 +6928,17 @@ def handle_route(route):
69196928
[`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor.
69206929
handler : Union[Callable[[Route, Request], Any], Callable[[Route], Any]]
69216930
handler function to route the request.
6931+
times : Union[int, NoneType]
6932+
How often a route should be used. By default it will be used every time.
69226933
"""
69236934

69246935
return mapping.from_maybe_impl(
69256936
await self._async(
69266937
"page.route",
69276938
self._impl_obj.route(
6928-
url=self._wrap_handler(url), handler=self._wrap_handler(handler)
6939+
url=self._wrap_handler(url),
6940+
handler=self._wrap_handler(handler),
6941+
times=times,
69296942
),
69306943
)
69316944
)
@@ -9265,12 +9278,18 @@ async def route(
92659278
typing.Callable[["Route"], typing.Any],
92669279
typing.Callable[["Route", "Request"], typing.Any],
92679280
],
9281+
*,
9282+
times: int = None
92689283
) -> NoneType:
92699284
"""BrowserContext.route
92709285
92719286
Routing provides the capability to modify network requests that are made by any page in the browser context. Once route
92729287
is enabled, every request matching the url pattern will stall unless it's continued, fulfilled or aborted.
92739288
9289+
> NOTE: `page.route()` will not intercept requests intercepted by Service Worker. See
9290+
[this](https://github.com/microsoft/playwright/issues/1090) issue. We recommend disabling Service Workers when using
9291+
request interception. Via `await context.addInitScript(() => delete window.navigator.serviceWorker);`
9292+
92749293
An example of a naive handler that aborts all image requests:
92759294
92769295
```py
@@ -9319,13 +9338,17 @@ def handle_route(route):
93199338
[`new URL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL) constructor.
93209339
handler : Union[Callable[[Route, Request], Any], Callable[[Route], Any]]
93219340
handler function to route the request.
9341+
times : Union[int, NoneType]
9342+
How often a route should be used. By default it will be used every time.
93229343
"""
93239344

93249345
return mapping.from_maybe_impl(
93259346
await self._async(
93269347
"browser_context.route",
93279348
self._impl_obj.route(
9328-
url=self._wrap_handler(url), handler=self._wrap_handler(handler)
9349+
url=self._wrap_handler(url),
9350+
handler=self._wrap_handler(handler),
9351+
times=times,
93299352
),
93309353
)
93319354
)
@@ -9512,7 +9535,7 @@ async def new_cdp_session(
95129535
Parameters
95139536
----------
95149537
page : Union[Frame, Page]
9515-
Target to create new session for. For backwards-compatability, this parameter is named `page`, but it can be a `Page` or
9538+
Target to create new session for. For backwards-compatibility, this parameter is named `page`, but it can be a `Page` or
95169539
`Frame` type.
95179540
95189541
Returns
@@ -11559,8 +11582,8 @@ async def is_hidden(self, *, timeout: float = None) -> bool:
1155911582
Parameters
1156011583
----------
1156111584
timeout : Union[float, NoneType]
11562-
Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
11563-
using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods.
11585+
**DEPRECATED** This option is ignored. `locator.is_hidden()` does not wait for the element to become hidden and
11586+
returns immediately.
1156411587
1156511588
Returns
1156611589
-------
@@ -11581,8 +11604,8 @@ async def is_visible(self, *, timeout: float = None) -> bool:
1158111604
Parameters
1158211605
----------
1158311606
timeout : Union[float, NoneType]
11584-
Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
11585-
using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods.
11607+
**DEPRECATED** This option is ignored. `locator.is_visible()` does not wait for the element to become visible and
11608+
returns immediately.
1158611609
1158711610
Returns
1158811611
-------

0 commit comments

Comments
 (0)