from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException, StaleElementReferenceException from core.config.config_manager import ConfigManager from core.utils.logger import Logger class WaitUtils: def __init__(self, driver): self.driver = driver self.config = ConfigManager() self.logger = Logger.get_logger() # 获取等待配置 self.timeout = self.config.get('browser.explicit_wait', 30) self.poll_frequency = self.config.get('browser.poll_frequency', 0.5) def _get_wait(self, timeout=None): """获取WebDriverWait实例""" timeout = timeout or self.timeout return WebDriverWait( self.driver, timeout=timeout, poll_frequency=self.poll_frequency ) def wait_for_element_present(self, locator, timeout=None): """等待元素出现在DOM中""" wait = self._get_wait(timeout) return wait.until(EC.presence_of_element_located(locator)) def wait_for_elements_present(self, locator, timeout=None): """等待多个元素出现在DOM中""" wait = self._get_wait(timeout) return wait.until(EC.presence_of_all_elements_located(locator)) def wait_for_element_visible(self, locator, timeout=None): """等待元素可见""" wait = self._get_wait(timeout) return wait.until(EC.visibility_of_element_located(locator)) def wait_for_elements_visible(self, locator, timeout=None): """等待多个元素可见""" wait = self._get_wait(timeout) return wait.until(EC.visibility_of_all_elements_located(locator)) def wait_for_element_invisible(self, locator, timeout=None): """等待元素不可见""" wait = self._get_wait(timeout) return wait.until(EC.invisibility_of_element_located(locator)) def wait_for_element_clickable(self, locator, timeout=None): """等待元素可点击""" wait = self._get_wait(timeout) return wait.until(EC.element_to_be_clickable(locator)) def wait_for_text_present_in_element(self, locator, text, timeout=None): """等待元素中包含特定文本""" wait = self._get_wait(timeout) return wait.until(EC.text_to_be_present_in_element(locator, text)) def wait_for_text_present_in_element_value(self, locator, text, timeout=None): """等待元素值中包含特定文本""" wait = self._get_wait(timeout) return wait.until(EC.text_to_be_present_in_element_value(locator, text)) def wait_for_frame_available(self, frame_locator, timeout=None): """等待框架可用并切换到该框架""" wait = self._get_wait(timeout) return wait.until(EC.frame_to_be_available_and_switch_to_it(frame_locator)) def wait_for_alert_present(self, timeout=None): """等待警报出现""" wait = self._get_wait(timeout) return wait.until(EC.alert_is_present()) def wait_for_page_loaded(self, timeout=None): """等待页面完全加载""" wait = self._get_wait(timeout) return wait.until( lambda driver: driver.execute_script('return document.readyState') == 'complete' ) def wait_for_custom_condition(self, condition, timeout=None, message=""): """等待自定义条件成立""" wait = self._get_wait(timeout) return wait.until(condition, message=message)