Skip to content

Commit 873da26

Browse files
committed
Introduced local server
1 parent 6b3940e commit 873da26

File tree

14 files changed

+128
-132
lines changed

14 files changed

+128
-132
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ async def get_all_links():
9999
.additional_capability(
100100
{"goog:chromeOptions": {"extensions": [], "args": ["--headless"]}}
101101
)
102-
).build()
102+
)
103103
driver_url = capabilities.driver_url
104104
session = await asynchronous.get_session(capabilities)
105105
await asynchronous.go_to_page(

caqui/asynchronous.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -781,11 +781,10 @@ async def find_element(driver_url, session, locator_type, locator_value):
781781
) from error
782782

783783

784-
async def get_session(capabilities):
784+
async def get_session(driver_url: str, capabilities: dict):
785785
"""Opens a browser and a session. This session is used for all functions to perform events in the page"""
786786
try:
787-
payload = capabilities.to_dict
788-
driver_url = capabilities.driver_url
787+
payload = capabilities
789788
url = f"{driver_url}/session"
790789
response = await __post(url, payload)
791790
return response.get("sessionId")

caqui/easy/capabilities.py

Lines changed: 59 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from requests.exceptions import ConnectionError
66

77

8-
class Brosers:
8+
class Browser:
99
"""
1010
https://pypi.org/project/webdriver-manager/
1111
"""
@@ -164,75 +164,18 @@ def build(self):
164164
return {"timeouts": self.__timeouts}
165165

166166

167-
class CapabilitiesBuilder:
167+
class Capabilities:
168168
"""Reference: https://www.w3.org/TR/webdriver/#capabilities"""
169-
170169
def __init__(self) -> None:
171170
self.__desired_capabilities = {}
172-
self.__result = {}
173-
self.__driver_ip = "localhost"
174-
self.__driver_port = "9999"
175-
self.__process = None
176-
177-
def __broser_factory(self):
178-
if Brosers.CHROME in self.__desired_capabilities.get("browserName", ""):
179-
from webdriver_manager.chrome import ChromeDriverManager
180-
181-
driver_manager = ChromeDriverManager().install()
182-
elif Brosers.FIREFOX in self.__desired_capabilities.get("browserName", ""):
183-
from webdriver_manager.firefox import GeckoDriverManager
184-
185-
driver_manager = GeckoDriverManager().install()
186-
elif Brosers.EDGE in self.__desired_capabilities.get("browserName", ""):
187-
from webdriver_manager.microsoft import EdgeChromiumDriverManager
188-
189-
driver_manager = EdgeChromiumDriverManager().install()
190-
elif Brosers.OPERA in self.__desired_capabilities.get("browserName", ""):
191-
from webdriver_manager.opera import OperaDriverManager
192-
193-
driver_manager = OperaDriverManager().install()
194-
elif Brosers.IE in self.__desired_capabilities.get("browserName", ""):
195-
from webdriver_manager.microsoft import IEDriverManager
196-
197-
driver_manager = IEDriverManager().install()
198-
else:
199-
raise Exception("Browser not supported")
200-
return driver_manager
201171

202-
def __wait_server(self):
203-
MAX_RETIES = 10
204-
for i in range(MAX_RETIES):
205-
try:
206-
requests.get(self.driver_url)
207-
break
208-
except ConnectionError:
209-
time.sleep(1)
210-
if i == (MAX_RETIES - 1):
211-
self.__process.kill()
212-
self.__process.wait()
213-
raise Exception("Driver not started")
214172

215-
@property
216-
def driver_url(self):
217-
"""
218-
Returns the driver URL.
219-
"""
220-
return f"http://{self.__driver_ip}:{self.__driver_port}"
221-
222-
@property
223173
def to_dict(self):
224174
"""
225175
Returns the capabilities.
226176
"""
227-
return self.__result
177+
return {"desiredCapabilities": self.__desired_capabilities}
228178

229-
def driver_ip(self, ip: str):
230-
self.__driver_ip = ip
231-
return self
232-
233-
def driver_port(self, port: str):
234-
self.__driver_port = port
235-
return self
236179

237180
def browser_name(self, name: str):
238181
self.__desired_capabilities = {
@@ -350,14 +293,54 @@ def additional_capability(self, capabilitiy: dict):
350293
self.__desired_capabilities = {**self.__desired_capabilities, **capabilitiy}
351294
return self
352295

353-
def build(self, start_server: bool = True):
354-
"""
355-
Build the capabilities and start the driver process."""
356-
self.__result = {"desiredCapabilities": self.__desired_capabilities}
357296

358-
if not start_server:
359-
return self
297+
class Server:
298+
"""Starts and stops the local server. Cannot be used with remote servers"""
299+
def __init__(self, browser: Browser, port=9999):
300+
self.__browser = browser
301+
self.__driver_port = port
302+
self.__process = None
303+
self.__start()
304+
305+
def __broser_factory(self):
306+
if Browser.CHROME == self.__browser:
307+
from webdriver_manager.chrome import ChromeDriverManager
308+
309+
driver_manager = ChromeDriverManager().install()
310+
elif Browser.FIREFOX == self.__browser:
311+
from webdriver_manager.firefox import GeckoDriverManager
312+
313+
driver_manager = GeckoDriverManager().install()
314+
elif Browser.EDGE == self.__browser:
315+
from webdriver_manager.microsoft import EdgeChromiumDriverManager
316+
317+
driver_manager = EdgeChromiumDriverManager().install()
318+
elif Browser.OPERA == self.__browser:
319+
from webdriver_manager.opera import OperaDriverManager
320+
321+
driver_manager = OperaDriverManager().install()
322+
elif Browser.IE == self.__browser:
323+
from webdriver_manager.microsoft import IEDriverManager
324+
325+
driver_manager = IEDriverManager().install()
326+
else:
327+
raise Exception("Browser not supported")
328+
return driver_manager
360329

330+
def __wait_server(self):
331+
MAX_RETIES = 10
332+
for i in range(MAX_RETIES):
333+
try:
334+
requests.get(self.url)
335+
break
336+
except ConnectionError:
337+
time.sleep(1)
338+
if i == (MAX_RETIES - 1):
339+
self.__process.kill()
340+
self.__process.wait()
341+
raise Exception("Driver not started")
342+
343+
def __start(self):
361344
driver_manager = self.__broser_factory()
362345

363346
self.__process = subprocess.Popen(
@@ -367,7 +350,16 @@ def build(self, start_server: bool = True):
367350
)
368351

369352
self.__wait_server()
370-
return self
353+
354+
355+
@property
356+
def url(self):
357+
"""
358+
Returns the driver URL.
359+
"""
360+
return f"http://localhost:{self.__driver_port}"
361+
362+
371363

372364
def dispose(self):
373365
"""

caqui/easy/driver.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99

1010
class AsyncDriver:
11-
def __init__(self, remote, capabilities, url=None) -> None:
12-
self.__remote = capabilities.driver_url
13-
self.__session = synchronous.get_session(capabilities)
11+
def __init__(self, driver_url: str, capabilities: dict, url=[str | None]) -> None:
12+
self.__remote = driver_url
13+
self.__session = synchronous.get_session(driver_url, capabilities)
1414
if url:
1515
synchronous.get(
1616
self.__remote,

caqui/synchronous.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -748,11 +748,11 @@ def __get_session(response):
748748
return response.get("sessionId")
749749

750750

751-
def get_session(capabilities):
751+
def get_session(driver_url: str, capabilities: dict):
752752
"""Opens a browser and a session. This session is used for all functions to perform events in the page"""
753753
try:
754-
url = f"{capabilities.driver_url}/session"
755-
data = capabilities.to_dict
754+
url = f"{driver_url}/session"
755+
data = capabilities
756756
response = __post(url, payload=data)
757757
return __get_session(response)
758758
except Exception as error:
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from caqui import synchronous, asynchronous
55
from os import getcwd
66
from tests.constants import PAGE_URL
7-
from caqui.easy.capabilities import CapabilitiesBuilder, Brosers
7+
from caqui.easy.capabilities import Capabilities, Browser, Server
88

99
BASE_DIR = getcwd()
1010

@@ -15,20 +15,20 @@
1515

1616
async def get_all_links():
1717
async with semaphore:
18-
capabilities: CapabilitiesBuilder = (
19-
CapabilitiesBuilder()
20-
.driver_ip("localhost")
21-
.driver_port("9999")
22-
.browser_name(Brosers.CHROME)
18+
capabilities: Capabilities = (
19+
Capabilities()
20+
.browser_name(Browser.CHROME)
2321
.accept_insecure_certs(True)
2422
.page_load_strategy("normal")
2523
# Reference: https://webdriver.io/docs/capabilities/
2624
.additional_capability(
2725
{"goog:chromeOptions": {"extensions": [], "args": ["--headless"]}}
2826
)
29-
).build()
30-
driver_url = capabilities.driver_url
31-
session = await asynchronous.get_session(capabilities)
27+
)
28+
server = Server(Browser.CHROME, port=9998)
29+
driver_url = server.url
30+
31+
session = await asynchronous.get_session(driver_url, capabilities)
3232
await asynchronous.go_to_page(
3333
driver_url,
3434
session,

tests/feature/test_objects.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,26 @@
33
from pytest import mark, fixture
44
from tests.constants import PAGE_URL
55
from caqui import synchronous
6-
from caqui.easy.capabilities import CapabilitiesBuilder
7-
import asyncio
6+
from caqui.easy.capabilities import Capabilities, Browser, Server
87

98

109
class TestObject:
1110
@fixture
1211
def setup(self):
13-
remote = "http://127.0.0.1:9999"
12+
server = Server(Browser.CHROME)
13+
remote = server.url
1414
capabilities = (
15-
CapabilitiesBuilder()
16-
.browser_name("chrome")
15+
Capabilities()
16+
.browser_name(Browser.CHROME)
1717
.accept_insecure_certs(True)
1818
.additional_capability(
1919
{"goog:chromeOptions": {"extensions": [], "args": ["--headless"]}}
2020
)
21-
).build()
21+
).to_dict()
2222
driver = AsyncDriver(remote, capabilities, PAGE_URL)
2323
yield driver
2424
driver.quit()
25-
capabilities.dispose()
25+
server.dispose()
2626

2727
@mark.asyncio
2828
async def test_action_chains(self, setup: AsyncDriver):

tests/feature/test_sync_and_async.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,28 @@
33
from tests.constants import PAGE_URL
44
from caqui.exceptions import WebDriverError
55
from caqui.by import By
6-
from caqui.easy.capabilities import CapabilitiesBuilder
6+
from caqui.easy.capabilities import Capabilities, Browser, Server
77

88

99
@fixture
1010
def __setup():
11-
driver_url = "http://127.0.0.1:9999"
11+
server = Server(Browser.CHROME)
12+
driver_url = server.url
1213
capabilities = (
13-
CapabilitiesBuilder()
14-
.browser_name("chrome")
14+
Capabilities()
15+
.browser_name(Browser.CHROME)
1516
.accept_insecure_certs(True)
1617
.additional_capability({"goog:chromeOptions": {"extensions": [], "args": ["--headless"]}})
17-
).build()
18-
session = synchronous.get_session(capabilities)
18+
).to_dict()
19+
session = synchronous.get_session(driver_url, capabilities)
1920
synchronous.go_to_page(
2021
driver_url,
2122
session,
2223
PAGE_URL,
2324
)
2425
yield driver_url, session
2526
synchronous.close_session(driver_url, session)
26-
capabilities.dispose()
27+
server.dispose()
2728

2829

2930
@mark.asyncio

tests/integration/test_async_scenarios.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
from caqui import synchronous, asynchronous
22
from tests.constants import PAGE_URL
33
from pytest import fixture, mark
4-
from caqui.easy.capabilities import CapabilitiesBuilder
4+
from caqui.easy.capabilities import Capabilities, Browser, Server
55

66

77
@fixture
88
def __setup():
9-
driver_url = "http://127.0.0.1:9999"
9+
server = Server(Browser.CHROME)
10+
driver_url = server.url
1011
capabilities = (
11-
CapabilitiesBuilder()
12-
.browser_name("chrome")
12+
Capabilities()
13+
.browser_name(Browser.CHROME)
1314
.accept_insecure_certs(True)
1415
.additional_capability({"goog:chromeOptions": {"extensions": [], "args": ["--headless"]}})
15-
).build()
16-
session = synchronous.get_session(capabilities)
16+
).to_dict()
17+
session = synchronous.get_session(driver_url, capabilities)
1718
synchronous.go_to_page(
1819
driver_url,
1920
session,
2021
PAGE_URL,
2122
)
2223
yield driver_url, session
2324
synchronous.close_session(driver_url, session)
24-
capabilities.dispose()
25+
server.dispose()
2526

2627

2728
@mark.asyncio

tests/integration/test_object_scenarios.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@
33
from caqui import synchronous
44
from tests.constants import PAGE_URL
55
from pytest import mark, fixture
6-
from caqui.easy.capabilities import CapabilitiesBuilder, Brosers
6+
from caqui.easy.capabilities import Capabilities, Browser, Server
77

88

99
@fixture
1010
def __setup():
11-
remote = "http://127.0.0.1:9999"
11+
server = Server(Browser.CHROME)
12+
remote = server.url
1213
capabilities = (
13-
CapabilitiesBuilder()
14-
.browser_name(Brosers.CHROME)
14+
Capabilities()
15+
.browser_name(Browser.CHROME)
1516
.accept_insecure_certs(True)
1617
.additional_capability({"goog:chromeOptions": {"extensions": [], "args": ["--headless"]}})
17-
).build()
18-
18+
).to_dict()
1919
driver = AsyncDriver(remote, capabilities, PAGE_URL)
2020
yield driver
2121
driver.quit()
22-
capabilities.dispose()
22+
server.dispose()
2323

2424

2525
@mark.asyncio

0 commit comments

Comments
 (0)