Selenium等待直到任意指定类的元素可见
我正在写一些Selenium测试,目的是确保我的自动完成(autocomplete)功能正常工作。在输入框中输入文本和尝试从自动完成列表中选择之间,我需要稍微延迟一下。我不想只用固定的延迟时间,而是希望等到列表出现后再进行操作。我试过以下方法:
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
可见,而我其实想等到 任何一个 pac-container
可见。
有没有办法等到至少有一个指定类的元素可见呢?
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。如果还有时间可以继续检查页面,就会重复这个过程。
编辑: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()
这两种方法都需要放在一个无限循环里,直到找到那个元素再跳出循环。
我想这就是你要找的 presence_of_all_elements_located(locator)
class selenium.webdriver.support.expected_conditions.presence_of_all_elements_located(locator)[source]
这个方法是用来检查网页上是否至少有一个元素存在的。locator 是用来找到这个元素的,一旦找到,就会返回一个元素列表。