diff --git a/docs/gitbook/README.md b/docs/gitbook/README.md new file mode 100644 index 0000000..5ca3782 --- /dev/null +++ b/docs/gitbook/README.md @@ -0,0 +1,33 @@ +# Input + +## Concept: Input Domain Leaks + +Bypass CDP-Leaks in [Input](https://chromedevtools.github.io/devtools-protocol/tot/Input/) domains.\ +For an interaction event _`e`_, the page coordinates won't ever equal the screen coordinates, unless Chrome is in full-screen. \ +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)).\ + + +```javascript +var is_bot = (e.pageY == e.screenY && e.pageX == e.screenX) +if (is_bot && 1 >= outerHeight - innerHeight){ // fullscreen + is_bot = false +} +``` + + + +*** + +{% hint style="warning" %} +#### Because Chrome does not recognize Input Events to specific tabs, these methods can only be used on the active tab. + +#### Chrome Tabs do have their own process with a process id (PID), but these can not be controlled using Input Events as they´re just engines. +{% endhint %} + +*** + +**Owner**: [Vinyzu](https://github.com/Vinyzu/)\ +**Co-Maintainer**: [Kaliiiiiiiiii](https://github.com/kaliiiiiiiiii/) + + + diff --git a/docs/gitbook/SUMMARY.md b/docs/gitbook/SUMMARY.md new file mode 100644 index 0000000..c224557 --- /dev/null +++ b/docs/gitbook/SUMMARY.md @@ -0,0 +1,8 @@ +# Table of contents + +* [Input](README.md) + * [Sync Usage](input/sync-usage.md) + * [Async Usage](input/async-usage.md) + * [Selenium Usage](input/selenium-usage.md) + * [Playwright Usage](input/playwright-usage.md) +* [Page](page.md) diff --git a/docs/gitbook/input/async-usage.md b/docs/gitbook/input/async-usage.md new file mode 100644 index 0000000..a796322 --- /dev/null +++ b/docs/gitbook/input/async-usage.md @@ -0,0 +1,48 @@ +# Async Usage + + + +## AsyncInput + +> ### `await cdp_patches.input.AsyncInput()` + +
KwargsTypeUsageDefaults
pidint

The Main Chrome Browser Window PID to connect to. Can also be found in Chromes Task-Manager (Shift+Esc).

None
browsersync_browsersA Async Browser Instance. Can be any of:
(sd = selenium_driverless)
(pw = playwright)
sd.webdriver.Chrome,
pw.async_api.Browser, pw.async_api.BrowserContext
None
scale_factorfloatThe Scaling Factor of the Browser. If a browserInstance is passed, this value gets determined automatically.1.0
emulate_behaviourboolWhether to emulate human behaviour.True
+ +*** + +### AsyncInput Properties + +
PropertyTypeUsageDefaults
emulate_behaviourboolWhether to emulate human behaviour.True
window_timeoutint

The Time of how long to search for the Window in seconds.

30
baseWindowsBase |
LinuxBase
The Base Interaction Layer. Can be useful in some special cases in which emulate_behaviour isnt sufficient. Only Readable.None
scale_factorfloatThe Scaling Factor of the Browser. If a browserInstance is passed, this value gets determined automatically.1.0
sleep_timeoutfloatHow long to sleep after certain actions, for example in between a double-click. In Seconds.0.01
typing_speedintHow fast to type in WPM.50
+ +*** + +### AsyncInput Methods + +
# Type Abbreviations
+Pos = Union[int, float]
+Button = Literal["left", "right", "middle"]
+EmulateBehaviour: Optional[bool] = True
+Timeout: Optional[float] = Non
+
+# Click at the given coordinates with the given button
+await async_input.click(button: Button, x: Pos, y: Pos, emulate_behaviour: EmulateBehaviour, timeout: Timeout)
+
+# Double-Click at the given coordinates with the given button
+await async_input.double_click(button: Button, x: Pos, y: Pos, emulate_behaviour: EmulateBehaviour, timeout: Timeout)
+
+# Mouse-Down at the given coordinates with the given button
+await async_input.down(button: Button, x: Pos, y: Pos, emulate_behaviour: EmulateBehaviour, timeout: Timeout)
+
+# Mouse-Up at the given coordinates with the given button
+await async_input.up(button: Button, x: Pos, y: Pos)
+
+# Mouse-Move to the given coordinates
+await async_input.move(x: Pos, y: Pos, emulate_behaviour: EmulateBehaviour, timeout: Timeout)
+
+# Scroll the page in the given direction by the given amount
+await async_input.scroll(direction: Literal["up", "down", "left", "right"], amount: int)
+
+# Type the given text and optionally fill the input field (Like pasting)
+await async_input.type(text: str, fill: Optional[bool] = False, timeout: Timeout)
+
+ diff --git a/docs/gitbook/input/playwright-usage.md b/docs/gitbook/input/playwright-usage.md new file mode 100644 index 0000000..b3a0f26 --- /dev/null +++ b/docs/gitbook/input/playwright-usage.md @@ -0,0 +1,64 @@ +# Playwright Usage + + + +## Sync Usage (Sync Playwright) + +```python +from playwright.sync_api import sync_playwright +from cdp_patches.input import SyncInput + +# Locator Position Helper +def get_locator_pos(locator: Locator): + bounding_box = locator.bounding_box() + assert bounding_box + + x, y, width, height = bounding_box.get("x"), bounding_box.get("y"), bounding_box.get("width"), bounding_box.get("height") + assert x and y and width and height + + x, y = x + width // 2, y + height // 2 + return x, y + +with sync_playwright() as playwright: + browser = playwright.chromium.launch() + page = browser.new_page() + sync_input = SyncInput(browser=browser) # Also works with Contexts + + # Example: Click Button + # Find Button Coords + locator = page.locator("button") + x, y = get_locator_pos(locator) + # Click Coords => Click Button + sync_input.click("left", x, y) +``` + +## Async Usage (Async Playwright / Botright) + +```python +from playwright.async_api import async_playwright +from cdp_patches.input import AsyncInput + +# Locator Position Helper +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 + +async with async_playwright() as playwright: + browser = await playwright.chromium.launch() + page = await browser.new_page() + async_input = await AsyncInput(browser=browser) # Also works with Contexts + + # Example: Click Button + # Find Button Coords + locator = page.locator("button") + x, y = await get_locator_pos(locator) + # Click Coords => Click Button + await async_input.click("left", x, y) +``` diff --git a/docs/gitbook/input/selenium-usage.md b/docs/gitbook/input/selenium-usage.md new file mode 100644 index 0000000..3612164 --- /dev/null +++ b/docs/gitbook/input/selenium-usage.md @@ -0,0 +1,63 @@ +# Selenium Usage + + + +## Sync Usage (Selenium / Sync Selenium-Driverless) + +```python +from selenium import webdriver +from cdp_patches.input import SyncInput + +# Locator Position Helper +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 + +with webdriver.Chrome(...) as driver: + sync_input = SyncInput(browser=driver) + + # Example: Click Button + # Find Button Coords + locator = driver.find_element(By.XPATH, "//button") + x, y = get_locator_pos(locator) + # Click Coords => Click Button + sync_input.click("left", x, y) +``` + +*** + +## Async Usage (Async Selenium-Driverless) + +```python +from selenium_driverless import webdriver +from cdp_patches.input import AsyncInput + +# Locator Position Helper +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 + +async with async_webdriver.Chrome(options) as driver: + async_input = await AsyncInput(browser=driver) + + # Example: Click Button + # Find Button Coords + locator = await async_driver.find_element(By.XPATH, "//button") + x, y = await get_locator_pos(locator) + # Click Coords => Click Button + await aawait async_driver.find_element(By.XPATH, "//button")sync_input.click("left", x, y) +``` diff --git a/docs/gitbook/input/sync-usage.md b/docs/gitbook/input/sync-usage.md new file mode 100644 index 0000000..6ec03ae --- /dev/null +++ b/docs/gitbook/input/sync-usage.md @@ -0,0 +1,51 @@ +# Sync Usage + + + +## SyncInput + +> ### `cdp_patches.input.SyncInput()` + +
KwargsTypeUsageDefaults
pidint

The Main Chrome Browser Window PID to connect to. Can also be found in Chromes Task-Manager (Shift+Esc).

None
browsersync_browsersA Sync Browser Instance. Can be any of:
(sd = selenium_driverless)
(pw = playwright)
selenium.webdriver.Chrome, sd.sync.webdriver.Chrome,
pw.sync_api.Browser, pw.sync_api.BrowserContext
None
scale_factorfloatThe Scaling Factor of the Browser. If a browserInstance is passed, this value gets determined automatically.1.0
emulate_behaviourboolWhether to emulate human behaviour.True
+ +*** + +### SyncInput Properties + +
PropertyTypeUsageDefaults
emulate_behaviourboolWhether to emulate human behaviour.True
window_timeoutint

The Time of how long to search for the Window in seconds.

30
baseWindowsBase |
LinuxBase
The Base Interaction Layer. Can be useful in some special cases in which emulate_behaviour isnt sufficient. Only Readable.None
scale_factorfloatThe Scaling Factor of the Browser. If a browserInstance is passed, this value gets determined automatically.1.0
sleep_timeoutfloatHow long to sleep after certain actions, for example in between a double-click. In Seconds.0.01
typing_speedintHow fast to type in WPM.50
+ +*** + +### SyncInput Methods + +{% code fullWidth="true" %} +```python +# Type Abbreviations +Pos = Union[int, float] +Button = Literal["left", "right", "middle"] +EmulateBehaviour: Optional[bool] = True +Timeout: Optional[float] = Non + +# Click at the given coordinates with the given button +sync_input.click(button: Button, x: Pos, y: Pos, emulate_behaviour: EmulateBehaviour, timeout: Timeout) + +# Double-Click at the given coordinates with the given button +sync_input.double_click(button: Button, x: Pos, y: Pos, emulate_behaviour: EmulateBehaviour, timeout: Timeout) + +# Mouse-Down at the given coordinates with the given button +sync_input.down(button: Button, x: Pos, y: Pos, emulate_behaviour: EmulateBehaviour, timeout: Timeout) + +# Mouse-Up at the given coordinates with the given button +sync_input.up(button: Button, x: Pos, y: Pos) + +# Mouse-Move to the given coordinates +sync_input.move(x: Pos, y: Pos, emulate_behaviour: EmulateBehaviour, timeout: Timeout) + +# Scroll the page in the given direction by the given amount +sync_input.scroll(direction: Literal["up", "down", "left", "right"], amount: int) + +# Type the given text and optionally fill the input field (Like pasting) +sync_input.type(text: str, fill: Optional[bool] = False, timeout: Timeout) +``` +{% endcode %} + diff --git a/docs/gitbook/page.md b/docs/gitbook/page.md new file mode 100644 index 0000000..5c4b4d5 --- /dev/null +++ b/docs/gitbook/page.md @@ -0,0 +1,2 @@ +# Page +