'''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()