def test_browserHelper_log(logType): BrowserHelperFunction.browserHelper_log(logType, "Log Text", MagicMock(), MagicMock, extra="test") assert 1 == 1
def goBack(self): """ Method to go 1 step back in current tab's browse history @return: """ self.statistics.update_teststep() try: self.javaScript("window.history.go(-1)") except Exception as e: helper.browserHelper_log( logging.WARNING, f"Tried to go back in history, didn't work with error {e}", self.browserData)
def findWaitNotVisible(self, css=None, xpath=None, id=None, timeout=90, optional=False): """ You'd use this method when you wait for an element to disappear, for instance Angular Spinner or a popup to disapear before you continue with your script in the main screen. """ self.statistics.update_teststep() logger.debug( f"Waiting for Element to disappear: XPATH:{xpath}, timeout: {timeout}" ) time.sleep(0.5) stillHere = True elapsed = 0 begin = time.time() while stillHere and elapsed < timeout: try: if xpath: self.element = self.browserData.driver.find_element_by_xpath( xpath) elif id: self.element = self.browserData.driver.find_element_by_id( id) elif css: self.element = self.browserData.driver.find_element_by_css_selector( css) time.sleep(0.2) elapsed = time.time() - begin except Exception as e: # Element gone - exit stillHere = False helper.browserHelper_log( logging.DEBUG, f"Element was gone after {format(elapsed, '.2f')} seconds", self.browserData) if not stillHere: raise Exceptions.baangtTestStepException( f"Element still here after {timeout} seconds. Locator: xpath={xpath}, id={id}" ) return stillHere
def findByAndSetTextValidated(self, id=None, css=None, xpath=None, class_name=None, value=None, iframe=None, timeout=60, retries=5): """ This is a method not recommended to be used regularly. Sometimes (especially with Angular Frontends) it gets pretty hard to set a value into a field. Chrome, but also FF will show the value, but the DOM will not have it. Ths Method should be your last ressort. Here we try <retries> time to set a value. Then we read the element again and compare value to what we'd expect. If value is different and we're less than <retries>-Times, we'll try again. """ tries = 0 self.element, self.html = self.findBy(id=id, css=css, xpath=xpath, class_name=class_name, iframe=iframe, timeout=timeout) while self.element.text != value and self.element.get_property( "value") != value and tries < retries: helper.browserHelper_log( logging.DEBUG, f"Verified trying of SetText - iteration {tries} of {retries}", self.browserData) self.findByAndForceText(id=id, css=css, xpath=xpath, class_name=class_name, iframe=iframe, value=value, timeout=timeout) self.element, self.html = self.findBy(id=id, css=css, xpath=xpath, class_name=class_name, iframe=iframe, timeout=timeout) tries += 1
def goToUrl(self, url): self.statistics.update_teststep() helper.browserHelper_log(logging.INFO, f'GoToUrl:{url}', self.browserData) try: if self.browserName == GC.BROWSER_FIREFOX: self.browserData.driver.set_context("content") self.browserData.driver.get(url) self.setZoomFactor() except WebDriverException as e: # Use noScreenshot-Parameter as otherwise we'll try on a dead browser to create a screenshot helper.browserHelper_log( logging.ERROR, f"Webpage {url} not reached. Error was: {e}", self.browserData, cbTakeScreenshot=self.takeScreenshot) helper.browserHelper_setProxyError(self.randomProxy) raise Exceptions.baangtTestStepException except Exception as e: # Use noScreenshot-Parameter as otherwise we'll try on a dead browser to create a screenshot helper.browserHelper_log(logging.ERROR, f"Webpage {url} throws error {e}", self.browserData, cbTakeScreenshot=self.takeScreenshot) helper.browserHelper_setProxyError(self.randomProxy) raise Exceptions.baangtTestStepException(url, e)
def takeScreenshot(self, screenShotPath=None): driver = self.browserData.driver # Filename must have ".png" inside lFile = str(uuid.uuid4()) + ".png" if screenShotPath: lFile = Path(screenShotPath).joinpath(lFile) else: lFile = Path(self.screenshotPath).joinpath(lFile) try: lFile = str(lFile) driver.save_screenshot(lFile) helper.browserHelper_log(logging.DEBUG, f"Stored Screenshot: {lFile}", self.browserData) except Exception as e: helper.browserHelper_log(logging.INFO, f"Screenshot not possible. Error: {e}", self.browserData) lFile = None return lFile
def handleIframe(self, iframe=None): """ Give an IFRAME and it will try to go into. If you're inside an iframe it will go out of the iframe """ self.statistics.update_teststep() if iframe: self.browserData.locatorType = "XPATH" self.browserData.locator = iframe helper.browserHelper_log(logging.DEBUG, "Going into Iframe: ", self.browserData, **{"iframe": iframe}) # frame_to_be_availble_and_switch_to_it doesn't work. mustEnd = time.time() + 30 while time.time() < mustEnd: try: self.browserData.driver.switch_to.default_content() self.iFrame = self.browserData.driver.switch_to.frame( iframe) break except WebDriverException as e: helper.browserHelper_log( logging.DEBUG, f"IFrame {iframe} not there yet - waiting 1 second", self.browserData) time.sleep(1) if time.time() > mustEnd: raise TimeoutError elif self.iFrame: helper.browserHelper_log(logging.DEBUG, f"Leaving Iframe: {self.iFrame}", self.browserData) self.browserData.driver.switch_to.default_content() self.iFrame = None else: # TODO add exception, this code should never be reached pass
def webdriver_doSomething(command, element, value=None, timeout=20, optional=False, browserData=None): """ Will interact in an element (that was found before by findBy-Method and stored in self.element) as defined by ``command``. Command can be "SETTEXT" (GC.CMD_SETTEXT), "CLICK" (GC.CMD_CLICK), "FORCETEXT" (GC.CMD_FORCETEXT). Similarly to __try_and_retry the method is pretty robust when it comes to error handling of timing issues. """ NUMBER_OF_SEND_KEY_BACKSPACE = 10 COUNTER_LIMIT_RETRY = 2 COUNTER_LIMIT_ELEMENT_REF = 4 COUNTER_LIMIT_ELEMENT_NOT_INTERACT = 5 didWork = False elapsed = 0 counter = 0 begin = time.time() while not didWork and elapsed < timeout: counter += 1 logger.debug(f"__doSomething {command} with {value}") try: if command.upper() == GC.CMD_SETTEXT: if not value: value = "" element.send_keys(value) elif command.upper() == GC.CMD_CLICK: element.click() elif command.upper() == GC.CMD_FORCETEXT: element.clear() element.click() # element.send_keys(keys.Keys.CONTROL+"A") # for i in range(0, NUMBER_OF_SEND_KEY_BACKSPACE): # element.send_keys(keys.Keys.BACKSPACE) element.send_keys(value) element.send_keys(keys.Keys.TAB) didWork = True except ElementClickInterceptedException as e: logger.debug("doSomething: Element intercepted - retry") time.sleep(0.2) except StaleElementReferenceException as e: logger.debug( f"doSomething: Element stale - retry {browserData.locatorType} {browserData.locator}" ) # If the element is stale after 2 times, try to re-locate the element if counter < COUNTER_LIMIT_RETRY: time.sleep(0.2) elif counter < COUNTER_LIMIT_ELEMENT_REF: begin, element = WebdriverFunctions.webdriver_refindElementAfterError( browserData, timeout, optional=optional) else: raise Exceptions.baangtTestStepException(e) except NoSuchElementException as e: logger.debug("doSomething: Element not there yet - retry") time.sleep(0.5) except InvalidSessionIdException as e: helper.browserHelper_log( logging.ERROR, f"Invalid Session ID Exception caught - aborting... {e} ", browserData) raise Exceptions.baangtTestStepException(e) except ElementNotInteractableException as e: if counter < COUNTER_LIMIT_RETRY: logger.debug( f"Element not interactable {browserData.locatorType} {browserData.locator}, retrying" ) time.sleep(0.2) elif counter < COUNTER_LIMIT_ELEMENT_NOT_INTERACT: logger.debug( f"Element not interactable {browserData.locatorType} {browserData.locator}, re-finding element" ) begin, element = WebdriverFunctions.webdriver_refindElementAfterError( browserData, timeout, optional=optional) else: helper.browserHelper_log(logging.ERROR, f"Element not interactable {e}", browserData) raise Exceptions.baangtTestStepException(e) except NoSuchWindowException as e: raise Exceptions.baangtTestStepException(e) elapsed = time.time() - begin if not didWork: if optional: logger.debug( f"Action not possible after {timeout} s, Locator: {browserData.locatorType}: {browserData.locator}, but flag 'optional' is set" ) else: raise Exceptions.baangtTestStepException( f"Action not possible after {timeout} s, Locator: {browserData.locatorType}: {browserData.locator}" ) else: # Function successful pass return didWork
def webdriver_tryAndRetry(browserData, timeout=20, optional=False): """ In: Locator Out: Boolean whether the element was found or not. Also sets the self.element for further use by other Methods (for instance to setText or read existing value) The method is resistant to common timing problems (can't work 100% of the time but will remove at least 80% of your pain compared to directly calling Selenium Methods). """ REQUEST_TIMEOUT_MINIMUM = 1.5 REQUEST_POLL_FREQUENCY = 0.5 element = None html = None begin = time.time() elapsed = 0 if timeout < REQUEST_TIMEOUT_MINIMUM: pollFrequency = timeout / 3 else: pollFrequency = REQUEST_POLL_FREQUENCY internalTimeout = timeout / 5 lLoopCount = 0 try: html = WebdriverFunctions.webdriver_getCurrentHTMLReference( browserData.driver) except BaseException as e: raise Exceptions.baangtTestStepException( f"__getCurrentHTMLReference was not successful: {e}") while not element and elapsed < timeout: lLoopCount += 1 try: driverWait = WebDriverWait(browserData.driver, timeout=internalTimeout, poll_frequency=pollFrequency) if By.ID == browserData.locatorType or By.CSS_SELECTOR == browserData.locatorType: element = driverWait.until( ec.visibility_of_element_located( (browserData.locatorType, browserData.locator))) elif By.CLASS_NAME == browserData.locatorType: element = browserData.driver.find_element_by_class_name( browserData.locator) elif By.XPATH == browserData.locatorType: # visibility of element sometimes not true, but still clickable. If we tried already # 2 times with visibility, let's give it one more try with Presence of element if lLoopCount > 1: logger.debug( f"Tried 2 times to find visible element, now trying presence " f"of element instead, XPATH = {browserData.locator}" ) element = driverWait.until( ec.presence_of_element_located( (browserData.locatorType, browserData.locator))) else: element = driverWait.until( ec.visibility_of_element_located( (browserData.locatorType, browserData.locator))) except StaleElementReferenceException as e: logger.debug("Stale Element Exception - retrying " + str(e)) time.sleep(pollFrequency) except ElementClickInterceptedException as e: logger.debug("ElementClickIntercepted - retrying " + str(e)) time.sleep(pollFrequency) except TimeoutException as e: logger.debug("TimoutException - retrying " + str(e)) time.sleep(pollFrequency) except NoSuchElementException as e: logger.debug("Retrying Webdriver Exception: " + str(e)) time.sleep(pollFrequency) except InvalidSessionIdException as e: logger.debug("WebDriver Exception - terminating testrun: " + str(e)) raise Exceptions.baangtTestStepException except NoSuchWindowException as e: helper.browserHelper_log( logging.CRITICAL, "WebDriver Exception - terminating testrun: " + str(e), browserData) raise Exceptions.baangtTestStepException except ElementNotInteractableException as e: logger.debug("Most probably timeout exception - retrying: " + str(e)) time.sleep(pollFrequency) except WebDriverException as e: helper.browserHelper_log( logging.ERROR, "Retrying WebDriver Exception: " + str(e), browserData) time.sleep(2) elapsed = time.time() - begin return element, html