【问题标题】:Selenium wait until any element with a given class is visibleSelenium 等到任何具有给定类的元素可见
【发布时间】:2014-05-31 20:09:12
【问题描述】:

我正在编写一些 Selenium 测试以确保我的自动完成功能正常工作,并且我需要在输入字段中输入文本和尝试从自动完成功能中进行选择之间稍作延迟。我宁愿等到列表出现,而不仅仅是使用固定延迟。我尝试了以下方法:

input_element.send_keys("zanzibar c")
WebDriverWait(self.selenium, 10).until(EC.visibility_of_element_located((By.CLASS_NAME, "pac-container")))
input_element.send_keys(Keys.DOWN)

其中pac-container 是自动完成列表元素的类。

这适用于具有自动完成功能的第一个输入,但其余部分会超时。我猜这是因为它正在等待第一个 pac-container 可见,而我希望它等待 any 其中一个 pac-containers 可见。

有没有办法等到至少一个给定类的元素可见?

【问题讨论】:

标签: python selenium autocomplete


【解决方案1】:

我猜这就是你要找的presence_of_all_elements_located(locator)

class selenium.webdriver.support.expected_conditions.presence_of_all_elements_located(locator)[source]

检查是否存在至少一个元素的期望 在网页上。 locator 用于查找返回列表的元素 定位后的 WebElements

参考:http://selenium.googlecode.com/git/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html

【讨论】:

  • 这似乎是在等待元素存在,他们已经这样做了。我需要等到一个可见。
【解决方案2】:

编辑:WebDriverWait 没有“等待其中一个可见”之类的内容。

有两种方法可以找到第一个可见元素。简单的方法是使用 JQuery/Javascript 选择它:

$('.pac-container').not(':hidden').click();

第二种方法是获取元素列表并遍历它们,检查它们是否可见:

for element in driver.find_elements_by_class_name("pac-container"):
    if element.is_displayed():
        element.do_something()

这两者都需要处于无限循环中,一旦找到该元素,您就会跳出该循环。

【讨论】:

  • 等待最后一个元素可见也无济于事,因为一次只有一个具有该类的元素可见。我不完全确定如何通过循环遍历元素来实现我正在寻找的效果。我想这只会在它进入下一次迭代之前让它在第一次超时......
  • @StephenTG 我更新了我的答案以实际回答您的问题
  • 好吧,这让我走上了正确的道路。我现在使用WebDriverWait(self.selenium, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, '.pac-container:not([style*="display: none"])'))),你的第一个建议促使我尝试通过css
  • 是的,我希望有一个 CSS 选择器,但我不知道它是如何不可见的。很高兴您找到了解决方案。
【解决方案3】:

我正在使用 Python 绑定,下面的函数允许您传入要等待的定位器列表。

以下是两个定位器和定位器列表的示例:

no_records_indicator_loc = (By.XPATH, "//*[contains(text(),'No records to display')]")
edit_button_loc =  (By.XPATH, "//*[@value='Edit']")
locators = [Customer.no_records_indicator_loc, Customer.edit_button_loc]

这是我调用函数的方式:

wait_for_one_these_elements_to_be_present(locators)

这里是函数

def wait_for_one_these_elements_to_be_present(locators, total_time_to_sleep=30):
    # will attempt to find each element on the page until either one is
    # found or the time expires
    total_slept = 0
    i_sleep_sec = .5

    while True:
        time.sleep(i_sleep_sec)

        for loc in locators:
            if len(driver.find_elements(*loc)) > 0:
                return
        total_slept += i_sleep_sec
        if total_slept == total_time_to_sleep:
            raise NoSuchElementException

解释:

如果在时间到期之前找到任何东西,则函数返回。如果不是,它会引发 NoSuchElementException。从技术上讲,时间的行为更像是一个迭代器,但对我来说已经足够接近了。

列表被迭代。如果在页面上找到列表中的任何项目,该函数将中断并返回。如果未在列表中找到定位器,则如果总时间已过期,则引发 NoSuchElementException。如果还有时间继续检查页面。重复。

【讨论】:

    猜你喜欢
    • 2017-08-14
    • 2021-09-05
    • 2014-05-03
    • 2016-07-18
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    • 2020-03-26
    相关资源
    最近更新 更多