在自动化测试中,代码的执行是很快的,往往出现定位不到元素的情况,其中一种原因是因为页面加载还没有完成或者需要find的元素还没有加载出来,但是代码已经执行到查找元素的位置了,这个时候程序就回报错:找不到元素
这种情况下,我们提出了延时等待的方式来解决这个问题
延时等待分为三种,分别是:硬性等待、隐式等待、显示等待
1、硬性等待:Thread.sleep(long millis)
- 硬性等待,线程休眠,强制等待
Thread.sleep(long millis)
- 不推荐使用,容易造成时间上的浪费,受到网络原因的影响因素太大。
- 使用场景:页面切换时
2、隐式等待:TimeOuts--implicitlyWait
- 在设置的超时时间范围内不断的查找元素,直到找到元素或者超时
- 设置等待时间为5秒,第3秒找到元素,不再继续等待
- 设置方式
driver.manage().timeouts().implicitlyWait(long time, TimeUnit.SECONDS);
- 优点:相对灵活
- 缺点:设置是针对全局的,在WebDriver实例的整个生命周期有效,但是并不是所有的元素都需要等待
3、显示等待(智能等待):WebDriverWait
- 显示等待通常是我们自定义一段代码,用来等待某个条件发生以后,再继续执行后续的代码(如找到元素、元素可点击、元素已显示)
- 可以自己指定某个元素需要等待,在有必要进行等待的时候进行等待
- 默认是0.5秒轮循一次,在dom中查找一次元素
- 我们可以自己设置期望条件
- 注意:在自己设置期望条件时,return时不能直接点击该元素,因为返回是webElement时只能说明该元素在dom中间存在,但是能不能点击是不确定的
因为元素能被点击具备三个条件:1、在dom中间存在;2、已经显示在页面上(isDisplayed);3、有效性(可以进行click操作)
WebDriverWait wait = new WebDriverWait(driver, 5);
//until:在超时时间内满足某个条件(才能进行下一步)或者超时也没满足(异常)
wait.until(new ExpectedCondition() {
@Override
public Object apply(Object input) {
//500ms找一次
return driver.findElement(By.id("menu-product")).isDisplayed(); }
});
- 期望的场景是非常复杂的,我们可以使用已经封装好的类ExpectedConditions去使用某些条件
//直到id为‘su’的这个元素可以被点击了,才能进行下一步,或者5秒内不能被点击,则报超时异常
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.elementToBeClickable(By.id("su")));
4、由于一些网页加载时间过长 ,我们可以让其停止加载
((JavascriptExecutor) driver).executeScript("window.stop()");
public void f() {
try {
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
driver.get("http://120.78.128.25:8765/");
} catch (TimeoutException e) {
// TODO Auto-generated catch block
//但是我想3秒后定位元素--》强制页面停止加载
//让页面停止加载,继续执行后续操作--》提高脚本执行效率
JavascriptExecutor jExecutor = (JavascriptExecutor) driver;
jExecutor.executeScript("window.stop()");
//刷新页面
driver.navigate().refresh();
e.printStackTrace();
}
driver.findElement(By.linkText("登录")).click();;
}