Skip to content

Commit 679d2b7

Browse files
authored
Merge pull request #116 from douglasdcm/migrate-to-cdp-prortocol
Add support to Chrome Devtools Protocol
2 parents 2edcd78 + af7dc6b commit 679d2b7

File tree

107 files changed

+9517
-827
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

107 files changed

+9517
-827
lines changed

.github/workflows/python-app.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ jobs:
4040
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
4141
- name: Test with pytest
4242
run: |
43-
python -m pytest -n auto
43+
python -m pytest -k unit

Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@ build:
55
python setup.py bdist_wheel
66

77
setenv:
8+
# Get the list of envs and run on all of them
89
python3.7 -m venv venv
910
. venv/bin/activate
1011
pip install --upgrade pip setuptools wheel
1112
pip install -r test-requirements.txt
1213
pip install -r dev-requirements.txt
1314

15+
PARAMS ?= ''
1416
test:
15-
pytest -n auto
17+
pytest $(PARAMS)
1618

1719
linter:
1820
black -l 100 .
@@ -21,7 +23,7 @@ linter:
2123
mypy caqui tests --config=pyproject.toml
2224

2325
coverage:
24-
coverage run --source='caqui' -m pytest -n auto
26+
coverage run --source='caqui' -m pytest
2527
coverage report
2628
coverage html
2729

README.md

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
[![Python application](https://github.com/douglasdcm/caqui/actions/workflows/python-app.yml/badge.svg)](https://github.com/douglasdcm/caqui/actions/workflows/python-app.yml)
44
[![PyPI Downloads](https://static.pepy.tech/badge/caqui)](https://pepy.tech/projects/caqui)
55

6-
**Caqui** is a Python library for browser, mobile, and desktop automation that works with any driver that exposes a WebDriver-style REST API. It lets you send commands **synchronously or asynchronously**, and you don’t need to think about which underlying driver you’re using.
6+
**Caqui** is a Python library for browser, mobile, and desktop automation that works with any driver that exposes a WebDriver-style REST API or Chrome Devtools Protocol. It lets you send commands **synchronously or asynchronously**, and you don’t need to think about which underlying driver you’re using.
77

88
Caqui is designed for developers who want a unified automation API that can run:
99

10+
* Chrome Devtools Protocol ((Chrome, Opera, Edge))
1011
* WebDriver (Chrome, Firefox, Opera, Edge)
1112
* Appium (Android, iOS)
1213
* Winium / WinAppDriver (Windows desktop applications)
@@ -16,7 +17,7 @@ Caqui runs seamlessly on a local machine or across remote hosts, and supports bo
1617

1718
---
1819

19-
# Supported Drivers
20+
# Supported Web Drivers
2021

2122
| WebDriver | Version | Remote* | If remote |
2223
| --------------------- | ------- | ------- | ------------------------------------------------------------- |
@@ -44,15 +45,49 @@ pip install caqui
4445
From version **2.0.0+**, Caqui includes a high-level API that mirrors Selenium’s object model and exposes async methods for browser, mobile, and desktop automation.
4546
[Full documentation:](https://caqui.readthedocs.io/en/latest/caqui.html)
4647

47-
Example:
48+
Chrome Devtools Protocol example:
49+
```python
50+
import time
51+
from pytest import raises
52+
from caqui.cdp.by import By
53+
from caqui.cdp.synchronous.drivers import SyncDriverCDP
54+
from caqui.exceptions import WebDriverError
55+
from tests.constants import OTHER_URL
56+
from caqui.cdp.server import LocalServerCDP, get_ws_url
57+
58+
@fixture(autouse=True, scope="session")
59+
def launch_browser():
60+
server = LocalServerCDP()
61+
server.start_chrome()
62+
yield server
63+
server.dispose()
64+
65+
@fixture
66+
def setup_sync_cdp_playground():
67+
with SyncCDPConnection(get_ws_url()) as conn:
68+
driver = SyncDriverCDP(conn)
69+
driver.get(PAGE_URL)
70+
driver.set_window_size(1000, 1000)
71+
yield driver
72+
73+
class TestSyncCDPElement:
74+
def test_cdp_is_element_enabled(self, setup_sync_cdp_playground: SyncDriverCDP):
75+
driver = setup_sync_cdp_playground
76+
locator_type = By.XPATH
77+
locator_value = "//input"
78+
element = driver.find_element(locator_type, locator_value)
79+
assert element.is_enabled() is True
80+
```
81+
82+
Web Driver example:
4883

4984
```python
5085
from os import getcwd
5186
from pytest import mark, fixture
52-
from caqui.easy.drivers import AsyncDriver
53-
from caqui.easy.capabilities import ChromeCapabilitiesBuilder
87+
from caqui.webdriver.drivers import AsyncDriver
88+
from caqui.webdriver.capabilities import ChromeCapabilitiesBuilder
5489
from caqui.by import By
55-
from caqui.easy.server import LocalServer
90+
from caqui.webdriver.server import LocalServer
5691

5792
BASE_DIR = getcwd()
5893
PAGE_URL = f"file:///{BASE_DIR}/html/playground.html"

caqui/bidi/__init__.py

Whitespace-only changes.

caqui/bidi/by.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright (C) 2023 Caqui - All Rights Reserved
2+
# You may use, distribute and modify this code under the
3+
# terms of the MIT license.
4+
# Visit: https://github.com/douglasdcm/caqui
5+
6+
from caqui.by import By # noqa F401

caqui/bidi/engine/__init__.py

Whitespace-only changes.

caqui/by.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ class By:
1515
CLASS_NAME: str = "class name"
1616
LINK_TEXT: str = "link text"
1717
PARTIAL_LINK_TEXT: str = "partial link text"
18+
# TODO add TEXT and expose to CDP

caqui/cdp/asynchronous/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright (C) 2023 Caqui - All Rights Reserved
2+
# You may use, distribute and modify this code under the
3+
# terms of the MIT license.
4+
# Visit: https://github.com/douglasdcm/caqui
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Copyright (C) 2023 Caqui - All Rights Reserved
2+
# You may use, distribute and modify this code under the
3+
# terms of the MIT license.
4+
# Visit: https://github.com/douglasdcm/caqui
5+
6+
from typing import TYPE_CHECKING, Coroutine, List, Union
7+
8+
from caqui.cdp.engine import asynchronous
9+
10+
if TYPE_CHECKING:
11+
from caqui.cdp.asynchronous.drivers import AsyncDriverCDP
12+
from caqui.cdp.asynchronous.element import Element
13+
14+
15+
class ActionChains:
16+
def __init__(self, driver: "AsyncDriverCDP") -> None:
17+
self._conn = driver.conn
18+
self._coroutines: List[Coroutine] = []
19+
self._element = Union["Element", None]
20+
21+
def click(self, element: "Element") -> "ActionChains":
22+
"""
23+
Clicks on the element `element`
24+
"""
25+
self._element = element
26+
coroutine = asynchronous.click(
27+
self._conn,
28+
element.element_id,
29+
)
30+
self._coroutines.append(coroutine)
31+
return self
32+
33+
def move_to_element(self, element: "Element") -> "ActionChains":
34+
"""Move the mouse to the element `element`"""
35+
self._element = element
36+
coroutine = asynchronous.actions_move_to_element(
37+
self._conn,
38+
element.element_id,
39+
)
40+
self._coroutines.append(coroutine)
41+
return self
42+
43+
def scroll_to_element(self, element: "Element", delta_y: int = 1000) -> "ActionChains":
44+
"""Scrolls the screen to the element `element`"""
45+
self._element = element
46+
coroutine = asynchronous.actions_scroll_to_element(
47+
self._conn,
48+
element.element_id,
49+
)
50+
self._coroutines.append(coroutine)
51+
return self
52+
53+
async def perform(self) -> None:
54+
"""Executes the chain of Coroutines"""
55+
[await coroutine for coroutine in self._coroutines]

0 commit comments

Comments
 (0)