BRE/webapi/portal/selenium_wrapper.py

98 lines
3.4 KiB
Python
Raw Permalink Normal View History

2024-06-07 19:50:21 +03:00
'''Selenium wrapper'''
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import TimeoutException, WebDriverException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.remote.webelement import WebElement
_LOAD_TIMEOUT = 10 # seconds
_AJAX_TIMEOUT = 10 # seconds
def _ajax_complete(driver) -> bool:
try:
return driver.execute_script("return jQuery.active") == 0
except WebDriverException:
return True
class WebBrowser:
'''Wrapper for selenium webdriver'''
def __init__(self):
self.driver = None
def __del__(self):
self.stop_chrome()
def start_chrome(self, chrome_options):
'''Start Google Chrome driver'''
self.driver = webdriver.Chrome(options=chrome_options)
def stop_chrome(self):
'''Stop driver'''
if self.driver:
self.driver.quit()
def by_xpath(self, xpath: str) -> WebElement:
'''Return web element found by xpath'''
return self.driver.find_element(By.XPATH, xpath)
def by_xpath_m(self, xpath: str) -> list[WebElement]:
'''Return multimple web elements found by xpath'''
return self.driver.find_elements(By.XPATH, xpath)
def wait_presence(self, elem_id: str, by_what: str = By.ID) -> bool:
'''Wait for presence of specific element'''
try:
element_present = EC.presence_of_element_located((by_what, elem_id))
WebDriverWait(self.driver, _LOAD_TIMEOUT).until(element_present)
return True
except TimeoutException:
return False
def wait_visibility(self, elem_id: str, by_what: str = By.ID) -> bool:
'''Wait for presence of specific element'''
try:
element_visible = EC.visibility_of_element_located((by_what, elem_id))
WebDriverWait(self.driver, _LOAD_TIMEOUT).until(element_visible)
return True
except TimeoutException:
return False
def wait_clickable(self, elem_id: str, by_what: str = By.ID) -> bool:
'''Wait for presence of specific element'''
try:
element_clickable = EC.element_to_be_clickable((by_what, elem_id))
WebDriverWait(self.driver, _LOAD_TIMEOUT).until(element_clickable)
return True
except TimeoutException:
return False
def wait_ajax(self):
'''Wait for ajax to finish'''
wait_token = WebDriverWait(self.driver, _AJAX_TIMEOUT)
wait_token.until(_ajax_complete)
wait_token.until(lambda driver: driver.execute_script('return document.readyState') == 'complete')
# WebDriverWait wait = new WebDriverWait(getWebDriver(), 10);
# WebElement element = wait.until(ExpectedConditions.visibilityOf(element));
# jQuery doesnt work for some reason so we just wait implicitly
time.sleep(1)
def send_esc(self):
'''Send Escape key to browser'''
webdriver.ActionChains(self.driver).send_keys(Keys.ESCAPE).perform()
def send_enter(self):
'''Send Enter key to browser'''
webdriver.ActionChains(self.driver).send_keys(Keys.ENTER).perform()
def send_tab(self):
'''Send Tab key to browser'''
webdriver.ActionChains(self.driver).send_keys(Keys.TAB).perform()