|
40 | 40 | PendingWaitEvent,
|
41 | 41 | RouteHandler,
|
42 | 42 | RouteHandlerEntry,
|
43 |
| - TimeoutError, |
44 | 43 | TimeoutSettings,
|
45 | 44 | URLMatch,
|
46 | 45 | URLMatcher,
|
|
53 | 52 | from playwright.input import Keyboard, Mouse
|
54 | 53 | from playwright.js_handle import JSHandle, serialize_argument
|
55 | 54 | from playwright.network import Request, Response, Route, serialize_headers
|
| 55 | +from playwright.wait_helper import WaitHelper |
56 | 56 | from playwright.worker import Worker
|
57 | 57 |
|
58 | 58 | if sys.version_info >= (3, 8): # pragma: no cover
|
@@ -103,6 +103,7 @@ def __init__(self, scope: ConnectionScope, guid: str, initializer: Dict) -> None
|
103 | 103 | self._pending_wait_for_events: List[PendingWaitEvent] = list()
|
104 | 104 | self._routes: List[RouteHandlerEntry] = list()
|
105 | 105 | self._owned_context: Optional["BrowserContext"] = None
|
| 106 | + self._timeout_settings = TimeoutSettings(None) |
106 | 107 |
|
107 | 108 | self._channel.on(
|
108 | 109 | "bindingCall",
|
@@ -370,25 +371,27 @@ async def goto(
|
370 | 371 | self,
|
371 | 372 | url: str,
|
372 | 373 | timeout: int = None,
|
373 |
| - waitUntil: DocumentLoadState = None, |
| 374 | + waitUntil: DocumentLoadState = "load", |
374 | 375 | referer: str = None,
|
375 | 376 | ) -> Optional[Response]:
|
376 | 377 | return await self._main_frame.goto(**locals_to_params(locals()))
|
377 | 378 |
|
378 | 379 | async def reload(
|
379 |
| - self, timeout: int = None, waitUntil: DocumentLoadState = None, |
| 380 | + self, timeout: int = None, waitUntil: DocumentLoadState = "load", |
380 | 381 | ) -> Optional[Response]:
|
381 | 382 | return from_nullable_channel(
|
382 | 383 | await self._channel.send("reload", locals_to_params(locals()))
|
383 | 384 | )
|
384 | 385 |
|
385 |
| - async def waitForLoadState(self, state: str = "load", timeout: int = None) -> None: |
| 386 | + async def waitForLoadState( |
| 387 | + self, state: DocumentLoadState = "load", timeout: int = None |
| 388 | + ) -> None: |
386 | 389 | return await self._main_frame.waitForLoadState(**locals_to_params(locals()))
|
387 | 390 |
|
388 | 391 | async def waitForNavigation(
|
389 | 392 | self,
|
390 | 393 | timeout: int = None,
|
391 |
| - waitUntil: DocumentLoadState = None, |
| 394 | + waitUntil: DocumentLoadState = "load", |
392 | 395 | url: str = None, # TODO: add url, callback
|
393 | 396 | ) -> Optional[Response]:
|
394 | 397 | return await self._main_frame.waitForNavigation(**locals_to_params(locals()))
|
@@ -440,9 +443,17 @@ def my_predicate(response: Response) -> bool:
|
440 | 443 | async def waitForEvent(
|
441 | 444 | self, event: str, predicate: Callable[[Any], bool] = None, timeout: int = None
|
442 | 445 | ) -> Any:
|
443 |
| - return await wait_for_event( |
444 |
| - self, self._timeout_settings, event, predicate=predicate, timeout=timeout |
| 446 | + if timeout is None: |
| 447 | + timeout = self._timeout_settings.timeout() |
| 448 | + wait_helper = WaitHelper() |
| 449 | + wait_helper.reject_on_timeout( |
| 450 | + timeout, f'Timeout while waiting for event "${event}"' |
445 | 451 | )
|
| 452 | + if event != Page.Events.Crash: |
| 453 | + wait_helper.reject_on_event(self, Page.Events.Crash, Error("Page crashed")) |
| 454 | + if event != Page.Events.Close: |
| 455 | + wait_helper.reject_on_event(self, Page.Events.Close, Error("Page closed")) |
| 456 | + return await wait_helper.wait_for_event(self, event, predicate) |
446 | 457 |
|
447 | 458 | async def goBack(
|
448 | 459 | self, timeout: int = None, waitUntil: DocumentLoadState = None,
|
@@ -480,20 +491,19 @@ async def addInitScript(self, source: str = None, path: str = None) -> None:
|
480 | 491 | raise Error("Either path or source parameter must be specified")
|
481 | 492 | await self._channel.send("addInitScript", dict(source=source))
|
482 | 493 |
|
483 |
| - async def route(self, match: URLMatch, handler: RouteHandler) -> None: |
484 |
| - self._routes.append(RouteHandlerEntry(URLMatcher(match), handler)) |
| 494 | + async def route(self, url: URLMatch, handler: RouteHandler) -> None: |
| 495 | + self._routes.append(RouteHandlerEntry(URLMatcher(url), handler)) |
485 | 496 | if len(self._routes) == 1:
|
486 | 497 | await self._channel.send(
|
487 | 498 | "setNetworkInterceptionEnabled", dict(enabled=True)
|
488 | 499 | )
|
489 | 500 |
|
490 | 501 | async def unroute(
|
491 |
| - self, match: URLMatch, handler: Optional[RouteHandler] = None |
| 502 | + self, url: URLMatch, handler: Optional[RouteHandler] = None |
492 | 503 | ) -> None:
|
493 | 504 | self._routes = list(
|
494 | 505 | filter(
|
495 |
| - lambda r: r.matcher.match != match |
496 |
| - or (handler and r.handler != handler), |
| 506 | + lambda r: r.matcher.match != url or (handler and r.handler != handler), |
497 | 507 | self._routes,
|
498 | 508 | )
|
499 | 509 | )
|
@@ -713,39 +723,3 @@ async def call(self, func: FunctionWithSource) -> None:
|
713 | 723 | asyncio.ensure_future(
|
714 | 724 | self._channel.send("reject", dict(error=serialize_error(e, tb)))
|
715 | 725 | )
|
716 |
| - |
717 |
| - |
718 |
| -async def wait_for_event( |
719 |
| - target: Union[Page, "BrowserContext"], |
720 |
| - timeout_settings: TimeoutSettings, |
721 |
| - event: str, |
722 |
| - predicate: Callable[[Any], bool] = None, |
723 |
| - timeout: int = None, |
724 |
| -) -> Any: |
725 |
| - if timeout is None: |
726 |
| - timeout = timeout_settings.timeout() |
727 |
| - if timeout == 0: |
728 |
| - timeout = 3600 * 24 * 7 * 30 * 365 |
729 |
| - timeout_future: asyncio.Future = asyncio.ensure_future( |
730 |
| - asyncio.sleep(timeout / 1000) |
731 |
| - ) |
732 |
| - |
733 |
| - future = target._scope._loop.create_future() |
734 |
| - |
735 |
| - def listener(e: Any = None) -> None: |
736 |
| - if not predicate or predicate(e): |
737 |
| - future.set_result(e) |
738 |
| - |
739 |
| - target.on(event, listener) |
740 |
| - |
741 |
| - pending_event = PendingWaitEvent(event, future, timeout_future) |
742 |
| - target._pending_wait_for_events.append(pending_event) |
743 |
| - done, _ = await asyncio.wait( |
744 |
| - {timeout_future, future}, return_when=asyncio.FIRST_COMPLETED |
745 |
| - ) |
746 |
| - target.remove_listener(event, listener) |
747 |
| - target._pending_wait_for_events.remove(pending_event) |
748 |
| - if future in done: |
749 |
| - timeout_future.cancel() |
750 |
| - return future.result() |
751 |
| - raise TimeoutError("Timeout exceeded") |
0 commit comments