98 lines
3.4 KiB
Python
98 lines
3.4 KiB
Python
![]() |
'''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()
|