def wait_for_ready_state_complete(driver, timeout=settings.LARGE_TIMEOUT): """ The DOM (Document Object Model) has a property called "readyState". When the value of this becomes "complete", page resources are considered fully loaded (although AJAX and other loads might still be happening). This method will wait until document.readyState == "complete". This may be redundant, as methods already wait for page elements to load. If the timeout is exceeded, the test will still continue because readyState == "interactive" may be good enough. (Previously, tests would fail immediately if exceeding the timeout.) """ start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() try: ready_state = driver.execute_script("return document.readyState") except WebDriverException: # Bug fix for: [Permission denied to access property "document"] time.sleep(0.03) return True if ready_state == "complete": time.sleep(0.01) # Better be sure everything is done loading return True else: now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) return False # readyState stayed "interactive" (Not "complete")
def wait_for_text_not_visible(driver, text, selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT): """ Searches for the text in the element of the given selector on the page. Returns True if the text is not visible on the page within the timeout. Raises an exception if the text is still present after the timeout. @Params driver - the webdriver object (required) text - the text that is being searched for in the element (required) selector - the locator for identifying the page element (required) by - the type of selector being used (Default: By.CSS_SELECTOR) timeout - the time to wait for elements in seconds @Returns A web element object that contains the text searched for """ start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() if not is_text_visible(driver, text, selector, by=by): return True now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) plural = "s" if timeout == 1: plural = "" raise Exception("Text {%s} in {%s} was still visible after %s " "second%s!" % (text, selector, timeout, plural))
def wait_for_element_not_visible(driver, selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT): """ Searches for the specified element by the given selector. Raises an exception if the element is still visible after the specified timeout. @Params driver - the webdriver object (required) selector - the locator for identifying the page element (required) by - the type of selector being used (Default: By.CSS_SELECTOR) timeout - the time to wait for the element in seconds """ start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() try: element = driver.find_element(by=by, value=selector) if element.is_displayed(): now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) else: return True except Exception: return True plural = "s" if timeout == 1: plural = "" raise Exception("Element {%s} was still visible after %s second%s!" % (selector, timeout, plural))
def wait_for_element_present(driver, selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT): """ Searches for the specified element by the given selector. Returns the element object if the element is present on the page. The element can be invisible. Raises an exception if the element does not appear in the specified timeout. @Params driver - the webdriver object selector - the locator for identifying the page element (required) by - the type of selector being used (Default: By.CSS_SELECTOR) timeout - the time to wait for elements in seconds @Returns A web element object """ element = None start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() try: element = driver.find_element(by=by, value=selector) return element except Exception: now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) if not element: raise NoSuchElementException( "Element {%s} was not present after %s seconds!" % (selector, timeout))
def wait_for_and_switch_to_alert(driver, timeout=settings.LARGE_TIMEOUT): """ Wait for a browser alert to appear, and switch to it. This should be usable as a drop-in replacement for driver.switch_to.alert when the alert box may not exist yet. @Params driver - the webdriver object (required) timeout - the time to wait for the alert in seconds """ start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): s_utils.check_if_time_limit_exceeded() try: alert = driver.switch_to.alert # Raises exception if no alert present dummy_variable = alert.text # noqa return alert except NoAlertPresentException: now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) message = ("Alert was not present after %s seconds!" % timeout) timeout_exception(Exception, message)
def wait_for_ready_state_complete(driver, timeout=settings.EXTREME_TIMEOUT): """ The DOM (Document Object Model) has a property called "readyState". When the value of this becomes "complete", page resources are considered fully loaded (although AJAX and other loads might still be happening). This method will wait until document.readyState == "complete". """ start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() try: # If there's an alert, skip driver.switch_to.alert return except Exception: # If there's no alert, continue pass try: ready_state = driver.execute_script("return document.readyState") except WebDriverException: # Bug fix for: [Permission denied to access property "document"] time.sleep(0.03) return True if ready_state == u'complete': time.sleep(0.01) # Better be sure everything is done loading return True else: now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) raise Exception("Page elements never fully loaded after %s seconds!" % timeout)
def switch_to_frame(driver, frame, timeout=settings.SMALL_TIMEOUT): """ Wait for an iframe to appear, and switch to it. This should be usable as a drop-in replacement for driver.switch_to.frame(). @Params driver - the webdriver object (required) frame - the frame element, name, id, index, or selector timeout - the time to wait for the alert in seconds """ start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() try: driver.switch_to.frame(frame) return True except NoSuchFrameException: if type(frame) is str: by = None if page_utils.is_xpath_selector(frame): by = By.XPATH else: by = By.CSS_SELECTOR if is_element_visible(driver, frame, by=by): try: element = driver.find_element(by=by, value=frame) driver.switch_to.frame(element) return True except Exception: pass now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) raise Exception("Frame was not present after %s seconds!" % timeout)
def wait_for_text_visible(driver, text, selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT): """ Searches for the specified element by the given selector. Returns the element object if the text is present in the element and visible on the page. Raises NoSuchElementException if the element does not exist in the HTML within the specified timeout. Raises ElementNotVisibleException if the element exists in the HTML, but the text is not visible within the specified timeout. @Params driver - the webdriver object (required) text - the text that is being searched for in the element (required) selector - the locator for identifying the page element (required) by - the type of selector being used (Default: By.CSS_SELECTOR) timeout - the time to wait for elements in seconds @Returns A web element object that contains the text searched for """ element = None is_present = False start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): s_utils.check_if_time_limit_exceeded() try: element = driver.find_element(by=by, value=selector) is_present = True if element.is_displayed() and text in element.text: return element else: element = None raise Exception() except Exception: now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) plural = "s" if timeout == 1: plural = "" if not element: if not is_present: # The element does not exist in the HTML message = "Element {%s} was not present after %s second%s!" % ( selector, timeout, plural, ) timeout_exception(NoSuchElementException, message) # The element exists in the HTML, but the text is not visible message = ( "Expected text {%s} for {%s} was not visible after %s second%s!" % (text, selector, timeout, plural)) timeout_exception(ElementNotVisibleException, message)
def switch_to_window(driver, window, timeout=settings.SMALL_TIMEOUT): """ Wait for a window to appear, and switch to it. This should be usable as a drop-in replacement for driver.switch_to.window(). @Params driver - the webdriver object (required) window - the window index or window handle timeout - the time to wait for the window in seconds """ start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) if isinstance(window, int): for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() try: window_handle = driver.window_handles[window] driver.switch_to.window(window_handle) return True except IndexError: now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) plural = "s" if timeout == 1: plural = "" message = "Window {%s} was not present after %s second%s!" "" % ( window, timeout, plural, ) timeout_exception(Exception, message) else: window_handle = window for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() try: driver.switch_to.window(window_handle) return True except NoSuchWindowException: now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) plural = "s" if timeout == 1: plural = "" message = "Window {%s} was not present after %s second%s!" "" % ( window, timeout, plural, ) timeout_exception(Exception, message)
def wait_for_element_visible(driver, selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT): """ Searches for the specified element by the given selector. Returns the element object if the element is present and visible on the page. Raises an exception if the element does not appear in the specified timeout. @Params driver - the webdriver object (required) selector - the locator for identifying the page element (required) by - the type of selector being used (Default: By.CSS_SELECTOR) timeout - the time to wait for elements in seconds @Returns A web element object """ element = None start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() try: element = driver.find_element(by=by, value=selector) if element.is_displayed(): return element else: element = None raise Exception() except Exception: now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) plural = "s" if timeout == 1: plural = "" if not element and by != By.LINK_TEXT: message = "Element {%s} was not visible after %s second%s!" "" % ( selector, timeout, plural, ) timeout_exception(ElementNotVisibleException, message) if not element and by == By.LINK_TEXT: message = "Link text {%s} was not visible after %s second%s!" "" % ( selector, timeout, plural, ) timeout_exception(ElementNotVisibleException, message)
def wait_for_element_present( driver, selector, by="css selector", timeout=settings.LARGE_TIMEOUT, original_selector=None, ): """ Searches for the specified element by the given selector. Returns the element object if it exists in the HTML. (The element can be invisible.) Raises NoSuchElementException if the element does not exist in the HTML within the specified timeout. @Params driver - the webdriver object selector - the locator for identifying the page element (required) by - the type of selector being used (Default: By.CSS_SELECTOR) timeout - the time to wait for elements in seconds original_selector - handle pre-converted ":contains(TEXT)" selector @Returns A web element object """ element = None start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() try: element = driver.find_element(by=by, value=selector) return element except Exception: now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) plural = "s" if timeout == 1: plural = "" if not element: if (original_selector and ":contains(" in original_selector and "contains(." in selector): selector = original_selector message = "Element {%s} was not present after %s second%s!" % ( selector, timeout, plural, ) timeout_exception(NoSuchElementException, message) else: return element
def wait_for_exact_text_visible(driver, text, selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT): """ Searches for the specified element by the given selector. Returns the element object if the text matches exactly with the text in the element, and the text is visible. Raises an exception if the text or element do not appear in the specified timeout. @Params driver - the webdriver object (required) text - the exact text that is expected for the element (required) selector - the locator for identifying the page element (required) by - the type of selector being used (Default: By.CSS_SELECTOR) timeout - the time to wait for elements in seconds @Returns A web element object that contains the text searched for """ element = None start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() try: element = driver.find_element(by=by, value=selector) if element.is_displayed() and text.strip() == element.text.strip(): return element else: element = None raise Exception() except Exception: now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) plural = "s" if timeout == 1: plural = "" if not element: message = "Expected exact text {%s} for {%s} was not visible " "after %s second%s!" % ( text, selector, timeout, plural, ) timeout_exception(ElementNotVisibleException, message)
def wait_for_attribute_not_present( driver, selector, attribute, value=None, by="css selector", timeout=settings.LARGE_TIMEOUT, ): """ Searches for the specified element attribute by the given selector. Returns True if the attribute isn't present on the page within the timeout. Also returns True if the element is not present within the timeout. Raises an exception if the attribute is still present after the timeout. @Params driver - the webdriver object (required) selector - the locator for identifying the page element (required) attribute - the element attribute (required) value - the attribute value (Default: None) by - the type of selector being used (Default: By.CSS_SELECTOR) timeout - the time to wait for the element attribute in seconds """ start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() if not is_attribute_present( driver, selector, attribute, value=value, by=by): return True now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) plural = "s" if timeout == 1: plural = "" message = ( "Attribute {%s} of element {%s} was still present after %s second%s!" "" % (attribute, selector, timeout, plural)) if value: message = ( "Value {%s} for attribute {%s} of element {%s} was still present " "after %s second%s!" "" % (value, attribute, selector, timeout, plural)) timeout_exception(Exception, message)
def wait_for_element_absent( driver, selector, by="css selector", timeout=settings.LARGE_TIMEOUT, original_selector=None, ): """ Searches for the specified element by the given selector. Raises an exception if the element is still present after the specified timeout. @Params driver - the webdriver object selector - the locator for identifying the page element (required) by - the type of selector being used (Default: By.CSS_SELECTOR) timeout - the time to wait for elements in seconds original_selector - handle pre-converted ":contains(TEXT)" selector """ start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() try: driver.find_element(by=by, value=selector) now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) except Exception: return True plural = "s" if timeout == 1: plural = "" if (original_selector and ":contains(" in original_selector and "contains(." in selector): selector = original_selector message = "Element {%s} was still present after %s second%s!" % ( selector, timeout, plural, ) timeout_exception(Exception, message)
def wait_for_attribute( driver, selector, attribute, value=None, by="css selector", timeout=settings.LARGE_TIMEOUT, ): """ Searches for the specified element attribute by the given selector. Returns the element object if the expected attribute is present and the expected attribute value is present (if specified). Raises NoSuchElementException if the element does not exist in the HTML within the specified timeout. Raises NoSuchAttributeException if the element exists in the HTML, but the expected attribute/value is not present within the timeout. @Params driver - the webdriver object (required) selector - the locator for identifying the page element (required) attribute - the attribute that is expected for the element (required) value - the attribute value that is expected (Default: None) by - the type of selector being used (Default: By.CSS_SELECTOR) timeout - the time to wait for the element attribute in seconds @Returns A web element object that contains the expected attribute/value """ element = None element_present = False attribute_present = False found_value = None start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() try: element = driver.find_element(by=by, value=selector) element_present = True attribute_present = False found_value = element.get_attribute(attribute) if found_value is not None: attribute_present = True else: element = None raise Exception() if value is not None: if found_value == value: return element else: element = None raise Exception() else: return element except Exception: now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) plural = "s" if timeout == 1: plural = "" if not element: if not element_present: # The element does not exist in the HTML message = "Element {%s} was not present after %s second%s!" % ( selector, timeout, plural, ) timeout_exception(NoSuchElementException, message) if not attribute_present: # The element does not have the attribute message = ( "Expected attribute {%s} of element {%s} was not present " "after %s second%s!" % (attribute, selector, timeout, plural)) timeout_exception(NoSuchAttributeException, message) # The element attribute exists, but the expected value does not match message = ( "Expected value {%s} for attribute {%s} of element {%s} was not " "present after %s second%s! (The actual value was {%s})" % (value, attribute, selector, timeout, plural, found_value)) timeout_exception(NoSuchAttributeException, message) else: return element
def wait_for_exact_text_visible( driver, text, selector, by="css selector", timeout=settings.LARGE_TIMEOUT, browser=None, ): """ Searches for the specified element by the given selector. Returns the element object if the text matches exactly with the text in the element, and the text is visible. Raises NoSuchElementException if the element does not exist in the HTML within the specified timeout. Raises ElementNotVisibleException if the element exists in the HTML, but the exact text is not visible within the specified timeout. @Params driver - the webdriver object (required) text - the exact text that is expected for the element (required) selector - the locator for identifying the page element (required) by - the type of selector being used (Default: By.CSS_SELECTOR) timeout - the time to wait for elements in seconds browser - used to handle a special edge case when using Safari @Returns A web element object that contains the text searched for """ element = None is_present = False actual_text = None start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() actual_text = None try: element = driver.find_element(by=by, value=selector) is_present = True if element.tag_name == "input": if (element.is_displayed() and text.strip() == element.get_property("value").strip()): return element else: if element.is_displayed(): actual_text = element.get_property("value").strip() element = None raise Exception() elif browser == "safari": if element.is_displayed() and ( text.strip() == element.get_attribute("innerText").strip()): return element else: if element.is_displayed(): actual_text = element.get_attribute("innerText") actual_text = actual_text.strip() element = None raise Exception() else: if (element.is_displayed() and text.strip() == element.text.strip()): return element else: if element.is_displayed(): actual_text = element.text.strip() element = None raise Exception() except Exception: now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) plural = "s" if timeout == 1: plural = "" if not element: if not is_present: # The element does not exist in the HTML message = "Element {%s} was not present after %s second%s!" % ( selector, timeout, plural, ) timeout_exception(NoSuchElementException, message) # The element exists in the HTML, but the exact text is not visible message = None if not actual_text or len(str(actual_text)) > 120: message = ("Expected exact text {%s} for {%s} was not visible " "after %s second%s!" % (text, selector, timeout, plural)) else: actual_text = actual_text.replace("\n", "\\n") message = ("Expected exact text {%s} for {%s} was not visible " "after %s second%s!\n (Actual text was {%s})" % (text, selector, timeout, plural, actual_text)) timeout_exception(TextNotVisibleException, message) else: return element
def wait_for_element_visible( driver, selector, by="css selector", timeout=settings.LARGE_TIMEOUT, original_selector=None, ): """ Searches for the specified element by the given selector. Returns the element object if the element is present and visible on the page. Raises NoSuchElementException if the element does not exist in the HTML within the specified timeout. Raises ElementNotVisibleException if the element exists in the HTML, but is not visible (eg. opacity is "0") within the specified timeout. @Params driver - the webdriver object (required) selector - the locator for identifying the page element (required) by - the type of selector being used (Default: By.CSS_SELECTOR) timeout - the time to wait for elements in seconds original_selector - handle pre-converted ":contains(TEXT)" selector @Returns A web element object """ element = None is_present = False start_ms = time.time() * 1000.0 stop_ms = start_ms + (timeout * 1000.0) for x in range(int(timeout * 10)): shared_utils.check_if_time_limit_exceeded() try: element = driver.find_element(by=by, value=selector) is_present = True if element.is_displayed(): return element else: element = None raise Exception() except Exception: now_ms = time.time() * 1000.0 if now_ms >= stop_ms: break time.sleep(0.1) plural = "s" if timeout == 1: plural = "" if not element and by != By.LINK_TEXT: if (original_selector and ":contains(" in original_selector and "contains(." in selector): selector = original_selector if not is_present: # The element does not exist in the HTML message = "Element {%s} was not present after %s second%s!" % ( selector, timeout, plural, ) timeout_exception(NoSuchElementException, message) # The element exists in the HTML, but is not visible message = "Element {%s} was not visible after %s second%s!" % ( selector, timeout, plural, ) timeout_exception(ElementNotVisibleException, message) elif not element and by == By.LINK_TEXT: message = "Link text {%s} was not visible after %s second%s!" % ( selector, timeout, plural, ) timeout_exception(ElementNotVisibleException, message) else: return element