147 lines
5.1 KiB
Python
147 lines
5.1 KiB
Python
# pages/base_page.py
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
from selenium.webdriver.common.by import By
|
|
from selenium.common.exceptions import TimeoutException
|
|
import time
|
|
import logging
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class BasePage:
|
|
"""Basis-Klasse für alle Page Objects"""
|
|
|
|
def __init__(self, driver, wait):
|
|
self.driver = driver
|
|
self.wait = wait
|
|
|
|
def wait_for_spa_navigation(self, expected_route_part, timeout=2):
|
|
"""Wartet bis SPA zur erwarteten Route navigiert hat"""
|
|
WebDriverWait(self.driver, timeout).until(
|
|
lambda d: expected_route_part in d.current_url
|
|
)
|
|
# Zusätzlich auf Vue-Rendering warten
|
|
time.sleep(0.5)
|
|
|
|
def wait_for_element(self, by, value, timeout=2):
|
|
"""Wartet auf ein Element"""
|
|
start_time = time.time()
|
|
logger.info(f"Waiting for element: {by}={value}")
|
|
|
|
result = WebDriverWait(self.driver, timeout).until(
|
|
EC.presence_of_element_located((by, value))
|
|
)
|
|
|
|
elapsed = time.time() - start_time
|
|
logger.info(f"Found element after {elapsed:.2f}s")
|
|
return result
|
|
def wait_for_clickable(self, by, value, timeout=2):
|
|
"""Wartet bis Element klickbar ist"""
|
|
return WebDriverWait(self.driver, timeout).until(
|
|
EC.element_to_be_clickable((by, value))
|
|
)
|
|
|
|
def fill_input(self, by, value, text, check_existence=False, timeout=2):
|
|
if check_existence:
|
|
# Prüfe ob Element existiert
|
|
try:
|
|
element = WebDriverWait(self.driver, timeout).until(
|
|
EC.presence_of_element_located((by, value))
|
|
)
|
|
logger.info(f"Element exists, filling...")
|
|
except TimeoutException:
|
|
logger.warning(f"Element does not exist, skipping (check_existence=True)")
|
|
return False
|
|
else:
|
|
# Normaler Modus - erwarte dass Element existiert
|
|
element = self.wait_for_element(by, value, timeout)
|
|
|
|
# Element existiert - jetzt füllen
|
|
element.clear()
|
|
element.send_keys(text)
|
|
logger.info(f"Filled input with: {text}")
|
|
return True
|
|
|
|
def click_button(self, by, value):
|
|
"""Klickt einen Button"""
|
|
start_time = time.time()
|
|
logger.info(f"Clicking button: {by}={value}")
|
|
|
|
button = self.wait_for_clickable(by, value)
|
|
button.click()
|
|
|
|
elapsed = time.time() - start_time
|
|
logger.info(f"Clicked after {elapsed:.2f}s")
|
|
|
|
def set_checkbox(self, by, value, checked, timeout=2):
|
|
label = self.wait_for_clickable(by, value, timeout)
|
|
|
|
checkbox_input = label.find_element(By.CSS_SELECTOR, "input[type='checkbox']")
|
|
|
|
is_checked = checkbox_input.is_selected()
|
|
|
|
if is_checked != checked:
|
|
label.click()
|
|
time.sleep(0.3)
|
|
|
|
|
|
def select_dropdown_option(self, by, value, option_text, timeout=10):
|
|
dropdown_button = self.wait_for_element(by, value, timeout=timeout)
|
|
|
|
try:
|
|
current_value = dropdown_button.find_element(
|
|
By.CSS_SELECTOR,
|
|
"span.dropdown-trigger-text"
|
|
).text
|
|
|
|
if current_value == option_text:
|
|
logger.info(f"Dropdown already has value: {option_text}")
|
|
return
|
|
except:
|
|
pass # Falls kein Text gefunden wurde, öffne das Dropdown
|
|
|
|
dropdown_button.click()
|
|
logger.info("Opened dropdown")
|
|
|
|
menu = WebDriverWait(self.driver, timeout).until(
|
|
EC.visibility_of_element_located((By.CSS_SELECTOR, "ul.dropdown-menu"))
|
|
)
|
|
logger.info("Dropdown menu visible")
|
|
|
|
option_xpath = f"//li[contains(@class, 'dropdown-option')][normalize-space(text())='{option_text}']"
|
|
option = WebDriverWait(self.driver, timeout).until(
|
|
EC.element_to_be_clickable((By.XPATH, option_xpath))
|
|
)
|
|
|
|
logger.info(f"Clicking option: {option_text}")
|
|
option.click()
|
|
|
|
|
|
time.sleep(0.2)
|
|
|
|
def search_and_select_autosuggest(self, by_or_selector, value_or_search_text,
|
|
search_text=None,
|
|
suggestion_selector=".suggestion-item",
|
|
timeout=2):
|
|
|
|
if search_text is not None:
|
|
# Fall: (By.CSS_SELECTOR, ".selector", "search_text")
|
|
search_input = self.wait_for_element(by_or_selector, value_or_search_text, timeout)
|
|
text_to_search = search_text
|
|
else:
|
|
# Fall: (".selector", "search_text")
|
|
search_input = self.wait_for_element(By.CSS_SELECTOR, by_or_selector, timeout)
|
|
text_to_search = value_or_search_text
|
|
|
|
search_input.clear()
|
|
search_input.send_keys(text_to_search)
|
|
|
|
time.sleep(1)
|
|
|
|
suggestion = WebDriverWait(self.driver, timeout).until(
|
|
EC.element_to_be_clickable((By.CSS_SELECTOR, suggestion_selector))
|
|
)
|
|
suggestion.click()
|
|
|
|
time.sleep(0.5)
|