Skip to content

Commit

Permalink
Merge branch 'dev' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
kaliiiiiiiiii authored Apr 27, 2024
2 parents 22c8d12 + 1fed15a commit b633d9c
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 34 deletions.
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
7 changes: 6 additions & 1 deletion docs/gitbook/input/playwright-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,34 @@ 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: Locator):
bounding_box = await 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


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 b633d9c

Please sign in to comment.