async def _with_element( self, task: Callable[[ElementHandle, float], Awaitable[T]], timeout: float = None, ) -> T: timeout = self._frame.page._timeout_settings.timeout(timeout) deadline = (monotonic_time() + timeout) if timeout else 0 handle = await self.element_handle(timeout=timeout) if not handle: raise Error(f"Could not resolve {self._selector} to DOM Element") try: return await task( handle, (deadline - monotonic_time()) if deadline else 0, ) finally: await handle.dispose()
async def continuation() -> Optional[Response]: event = await wait_helper.result() if "error" in event: raise Error(event["error"]) if wait_until not in self._load_states: t = deadline - monotonic_time() if t > 0: await self.wait_for_load_state(state=wait_until, timeout=t) if "newDocument" in event and "request" in event["newDocument"]: request = from_channel(event["newDocument"]["request"]) return await request.response() return None
async def wait_for_navigation( self, url: URLMatch = None, waitUntil: DocumentLoadState = None, timeout: float = None, ) -> Optional[Response]: if not waitUntil: waitUntil = "load" if timeout is None: timeout = self._page._timeout_settings.navigation_timeout() deadline = monotonic_time() + timeout wait_helper = self._setup_navigation_wait_helper(timeout) matcher = URLMatcher(url) if url else None def predicate(event: Any) -> bool: # Any failed navigation results in a rejection. if event.get("error"): return True return not matcher or matcher.matches(event["url"]) event = await wait_helper.wait_for_event( self._event_emitter, "navigated", predicate=predicate, ) if "error" in event: raise Error(event["error"]) if waitUntil not in self._load_states: t = deadline - monotonic_time() if t > 0: await self.wait_for_load_state(state=waitUntil, timeout=t) if "newDocument" in event and "request" in event["newDocument"]: request = from_channel(event["newDocument"]["request"]) return await request.response() return None
def expect_navigation( self, url: URLMatch = None, wait_until: DocumentLoadState = None, timeout: float = None, ) -> EventContextManagerImpl[Response]: if not wait_until: wait_until = "load" if timeout is None: timeout = self._page._timeout_settings.navigation_timeout() deadline = monotonic_time() + timeout wait_helper = self._setup_navigation_wait_helper("expect_navigation", timeout) to_url = f' to "{url}"' if url else "" wait_helper.log(f"waiting for navigation{to_url} until '{wait_until}'") matcher = ( URLMatcher(self._page._browser_context._options.get("baseURL"), url) if url else None ) def predicate(event: Any) -> bool: # Any failed navigation results in a rejection. if event.get("error"): return True wait_helper.log(f' navigated to "{event["url"]}"') return not matcher or matcher.matches(event["url"]) wait_helper.wait_for_event( self._event_emitter, "navigated", predicate=predicate, ) async def continuation() -> Optional[Response]: event = await wait_helper.result() if "error" in event: raise Error(event["error"]) if wait_until not in self._load_states: t = deadline - monotonic_time() if t > 0: await self._wait_for_load_state_impl(state=wait_until, timeout=t) if "newDocument" in event and "request" in event["newDocument"]: request = from_channel(event["newDocument"]["request"]) return await request.response() return None return EventContextManagerImpl(asyncio.create_task(continuation()))