Skip to content

Commit

Permalink
- add sleep to hover tests
Browse files Browse the repository at this point in the history
- improve documentation
- add get_top_window function
- remove "scrolling is discouraged" warning
[skip-ci]
  • Loading branch information
kaliiiiiiiiii committed Apr 26, 2024
1 parent 7f1e795 commit 1fed15a
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 52 deletions.
1 change: 0 additions & 1 deletion cdp_patches/input/async_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ async def move(self, x: Union[int, float], y: Union[int, float], emulate_behavio
self.last_x, self.last_y = x, y

async def scroll(self, direction: Literal["up", "down", "left", "right"], amount: int) -> None:
warnings.warn("Scrolling using CDP-Patches is discouraged as Scroll Inputs dont leak the CDP Domain.", UserWarning)
self._base.scroll(direction=direction, amount=amount)

async def type(self, text: str, fill: Optional[bool] = False, timeout: Optional[float] = None) -> None:
Expand Down
30 changes: 15 additions & 15 deletions cdp_patches/input/os_base/windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import ctypes
import re
import warnings
from typing import Literal, Union
from typing import Literal, Union, List

from pywinauto import application, timings
from pywinauto.application import WindowSpecification
Expand All @@ -24,6 +24,18 @@
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:
if windows is None:
windows = app
# win32_app.top_window(), but without timeout
criteria = {"backend": app.backend.name}
if windows[0].handle:
criteria["handle"] = windows[0].handle
else:
criteria["name"] = windows[0].name
return WindowSpecification(criteria, allow_magic_lookup=app.allow_magic_lookup)


class WindowsBase:
browser_window: Union[WindowSpecification, HwndWrapper]
hwnd: int
Expand Down Expand Up @@ -60,13 +72,7 @@ def get_window(
self.browser_window = window
break
else:
# win32_app.top_window(), but without timeout
criteria = {"backend": self.win32_app.backend.name}
if windows[0].handle:
criteria["handle"] = windows[0].handle
else:
criteria["name"] = windows[0].name
self.browser_window = WindowSpecification(criteria, allow_magic_lookup=self.win32_app.allow_magic_lookup)
self.browser_window = get_top_window(self.win32_app, windows)

for child in self.browser_window.iter_children():
if child.element_info.class_name == "Chrome_RenderWidgetHostHWND":
Expand Down Expand Up @@ -104,13 +110,7 @@ async def async_get_window(self, timeout: float = 1) -> WindowSpecification:
self.browser_window = window
break
else:
# top window, but without timeout
criteria = {"backend": self.win32_app.backend.name}
if windows[0].handle:
criteria["handle"] = windows[0].handle
else:
criteria["name"] = windows[0].name
self.browser_window = WindowSpecification(criteria, allow_magic_lookup=self.win32_app.allow_magic_lookup)
self.browser_window = get_top_window(self.win32_app, windows)

for child in self.browser_window.iter_children():
if child.element_info.class_name == "Chrome_RenderWidgetHostHWND":
Expand Down
1 change: 0 additions & 1 deletion cdp_patches/input/sync_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ def move(self, x: Union[int, float], y: Union[int, float], emulate_behaviour: Op
self.last_x, self.last_y = x, y

def scroll(self, direction: Literal["up", "down", "left", "right"], amount: int) -> None:
warnings.warn("Scrolling using CDP-Patches is discouraged as Scroll Inputs dont leak the CDP Domain.", UserWarning)
self._base.scroll(direction=direction, amount=amount)

def type(self, text: str, fill: Optional[bool] = False, timeout: Optional[float] = None) -> None:
Expand Down
41 changes: 24 additions & 17 deletions docs/gitbook/input/playwright-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## Sync Usage (Sync Playwright)

```python
from playwright.sync_api import sync_playwright
from playwright.sync_api import sync_playwright, Locator
from cdp_patches.input import SyncInput

# Locator Position Helper
Expand Down Expand Up @@ -35,30 +35,37 @@ with sync_playwright() as playwright:
## Async Usage (Async Playwright / Botright)

```python
from playwright.async_api import async_playwright
import asyncio
from playwright.async_api import async_playwright, Locator
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
async def get_locator_pos(locator: Locator):
bounding_box = await locator.bounding_box()
assert bounding_box

x, y, width, height = location.get("x"), location.get("y"), size.get("width"), size.get("height")
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

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)
async def main():
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)


asyncio.run(main())
```
18 changes: 2 additions & 16 deletions docs/gitbook/input/selenium-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@



## Sync Usage (Selenium / Sync Selenium-Driverless)
## Sync Usage (Selenium)

```python
from selenium import webdriver
Expand Down Expand Up @@ -45,32 +45,18 @@ with webdriver.Chrome(...) as driver:

```python
import asyncio

from selenium_driverless import webdriver
from selenium_driverless.types.webelement import WebElement
from selenium_driverless.types.by import By
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 def main():
async with webdriver.Chrome(...) as driver:
async_input = await AsyncInput(browser=driver)

# Example: Click Button
# Find Button Coords
locator = await driver.find_element(By.XPATH, "//button")
x, y = await get_locator_pos(locator)
x, y = await locator.mid_location()
# Click Coords => Click Button
await async_input.click("left", x, y)

Expand Down
2 changes: 1 addition & 1 deletion tests/test_async_playwright.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ async def test_locators_hover(async_page: Page, server: Server) -> None:
x, y = await get_locator_pos(button)
await async_page.async_input.move(x, y) # type: ignore[attr-defined]

await asyncio.sleep(0.5)
assert await async_page.evaluate("document.querySelector('button:hover').id") == "button-12"


@pytest.mark.skip(reason="Scrolling is discouraged")
@pytest.mark.asyncio
async def test_scroll(async_page: Page, server: Server) -> None:
await async_page.goto(server.PREFIX + "/offscreenbuttons.html")
Expand Down
1 change: 1 addition & 0 deletions tests/test_selenium.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ def test_locators_hover(selenium_driver: Chrome, server: Server) -> None:
x, y = get_locator_pos(sync_locator)
selenium_driver.sync_input.move(x, y) # type: ignore[attr-defined]

time.sleep(0.5)
assert selenium_driver.execute_script("return document.querySelector('button:hover').id") == "button-12"


Expand Down
1 change: 1 addition & 0 deletions tests/test_sync_driverless.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ def test_locators_hover(sync_driver: Chrome, server: Server) -> None:
x, y = get_locator_pos(sync_locator)
sync_driver.sync_input.move(x, y) # type: ignore[attr-defined]

time.sleep(0.5)
assert sync_driver.execute_script("return document.querySelector('button:hover').id") == "button-12"


Expand Down
2 changes: 1 addition & 1 deletion tests/test_sync_playwright.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ def test_locators_hover(sync_page: Page, server: Server) -> None:
x, y = get_locator_pos(button)
sync_page.sync_input.move(x, y) # type: ignore[attr-defined]

time.sleep(0.5)
assert sync_page.evaluate("document.querySelector('button:hover').id") == "button-12"


@pytest.mark.skip(reason="Scrolling is discouraged")
def test_scroll(sync_page: Page, server: Server) -> None:
sync_page.goto(server.PREFIX + "/offscreenbuttons.html")
for i in range(11):
Expand Down

0 comments on commit 1fed15a

Please sign in to comment.