如何让Selenium Web Driver等待元素可访问,而不仅仅是存在?

Ski*_*man 28 python selenium webdriver

我正在为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'
Run Code Online (Sandbox Code Playgroud)

这是我尝试过的代码,但它在可用之前"看到"了按钮,基本上是在假定的"等待"之后收费.

请注意,我可以在代码中填充十秒钟而不是这样,代码将正常工作,但这是丑陋,不可靠和低效的.但它确实证明问题只是"点击"命令在控制的可用性之前飙升.

Mis*_*sev 17

我假设事件时间表是这样的:

  1. 页面上没有必要的元素.
  2. 出现所需元素,但已禁用:
    <input type="button" id="createFolderCreateBtn" disabled="disabled" />
  3. 所需元素已启用:
    <input type="button" id="createFolderCreateBtn" />

目前,您正在按ID搜索元素,并在步骤2中找到一个,这比您需要的更早.你需要做的是通过xpath搜索它:

//input[@id="createFolderCreateBtn" and not(@disabled)]
Run Code Online (Sandbox Code Playgroud)

这是区别:

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>]
Run Code Online (Sandbox Code Playgroud)

要把它包起来,这是你的固定代码:

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'
Run Code Online (Sandbox Code Playgroud)

更新:
与实际的webdriver重复相同.
这是example.html页面代码:

<input type="button" id="createFolderCreateBtn" disabled="disabled" />
<input type="button" id="createFolderCreateBtn" />
Run Code Online (Sandbox Code Playgroud)

这是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>]
Run Code Online (Sandbox Code Playgroud)

更新2:

它也适用于此:

<input type="button" id="createFolderCreateBtn" disabled />
Run Code Online (Sandbox Code Playgroud)


Ski*_*man 13

    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()
Run Code Online (Sandbox Code Playgroud)

这是我们最终得到的结果.(感谢lukeis和RossPatterson.)请注意,我们必须按ID找到所有项目,然后按"禁用"过滤.我更喜欢单一的搜索模式,但你能做什么?