常見定位對象元素的方法
在使用selenium webdriver進行元素定位時,通常使用findElement或findElements方法結合By類返回的元素句柄來定位元素。其中By類的常用定位方式共八種,現分別介紹如下:
By.id()
id頁面元素的id一般是唯一的,使用id定位效率較高,並且定位精確
使用方法如下:
public class SearchButtonById {
public static void main(String[] args){
WebDriver driver = new FirefoxDriver();
driver.get("http://www.forexample.com");
WebElement searchBox = driver.findElement(By.id("gbqfba"));
searchBox.click();
}
}
常見定位對象元素的方法
By.name()
使用元素的name 和元素的id定位的益處類似
使用方法如下:
public class SearchButtonByName {
public static void main(String[] args){
WebDriver driver = new FirefoxDriver();
driver.get("http://www.forexample.com");
WebElement searchBox = driver.findElement(By.name("btnK"));
searchBox.click();
}
}
元素沒有id或者name,怎么辦?建議和相關開發人員溝通增加id或者name,或者使用下列方法:
By.xpath()
這個方法是非常強大的元素查找方式,使用這種方法幾乎可以定位到頁面上的任意元素。在正式開始使用XPath進行定位前,我們先了解下什么是XPath。XPath是XML Path的簡稱,由於HTML文檔本身就是一個標准的XML頁面,所以我們可以使用XPath的語法來定位頁面元素。
使用方法如下:
driver.findElement(By.xpath(“//a[contains(@href, ‘logout’)]”));
By.cssSelector()
cssSelector這種元素定位方式跟xpath比較類似,但執行速度較快,而且各種瀏覽器對它的支持都相當到位,所以功能也是蠻強大的。
使用方法如下:
WebElement password = driver.findElement(By.cssSelector("#J_login_form>dl>dt>input[id=’ J_password’]"));
By.tagName()
該方法可以通過元素的標簽名稱來查找元素。該方法跟之前兩個方法的區別是,這個方法搜索到的元素通常不止一個,所以一般建議結合使用findElements方法來使用。比如我們現在要查找頁面上有多少個button,就可以用button這個tagName來進行查找。
使用方法如下:
List<WebElement> buttons = driver.findElements(By.tagName("button"));
By.className()
className屬性是利用元素的css樣式表所引用的偽類名稱來進行元素查找的方法。對於任何HTML頁面的元素來說,一般程序員或頁面設計師會給元素直接賦予一個樣式屬性或者利用css文件里的偽類來定義元素樣式,使元素在頁面上顯示時能夠更加美觀。如果此時我們要通過className屬性來查找該button並操作它的話,就可以使用className屬性了。
使用方法如下:
WebElement searchBox = driver.findElement(By.className("buttonStyle"));
By.linkText()
這個方法比較直接,即通過超文本鏈接上的文字信息來定位元素,這種方式一般專門用於定位頁面上的超文本鏈接。
<a href="/intl/en/about.html">About Google</a>
使用方法如下:
WebElement aboutLink = driver.findElement(By.linkText("About Google"));
By.partialLinkText()
這個方法是上一個方法的擴展。當你不能准確知道超鏈接上的文本信息或者只想通過一些關鍵字進行匹配時,可以使用這個方法來通過部分鏈接文字進行匹配。
使用方法如下:
WebElement aboutLink = driver.findElement(By.partialLinkText("About"));
7.2 切換窗口、Frame和其他對象識別方法
在web應用中,常常會遇見點擊某個鏈接會彈出一個新的窗口,或者是相互關聯的web應用 ,要去操作新窗口中的元素,就需要主機切換到新窗口進行操作,不然會在之前的窗口找元素,這樣會導致找不到元素或者腳本報錯,WebDriver 提供了switchTo().window()方法可以實現在不同的窗口之間切換。
主要用到如下方法:
getWindowHandle():獲得當前窗口句柄
getWindowHandles():返回的所有窗口的句柄到當前會話
switchTo().window():用於切換到相應的窗口
switchTo().frame()默認的是取表單的ID和name屬性。如果沒有id和name ,可通過Xpath路徑定位。
對表單操作完成之后可以通過driver.switchTo().defaultContent() 跳出表單。
例如:在web應用中,前台網頁的設計一般會用到iframe/frame表單嵌套頁面的應用。簡單的就是一個頁面簽嵌套多個HEML/JSP文件。selenium webdriver 只能在同一頁面識別定位元素,可以理解成只能識別當前所在位置的頁面上的元素。對於不同的iframe/frame表單中的元素是無法直接定位的。需要結合switchTo().frame()方法切換到指定的frame/iframe中。
在web應用中,頁面有時會彈出Alert彈出框,讓用戶確認信息,處理這種情況,也需要switchTo彈窗,然后操作。
點擊ok
driver.switchTo().alert().accept();
點擊Cancel
driver.switchTo().alert().dismiss();
Selenium實現拖拽功能
1. 找到要拖拽的頁面元素-源(source)。
2. 找到要釋放的頁面元素-目標(target), 頁面顯示的這個元素可能是個坑, 但是在頁面代碼中他就是一個元素。
3. 借助(new Actions(driver)).DragAnddrop( source, target).perform(), 完成元素拖放操作。
Selenium實現拖拽功能
public static Boolean dragAndDrop(WebDriver driver, By source, By target){
try{
Actions action = new Actions(driver);
WebDriverWait wait = new WebDriverWait(driver, 60);
WebElement elementSource = wait.until(ExpectedConditions.presenceOfElementLocated(source));
WebElement elementTarget = wait.until(ExpectedConditions.presenceOfElementLocated(target));
action.dragAndDrop(elementSource, elementTarget).perform();
Sleeper.sleepTight(5);
return true;
}
catch(Exception e)
{
System.out.println(e.getClass().getName() + " " + e.getMessage());
return false;
}
}
Selenium實現上傳文件功能
普通上傳:普通的附件上傳是將本地文件的路徑作為一個值放在input 標簽中,通過form 表單將這個值提交給服務器。可以通過sendKeys("文件路徑")直接上傳。
插件上傳:一般是指基於Flash、JavaScript 或Ajax 等技術所實現的上傳功能。
插件上傳,可以使用AutoIt 實現上傳 編寫腳本 來實現。AutoIt 的安裝以及使用需要參考AutoIt 使用手冊等相關文檔。selenium 通過AutoIt 來操作window窗口的操作實質是通過java代碼來調用AutoIt 生成的腳本.exe文件。
通過Java調用的exe 程序並不在Java 的可控范圍內。換句話說,exe 執行多長時間,執行是否出錯,Java 程序都無法得知。
以下是在AutoIt 編輯器中編輯的操作文件上傳窗口的代碼:
ControlFocus("打開","","Edit1”);
識別windows窗口
WinWait("[CLASS:#32770]","",10);
窗口等待十秒
ControlSetText("打開", "", "Edit1", "C:\Users\happy\Desktop\FileUpload.html”);
想輸入框中輸入需要上傳的地址
Sleep(2000)
ControlClick("打開", "","Button1");
點擊[打開】按鈕
以下是java實現的代碼。
File file = new File("C:\\Users\\happy\\Desktop\\FileUpload.html");
// 用java來實現文件讀取功 \
driver.get(file.getAbsolutePath());
driver.findElement(By.name("uploadFile")).click();
// 點擊選擇文件按鈕
Thread.sleep(3000);
// 設置等待3秒
Runtime exe = Runtime.getRuntime();
// Java 的Runtime 模塊的getruntime.exec()方法可以調用exe 程序並執行。
try {
String str = "E://upload.exe";
exe.exec(str);
// 運行指定位置的.exe文件
} catch (IOException e) {
System.out.println("Error to run the exe");
e.printStackTrace();
}
Selenium實現鼠標、鍵盤功能
get()
driver.get("http://www.baidu.com")
打開一個網頁
sendKeys()
driver.findElement(By.id("pwdInput")).sendKeys("password");
模擬鍵盤輸入動作
-clear()
driver.findElement(By.id("pwdInput")).clear();
清除文本輸入框中的內容
-click()
driver.findElement(By.id("loginBtn")).click();
鼠標點擊事件
-contextClick()
Actions action = new Actions(driver); action.contextClick(driver.findElement(By.id("su"))).perform();
鼠標右鍵點擊指定的元素
-clickAndHold()
Actions action = new Actions(driver); action.clickAndHold(driver.findElement(By.linkText("設置"))).perform();
鼠標懸停
-moveToElement()
Actions action = new Actions(driver);
action.moveToElement(driver.findElement(By.linkText("設置"))).perform();
鼠標移動
-doubleClick()
Actions action = new Actions(driver); action.doubleClick(driver.findElement(By.name("element"))).perform();
鼠標雙擊
Selenium對瀏覽器的操作
-driver.manage().window().maximize();
窗口最大化
-driver.forward()/driver.back()
前進/后退
-driver.window_handles
返回當前瀏覽器的所有窗口
-driver.quit()/driver.close()
關閉瀏覽器
Selenium實現時間等待
隱性等待
顯式等待
implicitlyWait:
識別對象時的超時時間。過了這個時間如果對象還沒找到的話就會拋出NoSuchElement 異常
setScriptTimeout:
異步腳本的超時時間。webdriver可以異步執行腳本,這個是設置異步執行腳本腳本 返回結果的超時時間
pageLoadTimeout:
頁面加載時的超時時間。因為webdriver會等頁面加載完畢在進行后面的操作,所以如果頁面在這個超時時間內沒有加載完成,那么 webdriver 就會拋出異常。
//頁面加載超時時間設置為 5s:
driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS); driver.get("http://www.baidu.com/");
//定位對象時給 10s 的時間, 如果 10s 內還定位不到則拋出異常: driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.findElement(By.id("kw33")).sendKeys("selenium");
//異步腳本的超時時間設置成 3s
driver.manage().timeouts().setScriptTimeout(3, TimeUnit.SECONDS);
sleep 休眠方法:
當執行到 sleep()方法時會固定的休眠所設置的時長(這里以毫秒為單位);然后再繼續執行。
driver.get("http://www.baidu.com/");
Thread.sleep(2000);
Selenium處理Windows事件
Selenium 處理安全對話框 (windows security dialog)用安裝使用autoit 來代替
public void autoitHandleWin(String title,String userName,String pwd){
AutoItX x=new AutoItX();
if(x.winWaitActive(title,"",20)){
if(x.winExists(title)){
x.sleep(500);
x.ControlSetText(title,"",Edit1,userName);
x.ControlSetText(title,"",Edit1,pwd);
x.ControlClick(title,"",Button);
}
}
}
7.3 如何處理網頁出現異常的情況
如何處理網頁出現異常的情況?
1.捕獲異常,將異常寫入log日志
2.截圖記錄當時網頁
3.加入重試機制