import logging import os import time from traceback import print_stack import allure from appium.webdriver.common.mobileby import MobileBy from selenium.common.exceptions import ElementNotSelectableException, ElementNotVisibleException, NoSuchElementException from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.select import Select from selenium.webdriver.support.ui import WebDriverWait from ..utils import Logger, CoreConfig class InitDriver: """ Class contains wrappers around built-in selenium/ appium methods """ log = Logger(logging.DEBUG) def __init__(self, driver): self.driver = driver def take_screenshot(self, message): file_name = message + "." + str(round(time.time() * 1000)) + ".png" if len(file_name) >= 200: file_name = str(round(time.time() * 1000)) + ".png" screenshot_dir = "../../../screenshots/" relative_name = screenshot_dir + file_name current_dir = os.path.dirname(__file__) destination_file = os.path.abspath(os.path.join(current_dir, relative_name)) destination_dir = os.path.abspath(os.path.join(current_dir, screenshot_dir)) if not os.path.exists(destination_dir): os.makedirs(destination_dir) self.driver.save_screenshot(destination_file) allure.attach(self.driver.get_screenshot_as_png(), name=file_name, attachment_type=allure.attachment_type.PNG) self.log.info("Screenshot saved to directory: " + destination_file) def get_title(self): return self.driver.title def get_by_type(self, locator_type): locator_type = locator_type.lower() if locator_type == "id": return By.ID if locator_type == "name": return By.NAME if locator_type == "xpath": return By.XPATH if locator_type == "css": return By.CSS_SELECTOR if locator_type == "class": return By.CLASS_NAME if locator_type == "link": return By.LINK_TEXT if locator_type == "accessibility-id": return MobileBy.ACCESSIBILITY_ID if locator_type == "class-chain": return MobileBy.IOS_CLASS_CHAIN if locator_type == "predicate": return MobileBy.IOS_PREDICATE self.log.info("Locator type" + locator_type + "passed in wrong format") return False def select_element_from_dropdown(self, locator, locator_type="id", selector="", selector_type="value"): try: element = self.get_element(locator, locator_type) sel = Select(element) if selector_type == "value": sel.select_by_value(selector) time.sleep(1) elif selector_type == "index": sel.select_by_index(selector) time.sleep(1) elif selector_type == "text": sel.select_by_visible_text(selector) time.sleep(1) self.log.info("Element selected with selector: " + str(selector) + " and selector_type: " + selector_type) except Exception: self.log.error( "Element not selected with selector: " + str(selector) + " and selector_type: " + selector_type ) print_stack() def get_element(self, locator, locator_type="id"): element = None try: locator_type = locator_type.lower() by_type = self.get_by_type(locator_type) element = self.driver.find_element(by_type, locator) self.log.info("Got element found with locator: " + locator + " and locator_type: " + locator_type) except Exception: self.log.error("Element not found with locator: " + locator + " and locator_type: " + locator_type) return element def is_element_selected(self, locator, locator_type): is_selected = None try: element = self.get_element(locator, locator_type) is_selected = element.is_selected() self.log.info("Element is selected with locator: " + locator + " and locator_type: " + locator_type) except Exception: self.log.error("Element not found with locator: " + locator + " and locator_type: " + locator_type) return is_selected def get_elements(self, locator, locator_type="id"): element = None try: locator_type = locator_type.lower() by_type = self.get_by_type(locator_type) element = self.driver.find_elements(by_type, locator) self.log.info("Got elements list found with locator: " + locator + " and locator_type: " + locator_type) except Exception: self.log.error("Element list not found with locator: " + locator + " and locator_type: " + locator_type) return element def click_element(self, locator="", locator_type="id", element=None): try: if locator: if CoreConfig.SELENIUM_ENV not in ['web', 'local']: element = self.wait_for_element_present(locator, locator_type) else: element = self.get_element(locator, locator_type) element.click() self.log.info("Clicked on element with locator: " + locator + " locator_type: " + locator_type) except Exception: self.log.error("Cannot click on the element with locator: " + locator + " locator_type: " + locator_type) if CoreConfig.SELENIUM_ENV not in ['web', 'local']: if locator: element = self.wait_for_element_present(locator, locator_type) element.click() def hover_on_element(self, locator="", locator_type="id", element=None): try: if locator: element = self.get_element(locator, locator_type) hover = ActionChains(self.driver).move_to_element(element) hover.perform() time.sleep(2) self.log.info("Hover to element with locator: " + locator + " locator_type: " + locator_type) except Exception: self.log.error("Cannot hover to the element with locator: " + locator + " locator_type: " + locator_type) print_stack() def send_text(self, data, locator="", locator_type="id", element=None): try: if locator: element = self.get_element(locator, locator_type) element.send_keys(data) self.log.info("Send text on the element with locator: " + locator + " locator_type: " + locator_type) except Exception: self.log.error( "Cannot send text on the element with locator: " + locator + " locator_type: " + locator_type ) print_stack() def clear_text(self, locator="", locator_type="id", element=None): try: if locator: element = self.get_element(locator, locator_type) element.clear() self.log.info("Clear text of the element with locator: " + locator + " locator_type: " + locator_type) except Exception: self.log.error( "Cannot clear text of the element with locator: " + locator + " locator_type: " + locator_type ) print_stack() def get_text(self, locator="", locator_type="id", element=None, info=""): try: if locator: self.log.debug("In locator condition") element = self.get_element(locator, locator_type) self.log.debug("Before finding text") text = element.text self.log.debug("After finding element, size is: " + str(len(text))) if len(text) == 0: text = element.get_attribute("innerText") if len(text) != 0: self.log.info("Getting text on element :: " + info) self.log.info("The text is :: '" + text + "'") text = text.strip() except Exception: self.log.error("Failed to get text on element " + info) print_stack() text = None return text def is_element_present(self, locator="", locator_type="id", element=None): try: if locator: element = self.get_element(locator, locator_type) if element is not None: self.log.info("Element is present with locator: " + locator + " and locator_type: " + locator_type) return True else: self.log.error("Element not found with locator: " + locator + " and locator_type: " + locator_type) return False except Exception: self.log.error("Element not found with locator: " + locator + " and locator_type: " + locator_type) return False def is_element_displayed(self, locator="", locator_type="id", element=None): is_displayed = False try: if locator: element = self.get_element(locator, locator_type) if element is not None: is_displayed = element.is_displayed() self.log.info("Element is displayed: " + locator + " and locator_type: " + locator_type) else: self.log.error("Element is not displayed: " + locator + " and locator_type: " + locator_type) return is_displayed except Exception as ex: self.log.error( "Element is not displayed: " + locator + " and locator_type: " + locator_type + " " + str(ex) ) return False def wait_for_element_clickable( self, locator, locator_type="id", timeout=int(CoreConfig.SELENIUM_TIMEOUT), poll_frequency=0.5 ): element = None try: self.log.info("Waiting for maximum :: " + str(timeout) + " :: seconds for element to be clickable") wait = WebDriverWait( self.driver, timeout, poll_frequency=poll_frequency, ignored_exceptions=[NoSuchElementException, ElementNotVisibleException, ElementNotSelectableException], ) by_type = self.get_by_type(locator_type) element = wait.until(EC.element_to_be_clickable((by_type, locator))) self.log.info("Element found") except Exception: self.log.info("Element not found") print_stack() return element def wait_for_element_present( self, locator, locator_type="id", timeout=int(CoreConfig.SELENIUM_TIMEOUT), poll_frequency=0.5 ): element = None try: self.log.info("Waiting for maximum :: " + str(timeout) + " :: seconds for element to be clickable") wait = WebDriverWait( self.driver, timeout, poll_frequency=poll_frequency, ignored_exceptions=[NoSuchElementException, ElementNotVisibleException, ElementNotSelectableException], ) by_type = self.get_by_type(locator_type) element = wait.until(EC.presence_of_element_located((by_type, locator))) self.log.info("Element found") except Exception: self.log.info("Element not found") print_stack() return element def wait_for_element_visible( self, locator, locator_type="id", timeout=int(CoreConfig.SELENIUM_TIMEOUT), poll_frequency=0.5 ): element = None try: self.log.info("Waiting for maximum :: " + str(timeout) + " :: seconds for element to be visible") wait = WebDriverWait( self.driver, timeout, poll_frequency=poll_frequency, ignored_exceptions=[NoSuchElementException, ElementNotVisibleException, ElementNotSelectableException], ) by_type = self.get_by_type(locator_type) element = wait.until(EC.visibility_of_element_located((by_type, locator))) self.log.info("Element found") except Exception as ex: self.log.info("Element not found" + " " + str(ex)) print_stack() return element def wait_for_element_not_visible( self, locator, locator_type="id", timeout=int(CoreConfig.SELENIUM_TIMEOUT), poll_frequency=0.5 ): element = None try: self.log.info("Waiting for maximum :: " + str(timeout) + " :: seconds for element to be visible") wait = WebDriverWait( self.driver, timeout, poll_frequency=poll_frequency, ignored_exceptions=[NoSuchElementException, ElementNotVisibleException, ElementNotSelectableException], ) by_type = self.get_by_type(locator_type) element = wait.until(EC.invisibility_of_element_located((by_type, locator))) self.log.info("Element found") except Exception: self.log.info("Element not found") print_stack() return element def get_url(self): current_url = self.driver.current_url self.log.info("current url is: " + current_url) return current_url def go_to_url(self, url): self.driver.get(url) def go_back(self): self.driver.execute_script("window.history.go(-1)") def go_forward(self): self.driver.execute_script("window.history.go(1)") def get_attribute_value(self, locator="", locator_type="id", element=None, attribute=""): try: if locator: self.log.debug("In locator condition") element = self.get_element(locator, locator_type) attribute_value = element.get_attribute(attribute) except Exception: self.log.error( "Failed to get " + attribute + " in element with locator: " + locator + " and locator_type: " + locator_type ) print_stack() attribute_value = None return attribute_value def refresh(self): self.driver.get(self.driver.current_url) def page_has_loaded(self): try: WebDriverWait(self.driver, int(CoreConfig.SELENIUM_TIMEOUT), poll_frequency=0.5).until( lambda driver: self.driver.execute_script('return document.readyState == "complete";') ) WebDriverWait(self.driver, int(CoreConfig.SELENIUM_TIMEOUT), poll_frequency=0.5).until( lambda driver: self.driver.execute_script( 'return angular.element(document).injector().get("$http").' "pendingRequests.length === 0" ) ) self.log.info("Page is fully loaded") except Exception: return False def scroll_to_element(self, locator, locator_type): self.driver.execute_script("arguments[0].scrollIntoView(true);", self.get_element(locator, locator_type)) time.sleep(1) self.log.info("Scrolled to element: " + locator) def wait_for_url_contains(self, url_part): try: WebDriverWait( self.driver, int(CoreConfig.SELENIUM_TIMEOUT), poll_frequency=0.5, ignored_exceptions=[NoSuchElementException, ElementNotVisibleException, ElementNotSelectableException], ).until(EC.url_contains(url_part)) except Exception: print_stack() def wait_for_value_from_js(self, script, value): try: WebDriverWait(self.driver, int(CoreConfig.SELENIUM_TIMEOUT), poll_frequency=0.5).until( lambda driver: self.driver.execute_script(script == value) ) self.log.info("executed script value: " + self.driver.execute_script(script)) return value except Exception: self.log.info("executed script value: " + self.driver.execute_script(script)) def open_url(self, arg): self.driver.get(arg) self.page_has_loaded() def open_current_url_with_param(self, param): url_with_added_param = self.driver.current_url + param self.driver.get(url_with_added_param) def is_url_correct(self, correct_url): self.log.info("current url is: " + self.driver.current_url) return self.driver.current_url == correct_url def click_on_element_js(self, element): self.driver.execute_script("arguments[0].click();", element) self.page_has_loaded() def is_enabled(self, locator, locator_type="id"): try: by_type = self.get_by_type(locator_type) element = self.driver.find_element(by_type, locator) return element.is_enabled() except Exception: return False