web的自動化測試中故响,我們經常會遇到這樣一種情況:當我們的程序執(zhí)行時需要頁面某個元素宏蛉,而此時這個元素還未加載完成儿咱,這時我們的程序就會報錯。怎么辦场晶?等待混埠。等待元素出現(xiàn)后再進行對這個元素的操作。
在selenium-webdriver中我們用兩種方式進行等待:明確的等待和隱性的等待诗轻。
明確的等待
明確的等待是指在代碼進行下一步操作之前等待某一個條件的發(fā)生钳宪。最不好的情況是使用Thread.sleep()去設置一段確認的時間去等待。但為 什么說最不好呢扳炬?因為一個元素的加載時間有長有短吏颖,你在設置sleep的時間之前要自己把握長短,太短容易超時恨樟,太長浪費時間半醉。selenium
webdriver提供了一些方法幫助我們等待正好需要等待的時間。利用WebDriverWait類和ExpectedCondition接口就能實現(xiàn)這一點劝术。
下面的html代碼實現(xiàn)了這樣的一種效果:點擊click按鈕5秒鐘后缩多,頁面上會出現(xiàn)一個紅色的div塊。我們需要寫一段自動化腳本去捕獲這個出現(xiàn)的div夯尽,然后高亮之瞧壮。
<html>
<head>
<title>Set Timeout</title>
<style>
.red_box {background-color: red; width = 20%; height: 100px; border: none;}
</style>
<script>
function show_div(){
setTimeout("create_div()", 5000);
}
function create_div(){
d = document.createElement('div');
d.className = "red_box";
document.body.appendChild(d);
}
</script>
</head>
<body>
<button id = "b" onclick = "show_div()">click</button>
</body>
</html>
下面的代碼實現(xiàn)了高亮動態(tài)生成的div塊的功能:
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
public class WaitForSomthing {
/**
* @author gongjf
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.setProperty("webdriver.firefox.bin","D:\\Program Files\\Mozilla Firefox\\firefox.exe");
WebDriver dr = new FirefoxDriver();
String url = "file:///C:/Documents and Settings/gongjf/桌面/selenium_test/Wait.html";// "/Your/Path/to/Wait.html"
dr.get(url);
WebDriverWait wait = new WebDriverWait(dr,10);
wait.until(new ExpectedCondition<WebElement>(){
@Override
public WebElement apply(WebDriver d) {
return d.findElement(By.id("b"));
}}).click();
WebElement element = dr.findElement(By.cssSelector(".red_box"));
((JavascriptExecutor)dr).executeScript("arguments[0].style.border = \"5px solid yellow\"",element);
}
}
上 面的代碼WebDriverWait類的構造方法接受了一個WebDriver對象和一個等待最長時間(10秒)。然后調用until方法匙握,其中重寫了ExpectedCondition接口中的apply方法咆槽,讓其返回一個WebElement,即加載完成的元素,然后點擊。默認情況下,WebDriverWait每500毫秒調用一次ExpectedCondition捻激,直到有成功的返回,當然如果超過設定的值還沒有成功的返回灯谣,將拋出異常。
隱性等待
隱性等待是指當要查找元素蛔琅,而這個元素沒有馬上出現(xiàn)時胎许,告訴WebDriver查詢Dom一定時間。默認值是0,但是設置之后罗售,這個時間將在WebDriver對象實例整個生命周期都起作用辜窑。上面的代碼就變成了這樣:
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
public class WaitForSomthing {
/**
* @author gongjf
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.setProperty("webdriver.firefox.bin","D:\\Program Files\\Mozilla Firefox\\firefox.exe");
WebDriver dr = new FirefoxDriver();
//設置10秒
dr.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
String url = "file:///C:/Documents and Settings/gongjf/桌面/selenium_test/Wait.html";// "/Your/Path/to/Wait.html"
dr.get(url);
//注釋掉原來的
/*WebDriverWait wait = new WebDriverWait(dr,10);
wait.until(new ExpectedCondition<WebElement>(){
@Override
public WebElement apply(WebDriver d) {
return d.findElement(By.id("b"));
}}).click();*/
dr.findElement(By.id("b")).click();
WebElement element = dr.findElement(By.cssSelector(".red_box"));
((JavascriptExecutor)dr).executeScript("arguments[0].style.border = \"5px solid yellow\"",element);
}
}
兩者選其一,第二種看起來一勞永逸呀寨躁。哈哈