selenium webdriver學習(十一)-怎麼等待頁面元素載入完成
web的自動化測試中,我們經常會遇到這樣一種情況:當我們的程式執行時需要頁面某個元素,而此時這個元素還未載入完成,這時我們的程式就會報錯。怎麼辦?等待。等待元素出現後再進行對這個元素的操作。
在selenium-webdriver中我們用兩種方式進行等待:明確的等待和隱性的等待。
明確的等待
明確的等待是指在程式碼進行下一步操作之前等待某一個條件的發生。最不好的情況是使用Thread.sleep()去設定一段確認的時間去等待。但為什麼說最不好呢?因為一個元素的載入時間有長有短,你在設定sleep的時間之前要自己把握長短,太短容易超時,太長浪費時間。selenium webdriver提供了一些方法幫助我們等待正好需要等待的時間。利用WebDriverWait類和ExpectedCondition介面就能實現這一點。
下面的html程式碼實現了這樣的一種效果:點選click按鈕5秒鐘後,頁面上會出現一個紅色的div塊。我們需要寫一段自動化指令碼去捕獲這個出現的div,然後高亮之。
Wait.html <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>
下面的程式碼實現了高亮動態生成的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 aerchi */ public static void main(String[] args) { System.setProperty("webdriver.firefox.bin","D:\\Program Files\\Mozilla Firefox\\firefox.exe"); WebDriver dr = new FirefoxDriver(); String url = "file:///C:/Documents and Settings/aerchi/桌面/selenium/Wait.html";// "%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,直到有成功的返回,當然如果超過設定的值還沒有成功的返回,將丟擲異常。
隱性等待
隱性等待是指當要查詢元素,而這個元素沒有馬上出現時,告訴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/aerchi/桌面/selenium/Wait.html";// "%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);
}
}
兩者選其一,第二種看起來一勞永逸呀。哈哈
博主 用隱性等待是查詢之前會等麼 不管元素出現與否?