162 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			162 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								# pylint: disable=too-few-public-methods
							 | 
						||
| 
								 | 
							
								"""Utils methods for pytest-dash such wait_for wrappers."""
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import time
							 | 
						||
| 
								 | 
							
								import logging
							 | 
						||
| 
								 | 
							
								from selenium.common.exceptions import WebDriverException
							 | 
						||
| 
								 | 
							
								from selenium.webdriver.common.by import By
							 | 
						||
| 
								 | 
							
								from dash.testing.errors import TestingTimeoutError
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								logger = logging.getLogger(__name__)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def until(
							 | 
						||
| 
								 | 
							
								    wait_cond, timeout, poll=0.1, msg="expected condition not met within timeout"
							 | 
						||
| 
								 | 
							
								):  # noqa: C0330
							 | 
						||
| 
								 | 
							
								    res = wait_cond()
							 | 
						||
| 
								 | 
							
								    logger.debug(
							 | 
						||
| 
								 | 
							
								        "start wait.until with method, timeout, poll => %s %s %s",
							 | 
						||
| 
								 | 
							
								        wait_cond,
							 | 
						||
| 
								 | 
							
								        timeout,
							 | 
						||
| 
								 | 
							
								        poll,
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								    end_time = time.time() + timeout
							 | 
						||
| 
								 | 
							
								    while not res:
							 | 
						||
| 
								 | 
							
								        if time.time() > end_time:
							 | 
						||
| 
								 | 
							
								            raise TestingTimeoutError(msg)
							 | 
						||
| 
								 | 
							
								        time.sleep(poll)
							 | 
						||
| 
								 | 
							
								        res = wait_cond()
							 | 
						||
| 
								 | 
							
								        logger.debug("poll => %s", time.time())
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return res
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def until_not(
							 | 
						||
| 
								 | 
							
								    wait_cond, timeout, poll=0.1, msg="expected condition met within timeout"
							 | 
						||
| 
								 | 
							
								):  # noqa: C0330
							 | 
						||
| 
								 | 
							
								    res = wait_cond()
							 | 
						||
| 
								 | 
							
								    logger.debug(
							 | 
						||
| 
								 | 
							
								        "start wait.until_not method, timeout, poll => %s %s %s",
							 | 
						||
| 
								 | 
							
								        wait_cond,
							 | 
						||
| 
								 | 
							
								        timeout,
							 | 
						||
| 
								 | 
							
								        poll,
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								    end_time = time.time() + timeout
							 | 
						||
| 
								 | 
							
								    while res:
							 | 
						||
| 
								 | 
							
								        if time.time() > end_time:
							 | 
						||
| 
								 | 
							
								            raise TestingTimeoutError(msg)
							 | 
						||
| 
								 | 
							
								        time.sleep(poll)
							 | 
						||
| 
								 | 
							
								        res = wait_cond()
							 | 
						||
| 
								 | 
							
								        logger.debug("poll => %s", time.time())
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return res
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class contains_text:
							 | 
						||
| 
								 | 
							
								    def __init__(self, selector, text, timeout):
							 | 
						||
| 
								 | 
							
								        self.selector = selector
							 | 
						||
| 
								 | 
							
								        self.text = text
							 | 
						||
| 
								 | 
							
								        self.timeout = timeout
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __call__(self, driver):
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            elem = driver.find_element(By.CSS_SELECTOR, self.selector)
							 | 
						||
| 
								 | 
							
								            logger.debug("contains text {%s} => expected %s", elem.text, self.text)
							 | 
						||
| 
								 | 
							
								            value = elem.get_attribute("value")
							 | 
						||
| 
								 | 
							
								            return self.text in str(elem.text) or (
							 | 
						||
| 
								 | 
							
								                value is not None and self.text in str(value)
							 | 
						||
| 
								 | 
							
								            )
							 | 
						||
| 
								 | 
							
								        except WebDriverException:
							 | 
						||
| 
								 | 
							
								            return False
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def message(self, driver):
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            element = self._get_element(driver)
							 | 
						||
| 
								 | 
							
								            text = "found: " + str(element.text) or str(element.get_attribute("value"))
							 | 
						||
| 
								 | 
							
								        except WebDriverException:
							 | 
						||
| 
								 | 
							
								            text = f"{self.selector} not found"
							 | 
						||
| 
								 | 
							
								        return f"text -> {self.text} not found inside element within {self.timeout}s, {text}"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def _get_element(self, driver):
							 | 
						||
| 
								 | 
							
								        return driver.find_element(By.CSS_SELECTOR, self.selector)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class contains_class:
							 | 
						||
| 
								 | 
							
								    def __init__(self, selector, classname):
							 | 
						||
| 
								 | 
							
								        self.selector = selector
							 | 
						||
| 
								 | 
							
								        self.classname = classname
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __call__(self, driver):
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            elem = driver.find_element(By.CSS_SELECTOR, self.selector)
							 | 
						||
| 
								 | 
							
								            classname = elem.get_attribute("class")
							 | 
						||
| 
								 | 
							
								            logger.debug(
							 | 
						||
| 
								 | 
							
								                "contains class {%s} => expected %s", classname, self.classname
							 | 
						||
| 
								 | 
							
								            )
							 | 
						||
| 
								 | 
							
								            return self.classname in str(classname).split(" ")
							 | 
						||
| 
								 | 
							
								        except WebDriverException:
							 | 
						||
| 
								 | 
							
								            return False
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class text_to_equal:
							 | 
						||
| 
								 | 
							
								    def __init__(self, selector, text, timeout):
							 | 
						||
| 
								 | 
							
								        self.selector = selector
							 | 
						||
| 
								 | 
							
								        self.text = text
							 | 
						||
| 
								 | 
							
								        self.timeout = timeout
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __call__(self, driver):
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            elem = self._get_element(driver)
							 | 
						||
| 
								 | 
							
								            logger.debug("text to equal {%s} => expected %s", elem.text, self.text)
							 | 
						||
| 
								 | 
							
								            value = elem.get_attribute("value")
							 | 
						||
| 
								 | 
							
								            return str(elem.text) == self.text or (
							 | 
						||
| 
								 | 
							
								                value is not None and str(value) == self.text
							 | 
						||
| 
								 | 
							
								            )
							 | 
						||
| 
								 | 
							
								        except WebDriverException:
							 | 
						||
| 
								 | 
							
								            return False
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def message(self, driver):
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            element = self._get_element(driver)
							 | 
						||
| 
								 | 
							
								            text = "found: " + str(element.text) or str(element.get_attribute("value"))
							 | 
						||
| 
								 | 
							
								        except WebDriverException:
							 | 
						||
| 
								 | 
							
								            text = f"{self.selector} not found"
							 | 
						||
| 
								 | 
							
								        return f"text -> {self.text} not found within {self.timeout}s, {text}"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def _get_element(self, driver):
							 | 
						||
| 
								 | 
							
								        return driver.find_element(By.CSS_SELECTOR, self.selector)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class style_to_equal:
							 | 
						||
| 
								 | 
							
								    def __init__(self, selector, style, val):
							 | 
						||
| 
								 | 
							
								        self.selector = selector
							 | 
						||
| 
								 | 
							
								        self.style = style
							 | 
						||
| 
								 | 
							
								        self.val = val
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __call__(self, driver):
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            elem = driver.find_element(By.CSS_SELECTOR, self.selector)
							 | 
						||
| 
								 | 
							
								            val = elem.value_of_css_property(self.style)
							 | 
						||
| 
								 | 
							
								            logger.debug("style to equal {%s} => expected %s", val, self.val)
							 | 
						||
| 
								 | 
							
								            return val == self.val
							 | 
						||
| 
								 | 
							
								        except WebDriverException:
							 | 
						||
| 
								 | 
							
								            return False
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class class_to_equal:
							 | 
						||
| 
								 | 
							
								    def __init__(self, selector, classname):
							 | 
						||
| 
								 | 
							
								        self.selector = selector
							 | 
						||
| 
								 | 
							
								        self.classname = classname
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __call__(self, driver):
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            elem = driver.find_element(By.CSS_SELECTOR, self.selector)
							 | 
						||
| 
								 | 
							
								            classname = elem.get_attribute("class")
							 | 
						||
| 
								 | 
							
								            logger.debug(
							 | 
						||
| 
								 | 
							
								                "class to equal {%s} => expected %s", classname, self.classname
							 | 
						||
| 
								 | 
							
								            )
							 | 
						||
| 
								 | 
							
								            return str(classname) == self.classname
							 | 
						||
| 
								 | 
							
								        except WebDriverException:
							 | 
						||
| 
								 | 
							
								            return False
							 |