web的自動化測試中,我們經常會遇到這樣一種情況:當我們的程序執行時需要頁面某個元素,而此時這個元素還未加載完成,這時我們的程序就會報錯。怎么辦?等待。等待元素出現后再進行對這個元素的操作。
在selenium-webdriver中我們用兩種方式進行等待:明確的等待和隱性的等待。
明確的等待
明確的等待是指在代碼進行下一步操作之前等待某一個條件的發生。最不好的情況是使用Thread.sleep()去設置一段確認的時間去等待。但為什么說最不好呢?因為一個元素的加載時間有長有短,你在設置sleep的時間之前要自己把握長短,太短容易超時,太長浪費時間。selenium webdriver提供了一些方法幫助我們等待正好需要等待的時間。利用WebDriverWait類和ExpectedCondition接口就能實現這一點。
下面的html代碼實現了這樣的一種效果:點擊click按鈕5秒鍾后,頁面上會出現一個紅色的div塊。我們需要寫一段自動化腳本去捕獲這個出現的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>
--------------------------網頁源碼分隔結束------------------------------------------
- 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,直到有成功的返回,當然如果超過設定的值還沒有成功的返回,將拋出異常。
隱性等待
隱性等待是指當要查找元素,而這個元素沒有馬上出現時,告訴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);
- }
- }