""" Wait helper utilities for Cognitive Prism Automation Tests """ from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.common.exceptions import TimeoutException from config.config import EXPLICIT_WAIT class WaitHelpers: """Helper class for explicit waits""" def __init__(self, driver): """ Initialize WaitHelpers Args: driver: WebDriver instance """ self.driver = driver self.wait = WebDriverWait(driver, EXPLICIT_WAIT) def wait_for_element_clickable(self, locator): """ Wait for element to be clickable Args: locator: Tuple of (By, locator_string) Returns: WebElement: Clickable element """ return self.wait.until(EC.element_to_be_clickable(locator)) def wait_for_element_present(self, locator): """ Wait for element to be present in DOM Args: locator: Tuple of (By, locator_string) Returns: WebElement: Present element """ return self.wait.until(EC.presence_of_element_located(locator)) def wait_for_element_visible(self, locator, timeout=None): """ Wait for element to be visible Args: locator: Tuple of (By, locator_string) timeout: Optional timeout override (uses EXPLICIT_WAIT if not provided) Returns: WebElement: Visible element """ if timeout is not None: wait = WebDriverWait(self.driver, timeout) return wait.until(EC.visibility_of_element_located(locator)) else: return self.wait.until(EC.visibility_of_element_located(locator)) def wait_for_text_present(self, locator, text): """ Wait for text to be present in element Args: locator: Tuple of (By, locator_string) text: Text to wait for Returns: bool: True if text is present """ return self.wait.until(EC.text_to_be_present_in_element(locator, text)) def wait_for_element_invisible(self, locator, timeout=None): """ Wait for element to be invisible Args: locator: Tuple of (By, locator_string) timeout: Optional timeout override (uses EXPLICIT_WAIT if not provided) Returns: bool: True if element is invisible """ if timeout is not None: wait = WebDriverWait(self.driver, timeout) return wait.until(EC.invisibility_of_element_located(locator)) else: return self.wait.until(EC.invisibility_of_element_located(locator)) def wait_for_url_contains(self, url_part): """ Wait for URL to contain specific text Args: url_part: Part of URL to wait for Returns: bool: True if URL contains the text """ return self.wait.until(EC.url_contains(url_part)) def wait_for_page_load(self): """Wait for page to load completely (machine-speed optimized)""" # Check if already loaded - return immediately if ready if self.driver.execute_script("return document.readyState") == "complete": return # Otherwise wait, but with shorter timeout for machine-speed try: WebDriverWait(self.driver, 3).until( lambda driver: driver.execute_script("return document.readyState") == "complete" ) except TimeoutException: # Page might be interactive even if not "complete" - continue pass def wait_for_loading_to_disappear(self, timeout=None): """ Wait for loading indicator to disappear (machine-speed optimized) Args: timeout: Optional timeout override (defaults to 0.5s for machine-speed) """ # Machine-speed: Use minimal timeout (0.5s) - loading indicators disappear instantly or don't exist wait_time = timeout or 0.5 # Reduced from 2s to 0.5s for machine-speed wait = WebDriverWait(self.driver, wait_time) try: wait.until(EC.invisibility_of_element_located( (By.XPATH, "//div[contains(., 'Loading')]") )) except TimeoutException: # Loading might not be present, which is fine - don't fail pass