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, scope: ConnectionScope, guid: str, initializer: Dict) -> None: super().__init__(scope, guid, initializer, True) self._pages: List[Page] = list() self._routes: List[RouteHandlerEntry] = list() self._bindings: Dict[str, Any] = dict() self._pending_wait_for_events: List[PendingWaitEvent] = list() self._timeout_settings = TimeoutSettings(None) self._browser: Optional["Browser"] = None self._owner_page: Optional[Page] = None self._is_closed_or_closing = False for channel in initializer["pages"]: page = from_channel(channel) self._pages.append(page) page._set_browser_context(self) self._channel.on( "bindingCall", lambda binding_call: self._on_binding(from_channel(binding_call)), ) self._channel.on("close", lambda _: self._on_close()) self._channel.on("page", lambda page: self._on_page(from_channel(page))) self._channel.on( "route", lambda event: self._on_route(from_channel(event.get("route")), from_channel(event.get("request"))), )
def __init__(self, scope: ConnectionScope, guid: str, initializer: Dict) -> None: super().__init__(scope, guid, initializer) self.chromium: BrowserType = from_channel(initializer["chromium"]) self.firefox: BrowserType = from_channel(initializer["firefox"]) self.webkit: BrowserType = from_channel(initializer["webkit"]) self.devices = initializer["deviceDescriptors"] self.browser_types: Dict[str, BrowserType] = dict(chromium=self.chromium, webkit=self.webkit, firefox=self.firefox)
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 connect(self, wsEndpoint: str, slowMo: int = None, timeout: int = None) -> Browser: return from_channel(await self._channel.send("connect", locals_to_params(locals())))
async def launchServer( self, executablePath: str = None, args: List[str] = None, ignoreDefaultArgs: List[str] = None, handleSIGINT: bool = None, handleSIGTERM: bool = None, handleSIGHUP: bool = None, timeout: int = None, env: Dict = None, headless: bool = None, devtools: bool = None, proxy: Dict = None, downloadsPath: str = None, port: int = None, chromiumSandbox: bool = None, ) -> Browser: try: return from_channel( await self._channel.send("launchServer", locals_to_params(locals())) ) 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: str = None, content: str = None) -> ElementHandle: return from_channel(await self._channel.send("addStyleTag", locals_to_params(locals())))
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, ) -> BrowserContext: params = locals_to_params(locals()) if viewport == 0: del params["viewport"] params["noDefaultViewport"] = True if extraHTTPHeaders: params["extraHTTPHeaders"] = serialize_headers(extraHTTPHeaders) channel = await self._channel.send("newContext", params) context = from_channel(channel) self._contexts.append(context) context._browser = self return context
async def launch( self, executablePath: str = 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: ProxyServer = None, downloadsPath: str = None, slowMo: int = None, chromiumSandbox: 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 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 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: ProxyServer = None, downloadsPath: Union[str, Path] = None, slowMo: int = None, viewport: IntSize = 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, chromiumSandbox: bool = None, videosPath: str = None, videoSize: IntSize = None, recordHar: RecordHarOptions = None, ) -> BrowserContext: userDataDir = str(Path(userDataDir)) params = locals_to_params(locals()) 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 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 addScriptTag( self, url: str = None, path: str = None, content: str = None, type: str = None, ) -> ElementHandle: params = locals_to_params(locals()) if path: with open(path, "r") as file: params["content"] = file.read() + "\n//# sourceURL=" + path del params["path"] return from_channel(await self._channel.send("addScriptTag", params))
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))
async def evaluateHandle(self, expression: str, arg: Any = None, force_expr: bool = False) -> JSHandle: if not is_function_body(expression): force_expr = True return from_channel(await self._channel.send( "evaluateExpressionHandle", dict( expression=expression, isFunction=not (force_expr), arg=serialize_argument(arg), ), ))
async def call(self, func: FunctionWithSource) -> None: try: frame = from_channel(self._initializer["frame"]) source = dict(context=frame._page.context, page=frame._page, frame=frame) result = func(source, *self._initializer["args"]) if isinstance(result, asyncio.Future): result = await result await self._channel.send("resolve", dict(result=result)) except Exception as e: tb = sys.exc_info()[2] asyncio.ensure_future( 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._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 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: SetStorageState = 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 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 launchPersistentContext( self, userDataDir: str, executablePath: str = None, args: List[str] = None, ignoreDefaultArgs: List[str] = None, handleSIGINT: bool = None, handleSIGTERM: bool = None, handleSIGHUP: bool = None, timeout: int = None, env: Dict = None, headless: bool = None, devtools: bool = None, proxy: Dict = None, downloadsPath: str = None, slowMo: int = None, viewport: Dict = None, ignoreHTTPSErrors: bool = None, javaScriptEnabled: bool = None, bypassCSP: bool = None, userAgent: str = None, locale: str = None, timezoneId: str = None, geolocation: Dict = None, permissions: List[str] = None, extraHTTPHeaders: Dict[str, str] = None, offline: bool = None, httpCredentials: Dict = None, deviceScaleFactor: int = None, isMobile: bool = None, hasTouch: bool = None, colorScheme: ColorScheme = None, acceptDownloads: bool = None, ) -> BrowserContext: try: return from_channel( await self._channel.send( "launchPersistentContext", locals_to_params(locals()) ) ) 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 waitForNavigation( self, timeout: int = None, waitUntil: DocumentLoadState = "load", url: URLMatch = None, ) -> Optional[Response]: wait_helper = self._setup_navigation_wait_helper(timeout) matcher = URLMatcher(url) if url else None event = await wait_helper.wait_for_event( self._event_emitter, "navigated", lambda event: not matcher or matcher.matches(event["url"]), ) if "newDocument" in event and "request" in event["newDocument"]: request = from_channel(event["newDocument"]["request"]) return await request.response() if "error" in event: raise Error(event["error"]) return None
async def launchServer( self, executablePath: str = None, args: List[str] = None, ignoreDefaultArgs: List[str] = None, handleSIGINT: bool = None, handleSIGTERM: bool = None, handleSIGHUP: bool = None, timeout: int = None, env: Dict = None, headless: bool = None, devtools: bool = None, proxy: Dict = None, downloadsPath: str = None, port: int = None, ) -> Browser: return from_channel( await self._channel.send("launchServer", locals_to_params(locals())) )
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 frameElement(self) -> ElementHandle: return from_channel(await self._channel.send("frameElement"))
def frame(self) -> "Frame": return from_channel(self._initializer["frame"])
def request(self) -> Request: return from_channel(self._initializer["request"])
async def newPage(self) -> Page: if self._owner_page: raise Error("Please use browser.newContext()") return from_channel(await self._channel.send("newPage"))
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._main_frame: Frame = from_channel(initializer["mainFrame"]) self._main_frame._page = self self._frames = [self._main_frame] self._viewport_size = initializer.get("viewportSize") 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._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["failureText"] ), ) self._channel.on( "requestFinished", lambda params: self.emit( Page.Events.RequestFinished, from_channel(params["request"]) ), ) 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( "worker", lambda params: self._on_worker(from_channel(params["worker"])) )
async def getProperties(self) -> Dict[str, "JSHandle"]: map = dict() for property in await self._channel.send("getPropertyList"): map[property["name"]] = from_channel(property["value"]) return map