Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何让SeleniumWeb驱动程序等待一个元素被访问,而不是仅仅出现?_Python_Selenium_Webdriver - Fatal编程技术网

Python 如何让SeleniumWeb驱动程序等待一个元素被访问,而不是仅仅出现?

Python 如何让SeleniumWeb驱动程序等待一个元素被访问,而不是仅仅出现?,python,selenium,webdriver,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("crea

我正在为一个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'
这是我尝试过的代码,但它在按钮可用之前“看到”了按钮,基本上在假定的“等待”之后充电


请注意,我可以在代码中填充10秒钟的睡眠时间,而不是这个时间,代码将正常工作,但这是丑陋的、不可靠的和低效的。但它确实证明了问题在于“单击”命令比控件的可用性快。

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

  • 页面上没有需要的元素
  • 显示所需元素,但已禁用:
  • 所需元素已启用:
  • 目前,您正在按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>]
    

    更新:
    重新绘制与实际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>]
    
    [1]中的
    :从selenium.webdriver导入Firefox
    在[2]中:browser=Firefox()
    在[3]:browser.get('file:///tmp/example.html')
    在[4]:浏览器中。通过xpath('//input[@id=“createFolderCreateBtn”]'查找元素
    出[4]:
    [,
    ]
    在[5]:浏览器中。通过xpath('//input[@id=“createFolderCreateBtn”而不是(@disabled)]查找元素
    出[5]:
    []
    

    更新2:

    它也适用于此:

    <input type="button" id="createFolderCreateBtn" disabled />
    
    
    

    这就是我们的结局。(感谢lukeis和RossPatterson)注意,我们必须按id查找所有项目,然后按“disabled”过滤。我更喜欢单一的搜索模式,但是你能做什么呢?

    这里已经发布了一些很好的答案,但我想我会添加我的解决方案。显式等待等是用于硒测试的强大功能。然而,显式等待只执行只能设置一次的
    Thread.Sleep()
    函数。下面的功能是我用来“剃掉”几分钟的。它等待元素“可访问”

    //THREAD.SLEEP的替代方案
    公共静态类等待
    {  
    //公共静态无效等待(此IWebDriver驱动程序,列表IWebElementLIst)
    公共静态无效等待(此IWebDriver驱动程序由bylocator提供)
    {
    bool elementPresent=IsPresent.IsPresent(驱动程序、bylocator);
    while(elementPresent!=真)
    {
    睡眠(1000);
    elementPresent=IsPresent.IsPresent(驱动程序、bylocator);
    }
    }
    }
    

    这是C#,但要适应它并不难。希望这有帮助

    我认为这方面的东西也应该奏效:

    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)]")))
    

    我认为这为我指明了正确的方向,但“残疾”似乎不是正确的属性。我想,当firebug不可用时,我需要用firebug抓住它。我希望我的电子游戏技能能达到速度挑战。@SkipHuffman,它也可以轻松成为css类。要捕获所需的页面状态,请执行以下操作:1。在找到元素后立即将
    browser.page\u source
    值存储在某个变量中。2.将该变量存储在
    .html
    文件中。3.用chrome/firefox打开它,用firebug/developer console检查。css看起来可以做到type=“button”disabled=“disabled”id=“createFolderCreateBtn”在禁用时似乎是此控件的唯一属性。当按钮处于活动状态时,它将完全丢失“disabled”属性。(有道理。)现在我只需要重新设计css选择器来进行“这个,但不是那个”排序。(完成这项工作。也许我的思维过程会帮助其他人)。我可以找到元素为“\u css=”button[type=“button”][id=“createFolderCreateBtn”]”的按钮,这样它就可以搜索参数列表(一个类型为“button”、id为“createFolderCreateBtn”的按钮)。但是现在我需要添加一个否定搜索,如果属性包括'disabled=“disabled”',它应该会失败。我想现在我可以用编程的方式来做了,但我怀疑如果我对搜索字符串再聪明一点,我就能得到我所需要的东西了。@SkipHuffman仔细阅读了我最初的答案。我给了您有效的xpath选择器,该选择器与按钮匹配,按钮未被禁用:
    //输入[@id=“createFolderCreateBtn”且未(@disabled)]
    ,请注意
    未(@disabled)
    部分。毫无疑问,它工作正常。我正试图正确地定义它应该等待什么。在这种情况下,一个特定的元素,当它变得可用时,不仅仅是可见的。是的,对我来说是不精确的。我的意思是,当我想暂停的时候,我的测试马上就开始了。错误在于作为程序员的我,而不是作为工具的selenium。这个问题挽救了我的工作。只是澄清一下:我相信selenium中findElement的默认行为也是检查可见性。这与在DOM上检查“presence”不同,即使某些内容不可见,也可能返回true。您需要小心使用“isPresent”,因为当项目在DOM上但不可见时,它将返回true。在本线程中提出的问题的上下文中,您应该使用“isVisible”。此外,如果Selenium绑定允许,使用ExpectedCondition也是一个好主意。事实上,findElement的默认行为是(我认为是).isVisible而不是.isPresent。如果元素在1010毫秒或更长时间后被启用,该怎么办?你的考试会失败。如果加载的元素介于300毫秒到500毫秒之间,那么您的测试就是在浪费时间。时间不多,但是当您使用这个等待几个元素时,它可以加起来。
        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()
    
        //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); 
    
            }
    
        }
    
    }
    
    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)]")))