Source code for pytest_dash.wait_for

"""Utils methods for pytest-dash such wait_for wrappers"""
import pprint
import time

from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import By

from pytest_dash.errors import DashAppLoadingError


def _wait_for(driver, condition, timeout=10.0):
    return WebDriverWait(driver, timeout).until(condition)


def _wait_for_element(driver, by, accessor, timeout=10.0):
    return _wait_for(
        driver,
        EC.presence_of_element_located((by, accessor)),
        timeout=timeout
    )


[docs]def wait_for_element_by_css_selector(driver, selector, timeout=10.0): """ Wait until a single element is found and return it. This variant use the css selector api: https://www.w3schools.com/jsref/met_document_queryselector.asp :param driver: Selenium driver :type driver: selenium.webdriver.remote.webdriver.WebDriver :param selector: CSS selector to find. :type selector: str :param timeout: Maximum time to find the element. :type timeout: float :return: """ return _wait_for_element( driver, By.CSS_SELECTOR, selector, timeout=timeout )
[docs]def wait_for_elements_by_css_selector(driver, selector, timeout=10.0): """ Wait until all elements are found by the selector before the timeout. :param driver: Selenium driver :type driver: selenium.webdriver.remote.webdriver.WebDriver :param selector: Search for elements :type selector: str :param timeout: Maximum wait time :type timeout: float :return: Found elements """ return _wait_for( driver, EC.presence_of_all_elements_located((By.CSS_SELECTOR, selector)), timeout=timeout )
[docs]def wait_for_element_by_xpath(driver, xpath, timeout=10): """ Wait until a single element is found and return it. This variant use xpath to find the element. https://www.w3schools.com/xml/xml_xpath.asp :param driver: Selenium driver :type driver: selenium.webdriver.remote.webdriver.WebDriver :param xpath: Xpath query string. :type xpath: str :param timeout: Maximum time to find the element. :type timeout: float :return: """ return _wait_for_element(driver, By.XPATH, xpath, timeout=timeout)
[docs]def wait_for_elements_by_xpath(driver, xpath, timeout=10): """ Wait until all are found before the timeout. This variant use xpath to find the elements. https://www.w3schools.com/xml/xml_xpath.asp :param driver: Selenium driver :type driver: selenium.webdriver.remote.webdriver.WebDriver :param xpath: Xpath query string. :type xpath: str :param timeout: Maximum time to find the element. :type timeout: float :return: """ return _wait_for( driver, EC.presence_of_all_elements_located((By.XPATH, xpath)), timeout=timeout )
[docs]def wait_for_element_by_id(driver, _id, timeout=10): """ Wait until a single element is found and return it. This variant find by id. :param driver: Selenium driver :type driver: selenium.webdriver.remote.webdriver.WebDriver :param _id: The id of the element to find. :param timeout: Maximum time to find the element. :type timeout: float :return: """ return _wait_for_element(driver, By.ID, _id, timeout=timeout)
[docs]def wait_for_text_to_equal(driver, selector, text, timeout=10): """ Wait an element text found by css selector is equal to text. :param driver: Selenium driver :type driver: selenium.webdriver.remote.webdriver.WebDriver :param selector: Selector of the element to assert it's text property. :type selector: str :param text: Text to equal. :type text: str :param timeout: Maximum time for the text to equal. :type timeout: float :return: """ def condition(d): return text == d.find_element_by_css_selector(selector).text _wait_for(driver, condition, timeout=timeout)
[docs]def wait_for_style_to_equal( driver, selector, style_attribute, style_assertion, timeout=10 ): """ Wait for an element style attribute to equal. :param driver: Selenium driver :type driver: selenium.webdriver.remote.webdriver.WebDriver :param selector: Selector of the element to assert it's style property. :type selector: str :param style_attribute: The name of the CSS attribute to assert. :type style_attribute: str :param style_assertion: The value to equal of CSS attribute. :type style_assertion: str :param timeout: Maximum time. :type timeout: float :return: """ def condition(d): return style_assertion == d.find_element_by_css_selector(selector)\ .value_of_css_property(style_attribute) _wait_for(driver, condition, timeout=timeout)
[docs]def wait_for_property_to_equal( driver, selector, prop_name, prop_value, timeout=10 ): """ Wait for an element property to equal a value. :param driver: Selenium driver :type driver: selenium.webdriver.remote.webdriver.WebDriver :param selector: Selector of the element to assert it's property. :type selector: str :param prop_name: The name of property. :type prop_name: str :param prop_value: The value to assert. :param timeout: Maximum time. :type timeout: float :return: """ def condition(d): return prop_value == d.find_element_by_css_selector(selector)\ .get_property(prop_name) _wait_for(driver, condition, timeout=timeout)
def _wait_for_client_app_started(driver, url, wait_time=0.5, timeout=10): # Wait until the #_dash-app-content element is loaded. start_time = time.time() loading_errors = ( 'Error loading layout', 'Error loading dependencies', 'Internal Server Error', ) while True: try: driver.get(url) wait_for_element_by_css_selector( driver, '#_dash-app-content', timeout=wait_time ) return except TimeoutException: body = wait_for_element_by_css_selector(driver, 'body') if any(x in body.text for x in loading_errors) \ or time.time() - start_time > timeout: logs = driver.get_log('browser') raise DashAppLoadingError( 'Dash could not start after {}:' ' \nHTML:\n {}\n\nLOGS: {}'.format( timeout, body.get_property('innerHTML'), pprint.pformat(logs) ) )