From 8ae573199331bb00331c1801977cf367964d6880 Mon Sep 17 00:00:00 2001 From: kaliiiiiiiiii Date: Mon, 15 Apr 2024 01:40:01 +0200 Subject: [PATCH] - add functions to get pid from debugger-address - use that for selenium --- cdp_patches/input/browsers.py | 45 +++++++++++++++++++++++++++++------ requirements.txt | 2 ++ setup.cfg | 2 ++ 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/cdp_patches/input/browsers.py b/cdp_patches/input/browsers.py index e8483b3..e5cc906 100644 --- a/cdp_patches/input/browsers.py +++ b/cdp_patches/input/browsers.py @@ -1,4 +1,7 @@ import time +import json +import requests +from websockets.sync import client from contextlib import suppress from typing import Dict, List, Type, TypedDict, Union @@ -32,7 +35,8 @@ DriverlessAsyncChrome: Type["DriverlessAsyncChrome"] = "DriverlessAsyncChrome" # type: ignore[no-redef] DriverlessSyncChrome: Type["DriverlessSyncChrome"] = "DriverlessSyncChrome" # type: ignore[no-redef] -all_browsers = Union[AsyncContext, AsyncBrowser, SyncContext, SyncBrowser, BotrightContext, SeleniumChrome, DriverlessAsyncChrome, DriverlessSyncChrome] +all_browsers = Union[ + AsyncContext, AsyncBrowser, SyncContext, SyncBrowser, BotrightContext, SeleniumChrome, DriverlessAsyncChrome, DriverlessSyncChrome] sync_browsers = Union[SeleniumChrome, SyncContext, SyncBrowser, DriverlessSyncChrome] async_browsers = Union[AsyncContext, AsyncBrowser, BotrightContext, DriverlessAsyncChrome] @@ -57,14 +61,35 @@ def get_main_browser(self) -> InternalProcessInfo: raise ValueError("No browser process found.") +def process_info_from_ws(ws_url: str) -> dict: + with client.connect(ws_url) as websocket: + websocket.send(json.dumps({"id": 1, "method": "SystemInfo.getProcessInfo"})) + for message in websocket: + data = json.loads(message) + if data.get("id") == 1: + return data["result"] + + +def get_ws_url_from_url(url: str, timeout:float=30) -> str: + if len(url) < 7 or url[:7] != "http://": + url = "http://" + url + "/json/version" + try: + data = requests.get(url, timeout=timeout).json() + except requests.exceptions.Timeout: + raise TimeoutError(f"Couldn't connect to browser within {timeout} seconds") + return data["webSocketDebuggerUrl"] + + # Browser PID # Selenium & Selenium Driverless def get_sync_selenium_browser_pid(driver: Union[SeleniumChrome, DriverlessSyncChrome]) -> int: if isinstance(driver, DriverlessSyncChrome): cdp_system_info = driver.base_target.execute_cdp_cmd(cmd="SystemInfo.getProcessInfo") + elif isinstance(driver, SeleniumChrome): + ws_url = get_ws_url_from_url(driver.capabilities['goog:chromeOptions']['debuggerAddress']) + cdp_system_info = process_info_from_ws(ws_url) else: - cdp_system_info = driver.execute_cdp_cmd(cmd="SystemInfo.getProcessInfo", cmd_args={}) - + raise ValueError("Invalid browser type.") process_info = CDPProcessInfo(cdp_system_info) browser_info = process_info.get_main_browser() return browser_info["id"] @@ -173,7 +198,9 @@ def get_sync_playwright_scale_factor(browser: Union[SyncContext, SyncBrowser]) - page_frame_tree = cdp_session.send("Page.getFrameTree") page_id = page_frame_tree["frameTree"]["frame"]["id"] - isolated_world = cdp_session.send("Page.createIsolatedWorld", {"frameId": page_id, "grantUniveralAccess": True, "worldName": "Shimmy shimmy yay, shimmy yay, shimmy ya"}) + isolated_world = cdp_session.send("Page.createIsolatedWorld", + {"frameId": page_id, "grantUniveralAccess": True, + "worldName": "Shimmy shimmy yay, shimmy yay, shimmy ya"}) isolated_exec_id = isolated_world["executionContextId"] break except SyncError as e: @@ -187,7 +214,8 @@ def get_sync_playwright_scale_factor(browser: Union[SyncContext, SyncBrowser]) - time2 = time.perf_counter() while (time.perf_counter() - time2) <= 10: try: - scale_factor_eval = cdp_session.send("Runtime.evaluate", {"expression": "window.devicePixelRatio", "contextId": isolated_exec_id}) + scale_factor_eval = cdp_session.send("Runtime.evaluate", {"expression": "window.devicePixelRatio", + "contextId": isolated_exec_id}) scale_factor: int = scale_factor_eval["result"]["value"] break except SyncError as e: @@ -235,7 +263,9 @@ async def get_async_playwright_scale_factor(browser: Union[AsyncContext, AsyncBr page_frame_tree = await cdp_session.send("Page.getFrameTree") page_id = page_frame_tree["frameTree"]["frame"]["id"] - isolated_world = await cdp_session.send("Page.createIsolatedWorld", {"frameId": page_id, "grantUniveralAccess": True, "worldName": "Shimmy shimmy yay, shimmy yay, shimmy ya"}) + isolated_world = await cdp_session.send("Page.createIsolatedWorld", + {"frameId": page_id, "grantUniveralAccess": True, + "worldName": "Shimmy shimmy yay, shimmy yay, shimmy ya"}) isolated_exec_id = isolated_world["executionContextId"] break except AsyncError as e: @@ -249,7 +279,8 @@ async def get_async_playwright_scale_factor(browser: Union[AsyncContext, AsyncBr time2 = time.perf_counter() while (time.perf_counter() - time2) <= 10: try: - scale_factor_eval = await cdp_session.send("Runtime.evaluate", {"expression": "window.devicePixelRatio", "contextId": isolated_exec_id}) + scale_factor_eval = await cdp_session.send("Runtime.evaluate", {"expression": "window.devicePixelRatio", + "contextId": isolated_exec_id}) scale_factor: int = scale_factor_eval["result"]["value"] break except AsyncError as e: diff --git a/requirements.txt b/requirements.txt index b5381cf..fe160da 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ numpy==1.26.4 pywinauto==0.6.8 +requests +websockets python-xlib==0.33 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index c53b6a6..eb55b0d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,6 +25,8 @@ python_requires = >=3.8 packages = find: install_requires = numpy + websockets + requests pywinauto; platform_system=='Windows' python-xlib; platform_system=='Linux'