Skip to content

Commit b79f26b

Browse files
author
dmy.berezovskyi
committed
improved base_page.py
1 parent 13c62d7 commit b79f26b

File tree

3 files changed

+72
-26
lines changed

3 files changed

+72
-26
lines changed

.ruff.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Ruff Configuration
2-
line-length = 88
2+
line-length = 85
33
indent-width = 4
44
output-format = "grouped"
55
respect-gitignore = true

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ packages = [
1313
python = "^3.12"
1414
pytest = "8.3.2"
1515
PyYAML = "^6.0.1"
16-
selenium = "4.24.0"
16+
selenium = "~4.24.0"
1717
webdriver-manager = "4.0.2"
1818
python-dotenv = "1.0.1"
1919
asyncio = "3.4.3"

src/pageobjects/base_page.py

Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
from enum import Enum
2-
from typing import Tuple
3-
4-
from appium.webdriver import WebElement
5-
from selenium.common import ElementNotVisibleException, TimeoutException
2+
from typing import Tuple, Optional, Literal
63
from selenium.webdriver.common.by import By
7-
from selenium.webdriver.support import expected_conditions as ec
4+
from selenium.webdriver.remote.webelement import WebElement
5+
from selenium.webdriver.support import expected_conditions as EC
86
from selenium.webdriver.support.wait import WebDriverWait
7+
from selenium.common.exceptions import (
8+
TimeoutException, ElementNotVisibleException
9+
)
910

11+
# Type alias for locators
1012
Locator = Tuple[By, str]
1113

1214

@@ -30,33 +32,77 @@ def __init__(self, driver):
3032
ignored_exceptions=[ElementNotVisibleException],
3133
)
3234

33-
def wait(
34-
self, locator: Locator, waiter: WebDriverWait = None
35+
def _get_waiter(self, wait_type: Optional[WaitType] = None) -> WebDriverWait:
36+
"""
37+
Returns the appropriate WebDriverWait object based on the wait_type.
38+
Defaults to the default wait if no wait_type is provided.
39+
"""
40+
return {
41+
WaitType.SHORT: self._short_wait,
42+
WaitType.LONG: self._long_wait,
43+
WaitType.FLUENT: self._fluent_wait,
44+
}.get(wait_type, self._wait)
45+
46+
def wait_for(
47+
self,
48+
locator: Locator,
49+
condition: Literal["clickable", "visible", "present"],
50+
waiter: Optional[WebDriverWait] = None,
3551
) -> WebElement:
36-
if waiter is None:
37-
waiter = self._wait
52+
waiter = waiter or self._wait
53+
54+
conditions = {
55+
"clickable": EC.element_to_be_clickable(*locator),
56+
"visible": EC.visibility_of_element_located(*locator),
57+
"present": EC.presence_of_element_located(*locator),
58+
}
59+
60+
if condition not in conditions:
61+
raise ValueError(f"Unknown condition: {condition}")
62+
3863
try:
39-
return waiter.until(ec.presence_of_element_located(locator))
40-
except TimeoutException:
64+
return waiter.until(conditions[condition])
65+
except TimeoutException as e:
4166
raise TimeoutException(
42-
f"Element {locator} not found after {waiter._timeout} seconds"
43-
)
44-
45-
def find(self, locator: Locator):
46-
self.driver.find_element(*locator)
67+
f"Condition '{condition}' failed for element {locator} "
68+
f"after {waiter._timeout} seconds"
69+
) from e
4770

48-
def click(self, locator: Locator):
49-
element = self.wait(locator)
71+
def click(
72+
self,
73+
locator: Locator,
74+
condition: Literal["clickable", "visible", "present"] = "clickable",
75+
wait_type: Optional[WaitType] = None,
76+
):
77+
"""
78+
Click on an element.
79+
"""
80+
waiter = self._get_waiter(wait_type)
81+
element = self.wait_for(locator, condition=condition, waiter=waiter)
5082
element.click()
5183

52-
def set(self, locator: Locator, text: str):
53-
element = self.wait(locator)
84+
def set(
85+
self, locator: Locator, text: str, wait_type: Optional[WaitType] = None
86+
):
87+
"""
88+
Set text in an input field.
89+
"""
90+
waiter = self._get_waiter(wait_type)
91+
element = self.wait_for(locator, condition="visible", waiter=waiter)
5492
element.clear()
5593
element.send_keys(text)
5694

57-
def get_text(self, locator: Locator):
58-
element = self.wait(locator)
59-
return element.text
95+
def get_text(
96+
self, locator: Locator, wait_type: Optional[WaitType] = None
97+
) -> str:
98+
"""
99+
Get the text of an element.
100+
"""
101+
waiter = self._get_waiter(wait_type)
102+
return self.wait_for(locator, condition="present", waiter=waiter).text
60103

61-
def get_title(self):
104+
def get_title(self) -> str:
105+
"""
106+
Get the page title.
107+
"""
62108
return self.driver.title

0 commit comments

Comments
 (0)