SUM*_*SUM 46 java selenium selenium-webdriver
我在用:
driver.manage().timeouts().implicitlyWait(180, TimeUnit.SECONDS);
但是对于下面的元素,它仍然会不断失败
    driver.findElement(By.id("name")).clear();
    driver.findElement(By.id("name")).sendKeys("Create_title_01");
我添加了等待代码:
for (int second = 0;; second++) {
        if (second >= 120) fail("timeout");
        try { if (isElementPresent(By.id("name"))) break; } catch (Exception e) {}
        Thread.sleep(1000);
    }
不应该隐含等待,直到找到一个元素?如果我使用显式等待而不是我添加的代码,它会更好Thread.sleep()吗?
les*_*ana 92
TL; DR:始终使用显式等待.忘记存在隐式等待.
以下是显式和隐式等待之间差异的快速概述:
明确的等待:
隐含等待:
让我们看一下selenium的实际源代码中显式等待和隐式等待之间的区别.我复制了selenium的python绑定代码,因为python"易于阅读".
代码elementToBeClickable(显式等待):
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));
现在使用人类语言:显式等待需要一个方法,如果成功则返回一个值.然后它重复执行给定的方法,其间有延迟.抑制了给定方法的预期误差.如果给定方法返回truish值,则显式wait将返回该值.如果时间用完,则引发超时异常.
与代码比较numberOfElementsToBeMoreThan(为简洁起见,删除了注释):
WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement myDynamicElement = wait.until(
  ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
invisibilityOf是findElement*它调用findElement*这反过来做,据我所知,一个RPC硒的远程端.
在人类语言中:隐式等待将消息发送到selenium webdriver的"远程端".selenium webdriver的远程端是selenium的一部分,它实际上控制着浏览器.远程端对消息做了什么?"这取决于".这取决于操作系统和浏览器以及selenium的版本.据我所知,无法保证特定实现的实际行为.
可能的实现是:
请注意,隐式等待仅对find元素方法生效.
我没有查找selenium远程端的实际源代码.通过阅读关于硒中隐式和显式等待的错误报告中的注释来收集信息:
我的结论:隐性等待很糟糕.能力有限.该行为未记录且依赖于实现.
显式等待可以做一切隐含的等待可以做多.由于多个远程过程调用,显式等待的唯一缺点是更多开销.显式等待也有点冗长.但这种冗长使代码显而易见.隐式的显性更好.对?
进一步阅读:
您是否尝试过fluentWait?等待接口的实现,可以动态配置其超时和轮询间隔。每个FluentWait实例都定义了等待条件的最长时间,以及检查条件的频率。此外,用户可以配置等待以在等待时忽略特定类型的异常,例如在页面上搜索元素时的NoSuchElementExceptions。
看到此链接流利的等待描述
特别是我以这种方式使用了流畅的等待:
public WebElement fluentWait(final By locator) {
    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
        .withTimeout(30, TimeUnit.SECONDS)
        .pollingEvery(5, TimeUnit.SECONDS)
        .ignoring(NoSuchElementException.class);
    WebElement foo = wait.until(
        new Function<WebDriver, WebElement>() {
            public WebElement apply(WebDriver driver) {
                return driver.findElement(locator);
            }
        }
    );
    return foo;          
};
如您所知,流利的等待返回找到了web元素。因此,您只需通过“类型”传递定位符,然后就可以对找到的Web元素执行任何操作。
fluentWait(By.id("name")).clear();
希望这对您有帮助)
您是否尝试过使用“ WebDriverWait ”?我想你想要的是这样的:
WebDriverWait _wait = new WebDriverWait(driver, new TimeSpan(0, 0, 2)); //waits 2 secs max
_wait.Until(d => d.FindElement(By.Id("name")));
//do your business on the element here :)
据我了解,这几乎可以完成您当前的代码。它将不断尝试该方法(同时忽略未找到的异常),直到达到传入时间跨度的超时,并且可以输入第三个参数来指定睡眠(以毫秒为单位)。抱歉,如果这也是implicitlyWait 所做的!
编辑:我今天读了一些书,更好地理解了你的问题,并意识到这正是你的隐式等待设置应该做的。将其留在这里,以防代码本身可以帮助其他人。
| 归档时间: | 
 | 
| 查看次数: | 66141 次 | 
| 最近记录: |