Selenium WebDriver的簡單操作說明


1.打開一個測試瀏覽器

對瀏覽器進行操作首先需要打開一個瀏覽器,接下來才能對瀏覽器進行操作。

 

Java代碼

import java.io.File;

 

import org.openqa.selenium.WebDriver;

importorg.openqa.selenium.firefox.FirefoxBinary;

importorg.openqa.selenium.firefox.FirefoxDriver;

importorg.openqa.selenium.ie.InternetExplorerDriver;

 

public class OpenBrowsers {

 

        

         public static void main(String[] args) {

                   //打開默認路徑的firefox

                   WebDriver diver = new FirefoxDriver();

                  

                   //打開指定路徑的firefox,方法1

                   System.setProperty("webdriver.firefox.bin","D:\\ProgramFiles\\MozillaFirefox\\firefox.exe");

                   WebDriver dr = new FirefoxDriver();

                  

                   //打開指定路徑的firefox,方法2

                   File pathToFirefoxBinary = newFile("D:\\Program Files\\Mozilla Firefox\\firefox.exe"); 

                   FirefoxBinary firefoxbin = newFirefoxBinary(pathToFirefoxBinary); 

                   WebDriver driver1 = newFirefoxDriver(firefoxbin,null);

                  

                   //打開ie

                   WebDriver ie_driver = new InternetExplorerDriver();

                  

                   //打開chrome

                   System.setProperty("webdriver.chrome.driver","D:\\chromedriver.exe");

                   System.setProperty("webdriver.chrome.bin",

                                            "C:\\Documents and Settings\\gongjf\\Local Settings"

                                             +"\\ApplicationData\\Google\\Chrome\\Application\\chrome.exe");

                  

                  

         }

 

}

 

2.打開1個具體的url

打開一個瀏覽器後,我們需要跳轉到特定的url下,看下面代碼:

Java代碼

 

import org.openqa.selenium.WebDriver;

importorg.openqa.selenium.firefox.FirefoxDriver;

 

public class OpenUrl {

         publicstatic void main(String []args){

                   Stringurl = "http://www.51.com";

                   WebDriverdriver = new FirefoxDriver();

                  

                   //用get方法

                   driver.get(url);

                  

                   //用navigate方法,然後再調用to方法

                   driver.navigate().to(url);

         }

}

 

3.如何關閉瀏覽器

測試完成後,需要關閉瀏覽器

 

Java代碼

import org.openqa.selenium.WebDriver;

importorg.openqa.selenium.firefox.FirefoxDriver;

 

public class CloseBrowser {

         publicstatic void main(String []args){

                   Stringurl = "http://www.51.com";

                   WebDriverdriver = new FirefoxDriver();

                  

                   driver.get(url);

                  

                   //用quit方法

                   driver.quit();

                  

                   //用close方法       

                   driver.close();

                   }

}

 

4.如何返回當前頁面的url和title

有時候我們需要返回當前頁面的url或者title做一些驗證性的操作等。代碼如下:

Java代碼

import org.openqa.selenium.WebDriver;

importorg.openqa.selenium.firefox.FirefoxDriver;

 

public class GetUrlAndTitle {

         publicstatic void main(String []args){

                   Stringurl = "http://www.google.com";

                   WebDriverdriver = new FirefoxDriver();

                  

                   driver.get(url);

                  

                //得到title

                   Stringtitle = driver.getTitle();

 

                //得到當前頁面url

                   StringcurrentUrl = driver.getCurrentUrl();

                  

                //輸出title和currenturl

                   System.out.println(title+"\n"+currentUrl);

                  

                   }

}

 

5.其他方法

getWindowHandle()    返回當前的瀏覽器的窗口句柄

getWindowHandles()  返回當前的瀏覽器的所有窗口句柄

getPageSource()        返回當前頁面的源碼

 

從上面代碼可以看出操作瀏覽器的主要方法都來自org.openqa.selenium.WebDriver這個接口中。看了一下源代碼這些方法都是在org.openqa.selenium.remote.RemoteWebDriver這個類中實現的,然後不同瀏覽的driver類繼承RemoteWebDriver。

 

 

C  定位頁面元素

selenium-webdriver提供了強大的元素定位方法,支持以下三種方法。

單個對象的定位方法

多個對象的定位方法

層級定位 

定位單個元素

在定位單個元素時,selenium-webdriver提示瞭如下一些方法對元素進行定位。

 

 By.className(className))    

 By.cssSelector(selector)       

 By.id(id)                     

 By.linkText(linkText)          

 By.name(name)             

 By.partialLinkText(linkText)

 By.tagName(name)       

 By.xpath(xpathExpression)  

 

注意:selenium-webdriver通過findElement()\findElements()等find方法調用"By"對象來定位 和查詢元素。By類只是提供查詢的方式進行分類。findElement返回一個元素對象否則拋出異常,findElements返回符合條件的元素 List,如果不存在符合條件的就返回一個空的list。

1.使用className進行定位

當所定位的元素具有class屬性的時候我們可以通過classname來定位該元素。

下面的例子定位了51.com首頁上class爲"username"的li。

Java代碼

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

 

import org.openqa.selenium.By;

 

public class ByClassName {

 

  

   public static void main(String[] args) {

        WebDriver driver = new FirefoxDriver();

       driver.get("http://www.51.com");

        WebElement element =driver.findElement(By.className("username"));

        System.out.println(element.getTagName());

 

    }

}

輸出結果:

Java代碼

 

Li

2.使用id屬性定位

51.com首頁的帳號輸入框的html代碼如下:

Java代碼

<input id="passport_51_user"type="text" value="" tabindex="1" title="用戶名/彩虹號/郵箱"

name="passport_51_user">

 

在下面的例子中用id定位這個輸入框,並輸出其title,藉此也可以驗證代碼是否工作正常。

 

Java代碼

 

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

importorg.openqa.selenium.firefox.FirefoxDriver;

 

public class ByUserId {

 

         /**

          * @param args

          */

         publicstatic void main(String[] args) {

                   //TODO Auto-generated method stub

                   WebDriverdr = new FirefoxDriver();

                   dr.get("http://www.51.com");

                  

                   WebElementelement = dr.findElement(By.id("passport_51_user"));

                   System.out.println(element.getAttribute("title"));

         }

 

}

 

輸出結果:

 Java代碼

 

用戶名/彩虹號/郵箱

 

3.使用name屬性定位

51.com首頁的帳號輸入框的html代碼如下:

 

Java代碼

<input id="passport_51_user"type="text" value="" tabindex="1" title="用戶名/彩虹號/郵箱"

name="passport_51_user">

 

使用name定位

 

Java代碼

 

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

importorg.openqa.selenium.firefox.FirefoxDriver;

 

public class ByUserId {

 

         /**

          * @param args

          */

         publicstatic void main(String[] args) {

                   //TODO Auto-generated method stub

                   WebDriverdr = new FirefoxDriver();

                   dr.get("http://www.51.com");

                  

         WebElemente = dr.findElement(By.name("passport_51_user"));                                      System.out.println(element.getAttribute("title"));

         }

 

}

 

輸出結果:

 Java代碼

 

用戶名/彩虹號/郵箱

 

4.使用css屬性定位

51.com首頁的帳號輸入框的html代碼如下:

Java代碼

 

<input id="passport_51_user"type="text" value="" tabindex="1" title="用戶名/彩虹號/郵箱"

name="passport_51_user">

 

使用css定位

Java代碼

 

WebElement e1 =dr.findElement(By.cssSelector("#passport_51_user"));

 

5.使用 XPATH定位

51.com首頁的帳號輸入框的html代碼如下:

Java代碼

 

<input id="passport_51_user"type="text" value="" tabindex="1" title="用戶名/彩虹號/郵箱"

name="passport_51_user">

 

通過xpath查找:

Java代碼

 

WebElement element=driver.findElement(By.xpath("//input[@id=' passport_51_user ']"));

 

6.使用其他方式定位

在定位link元素的時候,可以使用link和link_text屬性;

另外還可以使用tag_name屬性定位任意元素;

7.定位多個元素

上面提到findElements()方法可以返回一個符合條件的元素List組。看下面例子。

Java代碼

import java.io.File;

import java.util.List;

 

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

importorg.openqa.selenium.firefox.FirefoxBinary;

import org.openqa.selenium.firefox.FirefoxDriver;

 

public class FindElementsStudy {

 

         /**

          * @author gongjf

          */

         publicstatic void main(String[] args) {

                   WebDriver  driver = new FirefoxDriver();

                   driver.get("http://www.51.com");

                  

                   //定位到所有<input>標籤的元素,然後輸出他們的id

                   List<WebElement>element = driver.findElements(By.tagName("input"));

                   for(WebElement e : element){

                            System.out.println(e.getAttribute("id"));

                   }

                  

                   driver.quit();

         }

}

 

輸出結果:

Java代碼

 

passport_cookie_login

gourl

passport_login_from

passport_51_user

passport_51_password

passport_qq_login_2

btn_reg

passport_51_ishidden

passport_auto_login

 

上面的代碼返回頁面上所有input對象

 

8.層級定位

層級定位的思想是先定位父元素,然後再從父元素中精確定位出其我們需要選取的子元素。

層級定位一般的應用場景是無法直接定位到需要選取的元素,但是其父元素比較容易定位,通過定位父元素再遍歷其子元素選擇需要的目標元素,或者需要定位某個元素下所有的子元素。

下面的代碼演示瞭如何使用層級定位class爲"login"的div,然後再取得它下面的所有label,並打印出他們的文本

Java代碼

 

import java.io.File;

importjava.util.List;

importorg.openqa.selenium.By;

importorg.openqa.selenium.WebDriver;

importorg.openqa.selenium.WebElement;

importorg.openqa.selenium.firefox.FirefoxBinary;

importorg.openqa.selenium.firefox.FirefoxDriver;

publicclass LayerLocator {

 

         /**

          * @author gongjf

          */

         public static void main(String[] args){

        

                   WebDriver  driver = new FirefoxDriver();

                   driver.get("http://www.51.com");

                  

                   //定位class爲"login"的div,然後再取得它下面的所有label,並打印出他們的值

                   WebElement element =driver.findElement(By.className("login"));

                    List<WebElement> el =element.findElements(By.tagName("label"));

                    for(WebElement e : el)

                   System.out.println(e.getText());

        

         }       

}

輸出結果:

Java代碼

 

帳號:

密碼:

隱身

 

 D  如何對頁面元素進行操作

找到頁面元素後,怎樣對頁面進行操作呢?我們可以根據不同的類型的元素來進行一一說明。

1. 輸入框(text field or textarea)

 找到輸入框元素:

WebElement element =driver.findElement(By.id("passwd-id"));

在輸入框中輸入內容:

element.sendKeys(“test”);

將輸入框清空:

element.clear();

獲取輸入框的文本內容:

element.getText();

 

2. 下拉選擇框(Select)

找到下拉選擇框的元素:

Select select = newSelect(driver.findElement(By.id("select")));

 

選擇對應的選擇項:

select.selectByVisibleText(“mediaAgencyA”);

select.selectByValue(“MA_ID_001”);

 

不選擇對應的選擇項:

select.deselectAll();

select.deselectByValue(“MA_ID_001”);

select.deselectByVisibleText(“mediaAgencyA”);

或者獲取選擇項的值:

select.getAllSelectedOptions();

select.getFirstSelectedOption();

 

 

對下拉框進行操作時首先要定位到這個下拉框,new 一個Selcet對象,然後對它進行操作 

3. 單選項(Radio Button)

找到單選框元素:

WebElement bookMode =driver.findElement(By.id("BookMode"));

選擇某個單選項:

bookMode.click();

清空某個單選項:

bookMode.clear();

判斷某個單選項是否已經被選擇:

bookMode.isSelected();

4. 多選項(checkbox)

多選項的操作和單選的差不多:

WebElement checkbox=driver.findElement(By.id("myCheckbox."));

checkbox.click();

checkbox.clear();

checkbox.isSelected();

checkbox.isEnabled();

5. 按鈕(button)

找到按鈕元素:

WebElement saveButton =driver.findElement(By.id("save"));

點擊按鈕:

saveButton.click();

判斷按鈕是否enable:

 

saveButton.isEnabled ();

6. 左右選擇框

也就是左邊是可供選擇項,選擇後移動到右邊的框中,反之亦然。例如:

Select lang = new Select(driver.findElement(By.id("languages")));

lang.selectByVisibleText(“English”);

WebElement addLanguage=driver.findElement(By.id("addButton"));

addLanguage.click();

7. 彈出對話框(Popup dialogs)

Alert alert = driver.switchTo().alert();

alert.accept();

alert.dismiss();

alert.getText();

 

後面有具體的例子解釋~

8. 表單(Form)

Form中的元素的操作和其它的元素操作一樣,對元素操作完成後對錶單的提交可以:

WebElement approve =driver.findElement(By.id("approve"));

approve.click();

approve.submit();//只適合於表單的提交

9. 上傳文件 (Upload File)

上傳文件的元素操作:

WebElement adFileUpload = driver.findElement(By.id("WAP-upload"));

String filePath ="C:\test\\uploadfile\\media_ads\\test.jpg";

adFileUpload.sendKeys(filePath);

10.拖拉(Drag andDrop)

WebElement element=driver.findElement(By.name("source"));

WebElement target = driver.findElement(By.name("target"));

 

(new Actions(driver)).dragAndDrop(element,target).perform();

 

11.導航 (Navigationand History)

打開一個新的頁面:

 driver.navigate().to("http://www.example.com");

 

通過歷史導航返回原頁面:

driver.navigate().forward();

driver.navigate().back();

                                                                                                                                           

E  iframe的處理

有時候我們在定位一個頁面元素的時候發現一直定位不了,反覆檢查自己寫的定位器沒有任何問題,代碼也沒有任何問題。這時你就要看一下這個頁面元素是否在一個iframe中,這可能就是找不到的原因之一。如果你在一個default content中查找一個在iframe中的元素,那肯定是找不到的。反之你在一個iframe中查找另一個iframe元素或default content中的元素,那必然也定位不到。

selenium webdriver中提供了進入一個iframe的方法:

WebDriverorg.openqa.selenium.WebDriver.TargetLocator.frame(String nameOrId)

也提供了一個返回default content的方法:

WebDriver org.openqa.selenium.WebDriver.TargetLocator.defaultContent()

這樣使我們面對iframe時可以輕鬆應對。

以下面的html代碼爲例,我們看一下處現iframe。

 

Html代碼

 

main.html

 

<html>

   <head>

       <title>FrameTest</title>

   </head>

   <body>

         <divid = "id1">this is a div!</div>

       <iframe id = "frame" frameborder="0" scrolling="no"style="left:0;position:absolute;" src ="frame.html"></iframe>

   </body>

</html>

 

 

 

frame.html

 

<html>

   <head>

       <title>this is a frame!</title>

   </head>

   <body>

         <divid = "div1">this is a div,too!</div>

         <label>input:</label>

         <inputid = "input1"></input>

   </body>

</html>

 

 

Java代碼

 

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

importorg.openqa.selenium.firefox.FirefoxDriver;

 

public class FameStudy {

 

        

         publicstatic void main(String[] args) {

                   WebDriverdr = new FirefoxDriver();

                   Stringurl = "\\Your\\Path\\to\\main.html";

                   dr.get(url);

 

                   //在defaultcontent定位id="id1"的div

                   dr.findElement(By.id("id1"));

                  

                   //此時,沒有進入到id="frame"的frame中時,以下兩句會報錯

                   dr.findElement(By.id("div1"));//報錯

                   dr.findElement(By.id("input1"));//報錯

                  

                   //進入id="frame"的frame中,定位id="div1"的div和id="input1"的輸入框。

                   dr.switchTo().frame("frame");        

                   dr.findElement(By.id("div1"));

                   dr.findElement(By.id("input1"));

                  

                   //此時,沒有跳出frame,如果定位defaultcontent中的元素也會報錯。

                   dr.findElement(By.id("id1"));//報錯

                  

                   //跳出frame,進入defaultcontent;重新定位id="id1"的div

                   dr.switchTo().defaultContent();

                   dr.findElement(By.id("id1"));

         }

 

}

 

 

小結:

switch_to方法會new1個TargetLocator對象,使用該對象的frame方法可以將當前識別的”主體”移動到需要定位的frame上去。 

F 如何得到彈出窗口

在selenium 1.X裏面得到彈出窗口是一件比較麻煩的事,特別是新開窗口沒有id、name的時候。在selenium webdriver中得到新開窗口相對簡單的多,它無關新開窗口的id、name等屬性。以下面的html爲例:

 

 

Html代碼

 

 

<span style="white-space: normal;background-color: #ffffff;">test.html</span>

 

 

<html>

 

   <head><title>Test Popup Window</title></head>

 

   <body>

 

       <a id = "51" href = "http://www.51.com/" target ="_blank">Let's go!</a>

 

   </body>

 

</html>

 

 

下面的代碼演示瞭如何去得到彈出的新窗口

 

Java代碼

 

import java.util.Iterator;

import java.util.Set;

 

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

importorg.openqa.selenium.firefox.FirefoxDriver;

 

public class PopupWindowTest {

 

 

         /**

          * @author gongjf

          */

         publicstatic void main(String[] args) {

                   System.setProperty("webdriver.firefox.bin","D:\\ProgramFiles\\Mozilla Firefox\\firefox.exe"); 

                   WebDriverdr = new FirefoxDriver();

                   Stringurl ="\\Your\\Path\\to\\main.html";

                   dr.get(url);       

                   dr.findElement(By.id("51")).click();

                   //得到當前窗口的句柄

                   StringcurrentWindow = dr.getWindowHandle();

                   //得到所有窗口的句柄

                   Set<String>handles = dr.getWindowHandles();

                   Iterator<String>it = handles.iterator();

                   while(it.hasNext()){

                            if(currentWindow== it.next())  continue;

                            dr.switchTo().window(it.next());

                           

                   }

         }

 

}

 

輸出結果:

 

title,url = 51.com 真人配對玩遊戲,http://www.51.com/

 

小結:

 

捕獲或者說定位彈出窗口的關鍵在於獲得彈出窗口的句柄。(

在上面的代碼裏,使用windowhandle方法來獲取當前瀏覽器窗口的句柄,使用了windowhandles方法獲取所有彈出的瀏覽器窗口的句柄,然後通過排除當前句柄的方法來得到新開窗口的句柄。

在獲取新彈出窗口的句柄後,使用switchto.window(newwindow_handle)方法,將新窗口的句柄作爲參數傳入既可捕獲到新窗口了。

如果想回到以前的窗口定位元素,那麼再調用1次switchto.window方法,傳入之前窗口的句柄既可達到目的。

 

G  如何處理alert、confirm、prompt對話框

alert、confirm、prompt這樣的js對話框在selenium1.X時代也是難啃的骨頭,常常要用autoit來幫助處理。

試用了一下selenium webdriver中處理這些對話框十分方便簡潔

 

Html代碼

 

Dialogs.html  

 

<html>

 

   <head>

 

       <title>Alert</title>

 

   </head>

 

   <body>

 

       <input id = "alert" value = "alert" type ="button" onclick = "alert('歡迎!請按確認繼續!');"/>

        <input id = "confirm" value= "confirm" type = "button" onclick = "confirm('確定嗎?');"/>

         <inputid = "prompt" value = "prompt" type = "button"onclick = "var name = prompt('請輸入你的名字:','請輸入

 

你的名字'); document.write(name) "/>

        

 

   </body>

 

</html>

 

 

 以上html代碼在頁面上顯示了三個按鈕,點擊他們分別彈出alert、confirm、prompt對話框。如果在prompt對話框中輸入文字點擊確定之後,將會刷新頁面,顯示出這些文字。

 

selenium webdriver 處理這些彈層的代碼如下:

 

Java代碼

 

import org.openqa.selenium.Alert;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

importorg.openqa.selenium.firefox.FirefoxDriver;

 

public class DialogsStudy {

 

         /**

          * @author gongjf

          */

         publicstatic void main(String[] args) {

                   //TODO Auto-generated method stub

                   System.setProperty("webdriver.firefox.bin","D:\\ProgramFiles\\Mozilla Firefox\\firefox.exe"); 

                   WebDriverdr = new FirefoxDriver();

                   Stringurl = "file:///C:/Documents and Settings/gongjf/桌面/selenium_test/Dialogs.html";//"/Your/Path/to/main.html"

                   dr.get(url);

                  

                   //點擊第一個按鈕,輸出對話框上面的文字,然後叉掉

                   dr.findElement(By.id("alert")).click();

                   Alertalert = dr.switchTo().alert();

                   Stringtext = alert.getText();

                   System.out.println(text);

                   alert.dismiss();

                  

                   //點擊第二個按鈕,輸出對話框上面的文字,然後點擊確認

                   dr.findElement(By.id("confirm")).click();

                   Alertconfirm = dr.switchTo().alert();

                   Stringtext1 = confirm.getText();

                   System.out.println(text1);

                   confirm.accept();

                  

                   //點擊第三個按鈕,輸入你的名字,然後點擊確認,最後

                   dr.findElement(By.id("prompt")).click();

                   Alertprompt = dr.switchTo().alert();

                   Stringtext2 = prompt.getText();

                   System.out.println(text2);

                   prompt.sendKeys("jarvi");

                   prompt.accept();

                  

         }

 

}

 

 

小結:

 

從以上代碼可以看出dr.switchTo().alert();這句可以得到alert\confirm\prompt對話框的對象,然後運用其方法對它進行操作。對話框操作的主要方法有:

 

getText()    得到它的文本值

accept()      相當於點擊它的"確認"

dismiss()     相當於點擊"取消"或者叉掉對話框

sendKeys() 輸入值,這個alert\confirm沒有對話框就不能用了,不然會報錯。

 

 

H  如何操作cookies

 

Web 測試中我們經常會接觸到Cookies,一個Cookies主要屬性有”所在域、name、value、有效日期和路徑",下面來講一下怎麼操作Cookies

 

Java代碼

 

import java.util.Set;

 

import org.openqa.selenium.Cookie;

import org.openqa.selenium.WebDriver;

importorg.openqa.selenium.firefox.FirefoxDriver;

 

public class CookiesStudy {

 

         /**

          * @author gongjf

          */

         publicstatic void main(String[] args) {

                   //TODO Auto-generated method stub

                   System.setProperty("webdriver.firefox.bin","D:\\ProgramFiles\\Mozilla Firefox\\firefox.exe"); 

                   WebDriverdr = new FirefoxDriver();

                   dr.get("http://www.51.com");

                  

                   //增加一個name ="name",value="value"的cookie

                   Cookiecookie = new Cookie("name", "value");

                   dr.manage().addCookie(cookie);

                  

                   //得到當前頁面下所有的cookies,並且輸出它們的所在域、name、value、有效日期和路徑

                   Set<Cookie>cookies = dr.manage().getCookies();

                   System.out.println(String.format("Domain-> name -> value -> expiry -> path"));

                   for(Cookiec : cookies)

                            System.out.println(String.format("%s-> %s -> %s -> %s -> %s",

                                               c.getDomain(),c.getName(), c.getValue(),c.getExpiry(),c.getPath()));

                  

                  

                   //刪除cookie有三種方法

                  

                   //第一種通過cookie的name

                   dr.manage().deleteCookieNamed("CookieName");

                   //第二種通過Cookie對象

                   dr.manage().deleteCookie(cookie);

                   //第三種全部刪除

                   dr.manage().deleteAllCookies();

         }

 

小結:

 

上面的代碼首先在頁面中增加了一個cookie,然後遍歷頁面的所有cookies,並輸出他們的主要屬性。最後就是三種刪除cookie的方法。

 

 

I  如何等待頁面元素加載完成

web的自動化測試中,我們經常會遇到這樣一種情況:當我們的程序執行時需要頁面某個元素,而此時這個元素還未加載完成,這時我們的程序就會報錯。怎麼辦?等待。等待元素出現後再進行對這個元素的操作。

在selenium-webdriver中我們用兩種方式進行等待:明確的等待和隱性的等待。

 

明確的等待

 

明確的等待是指在代碼進行下一步操作之前等待某一個條件的發生。最不好的情況是使用Thread.sleep()去設置一段確認的時間去等待。但爲什麼說最不好呢?因爲一個元素的加載時間有長有短,你在設置sleep的時間之前要自己把握長短,太短容易超時,太長浪費時間。selenium webdriver提供了一些方法幫助我們等待正好需要等待的時間。利用WebDriverWait類和ExpectedCondition接口就能實現這一點。

 

 

下面的html代碼實現了這樣的一種效果:點擊click按鈕5秒鐘後,頁面上會出現一個紅色的div塊。我們需要寫一段自動化腳本去捕獲這個出現的div,然後高亮之。

 

 

Html代碼

 

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塊的功能:

 

Java代碼

 

import org.openqa.selenium.By;

importorg.openqa.selenium.JavascriptExecutor;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

importorg.openqa.selenium.firefox.FirefoxDriver;

importorg.openqa.selenium.support.ui.ExpectedCondition;

importorg.openqa.selenium.support.ui.WebDriverWait;

 

 

public class WaitForSomthing {

 

         /**

          * @author gongjf

          */

         publicstatic void main(String[] args) {

                   //TODO Auto-generated method stub

                   System.setProperty("webdriver.firefox.bin","D:\\ProgramFiles\\Mozilla Firefox\\firefox.exe"); 

                   WebDriverdr = new FirefoxDriver();

                   Stringurl = "file:///C:/Documents and Settings/gongjf/桌面/selenium_test/Wait.html";//"/Your/Path/to/Wait.html"

                   dr.get(url);

                   WebDriverWaitwait = new WebDriverWait(dr,10);

                   wait.until(newExpectedCondition<WebElement>(){

                            @Override

                            publicWebElement apply(WebDriver d) {

                                     returnd.findElement(By.id("b"));

                            }}).click();

                  

                   WebElementelement = 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對象實例整個生命週期都起作用。上面的代碼就變成了這樣:

 

 

Java代碼

 

 

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;

importorg.openqa.selenium.JavascriptExecutor;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

importorg.openqa.selenium.firefox.FirefoxDriver;

importorg.openqa.selenium.support.ui.ExpectedCondition;

importorg.openqa.selenium.support.ui.WebDriverWait;

 

 

public class WaitForSomthing {

 

         /**

          * @author gongjf

          */

         publicstatic void main(String[] args) {

                   //TODO Auto-generated method stub

                   System.setProperty("webdriver.firefox.bin","D:\\ProgramFiles\\Mozilla Firefox\\firefox.exe"); 

                   WebDriverdr = new FirefoxDriver();

                  

                   //設置10秒

                   dr.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);

                  

                   Stringurl = "file:///C:/Documents and Settings/gongjf/桌面/selenium_test/Wait.html";//"/Your/Path/to/Wait.html"

                   dr.get(url);

                 //註釋掉原來的

                   /*WebDriverWaitwait = new WebDriverWait(dr,10);

                   wait.until(newExpectedCondition<WebElement>(){

                            @Override

                            publicWebElement apply(WebDriver d) {

                                     returnd.findElement(By.id("b"));

                            }}).click();*/

                   dr.findElement(By.id("b")).click();

                   WebElementelement = dr.findElement(By.cssSelector(".red_box"));

                   ((JavascriptExecutor)dr).executeScript("arguments[0].style.border= \"5px solid yellow\"",element); 

                  

         }

}

 

 

小結:

 

兩種方法任選其一

 

 

J  如何利用selenium-webdriver截圖

 

在自動化測試中常常會用到截圖功能。可以截取頁面全圖,不管頁面有多長。

 

下面的代碼演示瞭如何使用webdriver進行截圖:

 

 

Java代碼

 

 

import java.io.File;

import java.io.IOException;

 

import org.apache.commons.io.FileUtils;

import org.openqa.selenium.OutputType;

import org.openqa.selenium.TakesScreenshot;

import org.openqa.selenium.WebDriver;

importorg.openqa.selenium.firefox.FirefoxDriver;

public class ShotScreen {

 

         /**

          * @author gongjf

          * @throws IOException

          * @throws InterruptedException

          */

         publicstatic void main(String[] args) throws IOException, InterruptedException {

                  

                   System.setProperty("webdriver.firefox.bin","D:\\ProgramFiles\\Mozilla Firefox\\firefox.exe"); 

                   WebDriverdr = new FirefoxDriver();

                   dr.get("http://www.51.com");

                                    

                   //這裏等待頁面加載完成

                   Thread.sleep(5000);

                   //下面代碼是得到截圖並保存在D盤下

                   FilescreenShotFile = ((TakesScreenshot)dr).getScreenshotAs(OutputType.FILE);

                   FileUtils.copyFile(screenShotFile,new File("D:/test.png"));

}

}

 

 

K  封裝與重用

 

WebDriver對頁面的操作,需要找到一個WebElement,然後再對其進行操作,比較繁瑣:

 // Find the text inputelement by itsname

WebElement element =driver.findElement(By.name("q"));

 

// Enter something to search for

element.sendKeys("Cheese!");

我們可以考慮對這些基本的操作進行一個封裝,簡化操作。比如,封裝代碼:

    protected voidsendKeys(Byby, String value){

       driver.findElement(by).sendKeys(value);

    }

那麼,在測試用例可以這樣簡化調用:

sendKeys(By.name("q"),”Cheese!”);

 

看,這就簡潔多了。

 

類似的封裝還有:

package com.drutt.mm.end2end.actions;

 

 

import java.util.List;

import java.util.NoSuchElementException;

import java.util.concurrent.TimeUnit;

 

import org.openqa.selenium.By;

import org.openqa.selenium.WebElement;

importorg.openqa.selenium.remote.RemoteWebDriver;

importorg.openqa.selenium.support.ui.WebDriverWait;

 

importcom.drutt.mm.end2end.data.TestConstant;

 

public class WebDriverAction {

 

   //protected WebDriverdriver;

   protectedRemoteWebDriverdriver;

   protectedWebDriverWaitdriverWait;

 

 

    protected booleanisWebElementExist(Byselector) {

       try {

           driver.findElement(selector);

           return true;

       } catch(NoSuchElementException e) {

           return false;

       }

    }

   

    protectedStringgetWebText(By by) {

       try {

       return driver.findElement(by).getText();

       } catch (NoSuchElementException e) {

           return "Textnot existed!";

       }

    }

   

    protectedvoidclickElementContainingText(By by, String text){

       List<WebElement>elementList = driver.findElements(by);

       for(WebElement e:elementList){

           if(e.getText().contains(text)){

               e.click();

               break;

           }

       }    

    }

   

    protectedStringgetLinkUrlContainingText(By by, String text){

       List<WebElement>subscribeButton = driver.findElements(by);

       String url = null;

       for(WebElement e:subscribeButton){

           if(e.getText().contains(text)){

               url =e.getAttribute("href");

               break;

           }

       }

       return url;

    }

   

    protected voidclick(Byby){

       driver.findElement(by).click();

       driver.manage().timeouts().implicitlyWait(TestConstant.WAIT_ELEMENT_TO_LOAD,TimeUnit.SECONDS);

    }

 

    protectedStringgetLinkUrl(By by){

       return driver.findElement(by).getAttribute("href");

    }

   

    protected voidsendKeys(Byby, String value){

       driver.findElement(by).sendKeys(value);

    }

 

小結:

 

按照上面的例子你可以對各個方法進行封裝,使自己的代碼更加簡潔!

 

L  在selenium2.0中使用selenium1.0的API

 

Selenium2.0中使用WeDriver API對頁面進行操作,它最大的優點是不需要安裝一個selenium server就可以運行,但是對頁面進行操作不如selenium1.0的Selenium RC API那麼方便。Selenium2.0提供了使用Selenium RC API的方法:

// 我用火狐瀏覽器作爲例子

WebDriver driver = newFirefoxDriver(); 

 String baseUrl="http://www.google.com"; 

Selenium selenium = newWebDriverBackedSelenium(driver, baseUrl);

 

// 執行selenium命令

selenium.open("http://www.google.com");

selenium.type("name=q","cheese");

selenium.click("name=btnG");

 

WebDriver driverInstance = ((WebDriverBackedSelenium)selenium).getUnderlyingWebDriver();

 

selenium.stop();

 

我分別使用WebDriver API和SeleniumRC API寫了一個Login的腳本,很明顯,後者的操作更加簡單明瞭。

WebDriver API寫的Login腳本:

    public void login() {

       driver.switchTo().defaultContent();

       driver.switchTo().frame("mainFrame");

 

       WebElement eUsername= waitFindElement(By.id("username"));

       eUsername.sendKeys([email protected]);

 

       WebElement ePassword= waitFindElement(By.id("password"));

       ePassword.sendKeys(manager);

 

       WebElementeLoginButton = waitFindElement(By.id("loginButton"));

       eLoginButton.click();

 

    }

   

SeleniumRC API寫的Login腳本:

    public void login() {

       selenium.selectFrame("relative=top");

       selenium.selectFrame("mainFrame");

       selenium.type("username","[email protected]");

       selenium.type("password","manager");

       selenium.click("loginButton");

}

發佈了12 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章