def __init__(self, parent: ChannelOwner, type: str, guid: str, initializer: Dict) -> None: super().__init__(parent, type, guid, initializer) self._pages: List[Page] = [] self._routes: List[RouteHandlerEntry] = [] self._bindings: Dict[str, Any] = {} self._pending_wait_for_events: List[PendingWaitEvent] = [] self._timeout_settings = TimeoutSettings(None) self._browser: Optional["Browser"] = None self._owner_page: Optional[Page] = None self._is_closed_or_closing = False self._options: Dict[str, Any] = {} self._channel.on( "bindingCall", lambda params: self._on_binding(from_channel(params["binding"])), ) self._channel.on("close", lambda _: self._on_close()) self._channel.on( "page", lambda params: self._on_page(from_channel(params["page"]))) self._channel.on( "route", lambda params: self._on_route(from_channel(params.get("route")), from_channel(params.get("request"))), )
def __init__(self, parent: ChannelOwner, type: str, guid: str, initializer: Dict) -> None: super().__init__(parent, type, guid, initializer) self.chromium = from_channel(initializer["chromium"]) self.firefox = from_channel(initializer["firefox"]) self.webkit = from_channel(initializer["webkit"]) self.selectors = from_channel(initializer["selectors"]) self.devices = { device["name"]: device["descriptor"] for device in initializer["deviceDescriptors"] }
async def launch( self, executablePath: Union[str, Path] = None, args: List[str] = None, ignoreDefaultArgs: Union[bool, List[str]] = None, handleSIGINT: bool = None, handleSIGTERM: bool = None, handleSIGHUP: bool = None, timeout: int = None, env: Env = None, headless: bool = None, devtools: bool = None, proxy: ProxySettings = None, downloadsPath: Union[str, Path] = None, slowMo: int = None, chromiumSandbox: bool = None, firefoxUserPrefs: Dict[str, Union[str, int, bool]] = None, ) -> Browser: params = locals_to_params(locals()) normalize_launch_params(params) try: return from_channel(await self._channel.send("launch", params)) except Exception as e: if f"{self.name}-" in str(e): raise not_installed_error( f'"{self.name}" browser was not found.') raise e
async def call(self, func: Callable) -> None: try: frame = from_channel(self._initializer["frame"]) source = dict(context=frame._page.context, page=frame._page, frame=frame) if self._initializer.get("handle"): result = func(source, from_channel(self._initializer["handle"])) else: func_args = list(map(parse_result, self._initializer["args"])) result = func(source, *func_args) if asyncio.isfuture(result): result = await result await self._channel.send("resolve", dict(result=serialize_argument(result))) except Exception as e: tb = sys.exc_info()[2] asyncio.create_task( self._channel.send("reject", dict(error=serialize_error(e, tb))) )
def __init__(self, parent: ChannelOwner, type: str, guid: str, initializer: Dict) -> None: super().__init__(parent, type, guid, initializer) self._background_pages: Set[Page] = set() self._service_workers: Set[Worker] = set() self._channel.on( "crBackgroundPage", lambda params: self._on_background_page( from_channel(params["page"])), ) self._channel.on( "crServiceWorker", lambda params: self._on_service_worker( from_channel(params["worker"])), )
async def launchPersistentContext( self, userDataDir: Union[str, Path], executablePath: Union[str, Path] = None, args: List[str] = None, ignoreDefaultArgs: Union[bool, List[str]] = None, handleSIGINT: bool = None, handleSIGTERM: bool = None, handleSIGHUP: bool = None, timeout: int = None, env: Env = None, headless: bool = None, devtools: bool = None, proxy: ProxySettings = None, downloadsPath: Union[str, Path] = None, slowMo: int = None, viewport: Union[Tuple[int, int], Literal[0]] = None, ignoreHTTPSErrors: bool = None, javaScriptEnabled: bool = None, bypassCSP: bool = None, userAgent: str = None, locale: str = None, timezoneId: str = None, geolocation: Geolocation = None, permissions: List[str] = None, extraHTTPHeaders: Dict[str, str] = None, offline: bool = None, httpCredentials: HttpCredentials = None, deviceScaleFactor: int = None, isMobile: bool = None, hasTouch: bool = None, colorScheme: ColorScheme = None, acceptDownloads: bool = None, chromiumSandbox: bool = None, recordHar: RecordHarOptions = None, recordVideo: RecordVideoOptions = None, ) -> BrowserContext: userDataDir = str(Path(userDataDir)) params = locals_to_params(locals()) if viewport == 0: del params["viewport"] params["noDefaultViewport"] = True if extraHTTPHeaders: params["extraHTTPHeaders"] = serialize_headers(extraHTTPHeaders) normalize_launch_params(params) try: context = from_channel(await self._channel.send( "launchPersistentContext", params)) context._options = params return context except Exception as e: if f"{self.name}-" in str(e): raise not_installed_error( f'"{self.name}" browser was not found.') raise e
async def addStyleTag(self, url: str = None, path: Union[str, Path] = None, content: str = None) -> ElementHandle: params = locals_to_params(locals()) if path: with open(path, "r") as file: params["content"] = (file.read() + "\n/*# sourceURL=" + str(Path(path)) + "*/") del params["path"] return from_channel(await self._channel.send("addStyleTag", params))
async def evaluateHandle(self, expression: str, arg: Serializable = None, force_expr: bool = None) -> JSHandle: return from_channel(await self._channel.send( "evaluateExpressionHandle", dict( expression=expression, isFunction=not (force_expr), arg=serialize_argument(arg), ), ))
async def newContext( self, viewport: Union[IntSize, Literal[0]] = None, ignoreHTTPSErrors: bool = None, javaScriptEnabled: bool = None, bypassCSP: bool = None, userAgent: str = None, locale: str = None, timezoneId: str = None, geolocation: Geolocation = None, permissions: List[str] = None, extraHTTPHeaders: Dict[str, str] = None, offline: bool = None, httpCredentials: Credentials = None, deviceScaleFactor: int = None, isMobile: bool = None, hasTouch: bool = None, colorScheme: ColorScheme = None, acceptDownloads: bool = None, defaultBrowserType: str = None, proxy: ProxyServer = None, videosPath: str = None, videoSize: IntSize = None, recordHar: RecordHarOptions = None, recordVideo: RecordVideoOptions = None, storageState: Union[StorageState, str, Path] = None, ) -> BrowserContext: params = locals_to_params(locals()) # Python is strict in which variables gets passed to methods. We get this # value from the device descriptors, thats why we have to strip it out. if defaultBrowserType in params: del params["defaultBrowserType"] if storageState: if not isinstance(storageState, dict): with open(storageState, "r") as f: params["storageState"] = json.load(f) if viewport == 0: del params["viewport"] params["noDefaultViewport"] = True if extraHTTPHeaders: params["extraHTTPHeaders"] = serialize_headers(extraHTTPHeaders) if not recordVideo and videosPath: params["recordVideo"] = {"dir": videosPath} if videoSize: params["recordVideo"]["size"] = videoSize channel = await self._channel.send("newContext", params) context = from_channel(channel) self._contexts.append(context) context._browser = self context._options = params return context
async def waitForFunction( self, expression: str, arg: Serializable = None, force_expr: bool = None, timeout: int = None, polling: Union[int, Literal["raf"]] = None, ) -> JSHandle: if not is_function_body(expression): force_expr = True params = locals_to_params(locals()) params["isFunction"] = not (force_expr) params["arg"] = serialize_argument(arg) return from_channel(await self._channel.send("waitForFunction", params))
def __init__( self, parent: ChannelOwner, type: str, guid: str, initializer: Dict ) -> None: super().__init__(parent, type, guid, initializer) self._request: Request = from_channel(self._initializer["request"]) timing = self._initializer["timing"] self._request._timing["startTime"] = timing["startTime"] self._request._timing["domainLookupStart"] = timing["domainLookupStart"] self._request._timing["domainLookupEnd"] = timing["domainLookupEnd"] self._request._timing["connectStart"] = timing["connectStart"] self._request._timing["secureConnectionStart"] = timing["secureConnectionStart"] self._request._timing["connectEnd"] = timing["connectEnd"] self._request._timing["requestStart"] = timing["requestStart"] self._request._timing["responseStart"] = timing["responseStart"] self._request._headers = parse_headers(self._initializer["requestHeaders"])
async def waitForNavigation( self, url: URLMatch = None, waitUntil: DocumentLoadState = None, timeout: int = 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: timeout = deadline - monotonic_time() if timeout > 0: await self.waitForLoadState(state=waitUntil, timeout=timeout) if "newDocument" in event and "request" in event["newDocument"]: request = from_channel(event["newDocument"]["request"]) return await request.response() return None
async def newPage(self) -> Page: if self._owner_page: raise Error("Please use browser.newContext()") return from_channel(await self._channel.send("newPage"))
def request(self) -> Request: return from_channel(self._initializer["request"])
def frame(self) -> "Frame": return from_channel(self._initializer["frame"])
async def frameElement(self) -> ElementHandle: return from_channel(await self._channel.send("frameElement"))
async def newCDPSession(self, page: Page) -> CDPSession: return from_channel(await self._channel.send("crNewCDPSession", {"page": page._channel}))
def __init__(self, parent: ChannelOwner, type: str, guid: str, initializer: Dict) -> None: super().__init__(parent, type, guid, initializer) self.accessibility = Accessibility(self._channel) self.keyboard = Keyboard(self._channel) self.mouse = Mouse(self._channel) self.touchscreen = Touchscreen(self._channel) self._main_frame: Frame = from_channel(initializer["mainFrame"]) self._main_frame._page = self self._frames = [self._main_frame] vs = initializer.get("viewportSize") self._viewport_size: Optional[Tuple[int, int]] = ((vs["width"], vs["height"]) if vs else None) self._is_closed = False self._workers: List["Worker"] = [] self._bindings: Dict[str, Any] = {} self._pending_wait_for_events: List[PendingWaitEvent] = [] self._routes: List[RouteHandlerEntry] = [] self._owned_context: Optional["BrowserContext"] = None self._timeout_settings: TimeoutSettings = TimeoutSettings(None) self._video: Optional[Video] = None self._channel.on( "bindingCall", lambda params: self._on_binding(from_channel(params["binding"])), ) self._channel.on("close", lambda _: self._on_close()) self._channel.on( "console", lambda params: self.emit(Page.Events.Console, from_channel(params["message"])), ) self._channel.on("crash", lambda _: self._on_crash()) self._channel.on( "dialog", lambda params: self.emit(Page.Events.Dialog, from_channel(params["dialog"])), ) self._channel.on("domcontentloaded", lambda _: self.emit(Page.Events.DOMContentLoaded)) self._channel.on( "download", lambda params: self.emit(Page.Events.Download, from_channel(params["download"])), ) self._channel.on( "fileChooser", lambda params: self.emit( Page.Events.FileChooser, FileChooser(self, from_channel(params["element"]), params[ "isMultiple"]), ), ) self._channel.on( "frameAttached", lambda params: self._on_frame_attached( from_channel(params["frame"])), ) self._channel.on( "frameDetached", lambda params: self._on_frame_detached( from_channel(params["frame"])), ) self._channel.on("load", lambda _: self.emit(Page.Events.Load)) self._channel.on( "pageError", lambda params: self.emit(Page.Events.PageError, parse_error(params["error"]["error"])), ) self._channel.on( "popup", lambda params: self.emit(Page.Events.Popup, from_channel(params["page"])), ) self._channel.on( "request", lambda params: self.emit(Page.Events.Request, from_channel(params["request"])), ) self._channel.on( "requestFailed", lambda params: self._on_request_failed( from_channel(params["request"]), params["responseEndTiming"], params["failureText"], ), ) self._channel.on( "requestFinished", lambda params: self._on_request_finished( from_channel(params["request"]), params["responseEndTiming"]), ) self._channel.on( "response", lambda params: self.emit(Page.Events.Response, from_channel(params["response"])), ) self._channel.on( "route", lambda params: self._on_route(from_channel(params["route"]), from_channel(params["request"])), ) self._channel.on( "video", lambda params: cast(Video, self.video)._set_relative_path(params[ "relativePath"]), ) self._channel.on( "webSocket", lambda params: self.emit(Page.Events.WebSocket, from_channel(params["webSocket"])), ) self._channel.on( "worker", lambda params: self._on_worker(from_channel(params["worker"])))
async def getProperties(self) -> Dict[str, "JSHandle"]: return { prop["name"]: from_channel(prop["value"]) for prop in await self._channel.send("getPropertyList") }
async def getProperty(self, propertyName: str) -> "JSHandle": return from_channel(await self._channel.send("getProperty", dict(name=propertyName)))