等待元素可以使用python和Selenium单击

时间:2019-05-30 15:06:45

标签: python selenium-webdriver webdriverwait

有多种方法等待对象,例如在硒python中可以单击的按钮。我使用time.sleep()和/或WebDriverWait...until,效果很好。

但是,当有数百个对象时,是否有办法全局设置默认时滞,而不是在每个对象上都实现默认时滞?

click()操作应该有条件的等待时间吗?

4 个答案:

答案 0 :(得分:0)

您可以做一些事情...

  1. 定义一个全局默认等待时间,然后在每次创建的等待中使用该时间。

    default_wait_time = 10 # seconds
    ...
    wait = WebDriverWait(driver, default_wait_time)
    
  2. 在多次使用等待的方法中,您可以实例化等待,将其存储在变量中,然后重用。

    def my_method(self):
        wait = WebDriverWait(driver, 10)
        wait.until(EC.visibility_of_element_located((By.ID, "username")).send_keys("username")
        wait.until(EC.visibility_of_element_located((By.ID, "password")).send_keys("password")
        wait.until(EC.element_to_be_clickable((By.ID, "login")).click()
    
  3. 定义一个默认的WebDriverWait实例,然后重复使用它。

    注意:如果您正在或将要并行运行脚本,则使用此方法时要格外小心,因为WebDriverWait的实例绑定到特定的驱动程序。

    # some global location
    wait = WebDriverWait(driver, 10)
    ...
    # in your script, page object, helper method, etc.
    wait.until(EC.element_to_be_clickable((By.ID, "login")).click()
    

答案 1 :(得分:0)

  

是否可以全局设置默认时滞,   而不是在每个对象上实现它?

是的,这正是隐式等待的设置。隐式等待用于WebDriver的使用寿命。

示例:

driver.implicitly_wait(10)

信息:

答案 2 :(得分:0)

我想出了这个

def myClick(by, desc):
    wait = WebDriverWait(dr, 10)
    by = by.upper()
    if by == 'XPATH':
        wait.until(EC.element_to_be_clickable((By.XPATH, desc))).click()
    if by == 'ID':
        wait.until(EC.element_to_be_clickable((By.ID, desc))).click()
    if by == 'LINK_TEXT':
        wait.until(EC.element_to_be_clickable((By.LINK_TEXT, desc))).click()

具有此功能的代码:

driver.find_element_by_link_text('Show Latest Permit').click()

将是

myClick('link_text', 'Show Latest Permit')

相反。

我已经运行了几周,需要点击数百个元素,我再也没有看到错误。

答案 3 :(得分:-2)

首先,引诱time.sleep()并不是等待对象的理想解决方案,例如一个可单击的按钮,因为它会降低整体测试执行性能。您可以在以下位置找到一些详细的讨论:


现在,当有数百个对象时,将很难根据One size fits all的概念来计算和设置要在全局范围内配置的默认时滞。

原因

通过所有可能的方式,click()操作将在各种类型的元素上被调用,例如:

尽管所有这些类型的元素都是通过 JavaScript 动态生成的,并且看起来很相似,但是从功能和实现上看,它们之间基本上存在一些差异。例如,

  • executeScript():在当前选定的框架或窗口的上下文中执行JavaScript。提供的脚本片段将作为匿名函数的主体执行。
  • executeAsyncScript():在当前选定的框架或窗口的上下文中执行异步JavaScript。与执行同步JavaScript不同,使用此方法执行的脚本必须通过调用提供的回调来显式表示已完成脚本。此回调始终作为最后一个参数注入执行的函数中。

因此,一种更好的方法是根据您的测试规范诱导WebDriverWait。应该在 5秒内变为 clickable 的元素不应(理想地)赋值为 10秒的全局WebDriverWait >。这可能会隐藏潜在的 JavaScript AJAX 错误,从而需要花费更长的时间来呈现DOM Tree。同样,应该在 10秒之内变为 clickable 的元素不应获得 5秒的全局WebDriverWait权限>。在这种情况下,您的 Test 将由于不想要的原因而失败。

最后,请根据您的测试规范引出WebDriverWait

  • 样品A:

    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#btn_download"))).click()
    
  • 样品B:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@class='standard']"))).click()
    

更新

根据您的评论更新,如果您的任何测试基于以下前提:期望的元素可以在HTML DOM内(易于)交互,那么可以避免使用{{1} },然后立即查找并调用WebDriverWait,如下所示:

  • 样品A:

    click()
  • 样品B:

    driver.find_element_by_css_selector("input.string.required#order_billing_name").click()