diff --git a/README.md b/README.md index 3705536..5c5a2b7 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ pip install cdp-patches[automation_linting] ### Concept: Input Domain Leaks Bypass CDP Leaks in [Input](https://chromedevtools.github.io/devtools-protocol/tot/Input/) domains +[![Brotector Banner](https://github.com/Kaliiiiiiiiii-Vinyzu/CDP-Patches/assets/50874994/fdbe831d-cb39-479d-ba0a-fea7f29fe90a)](https://github.com/kaliiiiiiiiii/brotector) + For an interaction event `e`, the page coordinates won't ever equal the screen coordinates, unless Chrome is in fullscreen. However, all `CDP` input commands just set it the same by default (see [crbug#1477537](https://bugs.chromium.org/p/chromium/issues/detail?id=1477537)). ```js diff --git a/cdp_patches/input/async_input.py b/cdp_patches/input/async_input.py index db510f5..2b921ae 100644 --- a/cdp_patches/input/async_input.py +++ b/cdp_patches/input/async_input.py @@ -51,7 +51,7 @@ class AsyncInput: def __init__( self, pid: Optional[int] = None, browser: Optional[async_browsers] = None, scale_factor: Optional[float] = 1.0, emulate_behaviour: Optional[bool] = True, window_timeout: Optional[float] = 30.0 ) -> None: - if platform.system() not in ('Windows', 'Linux'): + if platform.system() not in ("Windows", "Linux"): raise SystemError("Unknown system (You´re probably using MacOS, which is currently not supported).") self.pid = pid diff --git a/cdp_patches/input/os_base/windows.py b/cdp_patches/input/os_base/windows.py index 84ffacc..cda7650 100644 --- a/cdp_patches/input/os_base/windows.py +++ b/cdp_patches/input/os_base/windows.py @@ -2,7 +2,7 @@ import ctypes import re import warnings -from typing import Literal, Union, List +from typing import List, Literal, Union from pywinauto import application, timings from pywinauto.application import WindowSpecification @@ -24,7 +24,7 @@ warnings.filterwarnings("ignore", category=UserWarning, message="32-bit application should be automated using 32-bit Python (you use 64-bit Python)") -def get_top_window(app:application.Application, windows=List[Union[WindowSpecification, HwndWrapper]]) -> WindowSpecification: +def get_top_window(app: application.Application, windows=List[Union[WindowSpecification, HwndWrapper]]) -> WindowSpecification: if windows is None: windows = app # win32_app.top_window(), but without timeout diff --git a/cdp_patches/input/sync_input.py b/cdp_patches/input/sync_input.py index 7b396ba..ef5645d 100644 --- a/cdp_patches/input/sync_input.py +++ b/cdp_patches/input/sync_input.py @@ -50,7 +50,7 @@ class SyncInput: def __init__( self, pid: Optional[int] = None, browser: Optional[sync_browsers] = None, scale_factor: Optional[float] = 1.0, emulate_behaviour: Optional[bool] = True, window_timeout: Optional[float] = 30.0 ) -> None: - if platform.system() not in ('Windows', 'Linux'): + if platform.system() not in ("Windows", "Linux"): raise SystemError("Unknown system (You´re probably using MacOS, which is currently not supported).") self._scale_factor = scale_factor or self._scale_factor diff --git a/tests/__init__.py b/tests/__init__.py index e69de29..75bf67e 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1,19 @@ +from selenium_driverless import webdriver +from selenium_driverless.types.by import By +from cdp_patches.input import AsyncInput +import asyncio + + +async def main(): + options = webdriver.ChromeOptions() + async with webdriver.Chrome(options=options) as driver: + async_input = await AsyncInput(browser=driver) + await driver.get('https://kaliiiiiiiiii.github.io/brotector/', wait_load=True) + locator = await driver.find_element(By.XPATH, '/html/body/div/h1') + x, y = await locator.mid_location() + # Click Coords => Click Button + await async_input.click("left", x, y) + await driver.sleep(1000000) + + +asyncio.run(main()) diff --git a/tests/test_async_driverless.py b/tests/test_async_driverless.py index 4dcf423..081d05d 100644 --- a/tests/test_async_driverless.py +++ b/tests/test_async_driverless.py @@ -12,17 +12,10 @@ async def get_locator_pos(locator: WebElement): - location = await locator.location - size = await locator.size - assert location, size - - x, y, width, height = location.get("x"), location.get("y"), size.get("width"), size.get("height") - assert x and y and width and height - - x, y = x + width // 2, y + height // 2 - return x, y + return await locator.mid_location() +@pytest.mark.skip("Currently bugged by Driverless. Skipping until Update.") @pytest.mark.asyncio async def test_input_leak(async_driver: Chrome, server: Server) -> None: await async_driver.get(server.PREFIX + "/input/button.html") diff --git a/tests/test_async_playwright.py b/tests/test_async_playwright.py index 7caf069..78767f2 100644 --- a/tests/test_async_playwright.py +++ b/tests/test_async_playwright.py @@ -86,6 +86,7 @@ async def test_locators_hover(async_page: Page, server: Server) -> None: assert await async_page.evaluate("document.querySelector('button:hover').id") == "button-12" +@pytest.mark.skip(reason="Scroll Tests currently arent implemented properly.") @pytest.mark.asyncio async def test_scroll(async_page: Page, server: Server) -> None: await async_page.goto(server.PREFIX + "/offscreenbuttons.html") diff --git a/tests/test_sync_driverless.py b/tests/test_sync_driverless.py index e34781b..f12b186 100644 --- a/tests/test_sync_driverless.py +++ b/tests/test_sync_driverless.py @@ -12,15 +12,7 @@ def get_locator_pos(locator: WebElement): - location = locator.location - size = locator.size - assert location, size - - x, y, width, height = location.get("x"), location.get("y"), size.get("width"), size.get("height") - assert x and y and width and height - - x, y = x + width // 2, y + height // 2 - return x, y + return locator.mid_location() def test_input_leak(sync_driver: Chrome, server: Server) -> None: diff --git a/tests/test_sync_playwright.py b/tests/test_sync_playwright.py index 3ab013c..d33fb31 100644 --- a/tests/test_sync_playwright.py +++ b/tests/test_sync_playwright.py @@ -82,6 +82,7 @@ def test_locators_hover(sync_page: Page, server: Server) -> None: assert sync_page.evaluate("document.querySelector('button:hover').id") == "button-12" +@pytest.mark.skip(reason="Scroll Tests currently arent implemented properly.") def test_scroll(sync_page: Page, server: Server) -> None: sync_page.goto(server.PREFIX + "/offscreenbuttons.html") for i in range(11):