我正在为Web应用程序编写测试。某些命令会拉出对话框,这些对话框具有可见的控件,但暂时不可用。 (它们是灰色的,但是webdriver仍然看到它们可见)。
如何告诉Selenium等待元素实际可访问,而不仅仅是可见?
try:
print "about to look for element"
element = WebDriverWait(driver, 10).until(lambda driver : driver.find_element_by_id("createFolderCreateBtn"))
print "still looking?"
finally: print 'yowp'
以下是我尝试过的代码,但它在可用之前“看到”按钮,并且基本上是在假定的“等待”之后收费。
请注意,我可以在代码中填充十秒钟而不是这样,代码将正常工作,但这是丑陋,不可靠和低效的。但它确实证明问题只是“点击”命令在控制的可用性之前飙升。
答案 0 :(得分:16)
我认为事件时间表是这样的:
<input type="button" id="createFolderCreateBtn" disabled="disabled" />
<input type="button" id="createFolderCreateBtn" />
目前,您正在按ID搜索元素,并在步骤2中找到一个,这比您需要的更早。你需要做的是通过xpath搜索它:
//input[@id="createFolderCreateBtn" and not(@disabled)]
区别在于:
from lxml import etree
html = """
<input type="button" id="createFolderCreateBtn" disabled="disabled" />
<input type="button" id="createFolderCreateBtn" />
"""
tree = etree.fromstring(html, parser=etree.HTMLParser())
tree.xpath('//input[@id="createFolderCreateBtn"]')
# returns both elements:
# [<Element input at 102a73680>, <Element input at 102a73578>]
tree.xpath('//input[@id="createFolderCreateBtn" and not(@disabled)]')
# returns single element:
# [<Element input at 102a73578>]
总结一下,这是你的固定代码:
try:
print "about to look for element"
element_xpath = '//input[@id="createFolderCreateBtn" and not(@disabled)]'
element = WebDriverWait(driver, 10).until(
lambda driver : driver.find_element_by_xpath(element_xpath)
)
print "still looking?"
finally:
print 'yowp'
更新:
用实际的webdriver重复它。
这是example.html
页面代码:
<input type="button" id="createFolderCreateBtn" disabled="disabled" />
<input type="button" id="createFolderCreateBtn" />
这是ipython会话:
In [1]: from selenium.webdriver import Firefox
In [2]: browser = Firefox()
In [3]: browser.get('file:///tmp/example.html')
In [4]: browser.find_elements_by_xpath('//input[@id="createFolderCreateBtn"]')
Out[4]:
[<selenium.webdriver.remote.webelement.WebElement at 0x103f75110>,
<selenium.webdriver.remote.webelement.WebElement at 0x103f75150>]
In [5]: browser.find_elements_by_xpath('//input[@id="createFolderCreateBtn" and not(@disabled)]')
Out[5]:
[<selenium.webdriver.remote.webelement.WebElement at 0x103f75290>]
更新2:
它也适用于此:
<input type="button" id="createFolderCreateBtn" disabled />
答案 1 :(得分:12)
print time.time()
try:
print "about to look for element"
def find(driver):
e = driver.find_element_by_id("createFolderCreateBtn")
if (e.get_attribute("disabled")=='true'):
return False
return e
element = WebDriverWait(driver, 10).until(find)
print "still looking?"
finally: print 'yowp'
print "ok, left the loop"
print time.time()
这是我们最终的结果。 (感谢lukeis和RossPatterson。)请注意,我们必须按ID找到所有项目,然后按“禁用”过滤。我更喜欢单一的搜索模式,但你能做什么?
答案 2 :(得分:0)
这里已经发布了一些很棒的答案,但我想我会添加我的解决方案。显式等待是用于测试硒的重要功能。然而,显式等待仅执行Thread.Sleep()
的功能,您只能设置一次。以下功能是我过去几分钟“刮掉”的功能。它等待元素“可访问”。
//ALTERNATIVE FOR THREAD.SLEEP
public static class Wait
{
//public static void wait(this IWebDriver driver, List<IWebElement> IWebElementLIst)
public static void wait(this IWebDriver driver, By bylocator)
{
bool elementPresent = IsPresent.isPresent(driver, bylocator);
while (elementPresent != true)
{
Thread.Sleep(1000);
elementPresent = IsPresent.isPresent(driver, bylocator);
}
}
}
它在C#中,但要适应它并不会那么困难。希望这可以帮助。
答案 3 :(得分:0)
我认为这些方面的内容也应该有效:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
browser = webdriver.Firefox()
wait = WebDriverWait(browser, 30)
wait.until(expected_conditions.presence_of_element_located((By.XPATH, "//*[@id='createFolderCreateBrn' and not(@disabled)]")))