selenium --显示等待高级使用

显示等待原理

  • 在代码中定义等待一定条件发生后(一般指js/css代码调用这段过程)再进一步执行代码
  • 在最长等待时间内循环执行结束条件的函数
  • webDriverWait(driver实例,最长等待时间,轮询时间).until(结束条件函数)

源码:

expected_conditions

Selenium 显式等待官网说明

演示网站: 霍格沃兹测试开发

常见expected_conditions

针对于元素,比如判断元素是否可以点击,或者元素是否可见

  • until(expected_conditions.element_to_be_clickable(()))
  • until(expected_conditions.visibility_of_element_located(()))

针对于url

  • until(expected_conditions.url_contains(()))

针对于标题

  • until(expected_conditions.title_is(()))

针对于frame

  • until(expected_conditions.frame_to_be_available_and_switch_to_it(locator))

针对于弹窗

  • until(expected_conditions.alert_is_present(()))

封装等待条件

  • 官方的expected_conditions不可能覆盖所有场景
  • 定制封装条件会更加灵活、可控
def element_to_be_clickable(target_element, next_element):
    """
    封装显示等待的等待条件:
        解决的问题:有的按钮点击一次没有反应,可能要点击多次,比如企业微信的添加成员
        解决的方案:一直点击按钮,直到下个页面出现,封装成显示等待的一个条件
    target_element: 点击的目标按钮
    next_element: 下一个页面的某个元素
    :return:
    """

    def _predicate(driver):
        driver.find_element(*target_element).click()
        # 1、结果找到了,return 找到的webelement对象
        # 2、结果没找到,return driver.find_element(*next_element) 报错,但是会在until源码中捕获到异常,并抛出异常,
        # 继续循环执行_predicate函数,直到return driver.find_element(*next_element)执行成功
        return driver.find_element(*next_element)

    return _predicate


def wait_until():
    """
    问题:使用官方提供的expected condition已经无法满足需求
    解决方案:自己封装等待条件
    需求:一直点击按钮,直到下一个页面出现为止
    :return:
    """
    driver = webdriver.Chrome()
    driver.get("https://vip.ceshiren.com/#/ui_study")
    WebDriverWait(driver, 10, 2).until(
        element_to_be_clickable((By.ID, "primary_btn"), (By.XPATH, "//*[text()='该弹框点击两次后才会弹出']")))
    time.sleep(5)


if __name__ == '__main__':
    wait_until()