經過前面兩篇文章的鋪 墊,我們這篇介紹,webdriver如何處理,一個瀏覽器上多個窗口之間切換的問題。我們先腦補這樣一個測試場景,你在頁面A點擊一個連接,會在新的 tab窗口打開頁面B,這個時候,你在頁面B點擊一個連接,會在新的tab窗口打開頁面C。這種情況,在測試中經常遇到,自動化中,webdriver是 如何處理的呢。
我們先來看一個實例,在京東首頁,點擊手機,會在新的頁面顯示手機通訊的頁面,在手機頁面點擊小米,會在新的窗口打開顯示小米手機的頁面。這個過程,剛好 是頁面A到頁面B再到頁面C。我們先拋開其他的,就是先實現driver在頁面A切換到頁面B,然后切換到頁面C這個過程如何實現,在webdriver 中提供了一個switch.to.window(handle)的方法。參數handle就是前面文章中提到的獲取窗口句柄的值。
相關代碼如下:
- package lessons;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Set;
- import java.util.concurrent.TimeUnit;
- import org.openqa.selenium.By;
- import org.openqa.selenium.WebDriver;
- import org.openqa.selenium.WebElement;
- import org.openqa.selenium.chrome.ChromeDriver;
- public class ElementOpration {
- public static void main(String[] args) throws Exception {
- System.setProperty("webdriver.chrome.driver", ".\\Tools\\chromedriver.exe");
- WebDriver driver = new ChromeDriver();
- driver.manage().window().maximize();
- driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
- driver.get("https://www.jd.com/");
- Thread.sleep(1000);
- //點擊京東左側菜單中的 手機
- WebElement phone_link = driver.findElement(By.linkText("手機"));
- phone_link.click();
- Thread.sleep(1000);
- // 獲取當前頁面句柄
- String handle = driver.getWindowHandle();
- // 獲取所有頁面的句柄,並循環判斷不是當前的句柄
- for (String handles : driver.getWindowHandles()) {
- if (handles.equals(handle))
- continue;
- driver.switchTo().window(handles);
- }
- WebElement xiaomi_link = driver.findElement(By.linkText("小米"));
- xiaomi_link.click();
- Thread.sleep(1000);
- }
- }
上面在獲取handles過程寫了一個for循環,for循環的句柄和當前driver的句柄相等,那么就continue,也就是結束單循環,什么也不 做。如果不是,那么就調用切換窗口的方法,切換到第二個窗口。到了這里,可能有人就會提出,如果我需要第二個切換到第三個呢,假如說,在判斷第三個句柄不 等於第二個,那么driver會不會默認切換到第三個窗口還是切換到第一個呢。如果真要這么做,需要用到ArrayList,然后用到迭代,可能稍微變得 復雜。為了避免這種復雜情況出現,我推薦這樣做,只需要把上面代碼中的continue語句改成driver.close(),前面文章介紹 過,close是關閉當前頁面。如果是頁面A點擊鏈接打開頁面B,那么這個過程關閉的就是頁面A,同時把driver切換到頁面B。如果有第三個,從第二 個頁面到第三個頁面也是用這樣切換方法。這里永遠就兩個頁面之間處理的關系。一般來說,自動化也是盡量在一個頁面做完相關測試,才會切換到其他頁面。
修改后腳本代碼如下:
- package lessons;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Set;
- import java.util.concurrent.TimeUnit;
- import org.openqa.selenium.By;
- import org.openqa.selenium.WebDriver;
- import org.openqa.selenium.WebElement;
- import org.openqa.selenium.chrome.ChromeDriver;
- public class ElementOpration {
- public static void main(String[] args) throws Exception {
- System.setProperty("webdriver.chrome.driver", ".\\Tools\\chromedriver.exe");
- WebDriver driver = new ChromeDriver();
- driver.manage().window().maximize();
- driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
- driver.get("https://www.jd.com/");
- Thread.sleep(1000);
- //點擊京東左側菜單中的 手機
- WebElement phone_link = driver.findElement(By.linkText("手機"));
- phone_link.click();
- Thread.sleep(1000);
- // 獲取當前頁面句柄
- String handle = driver.getWindowHandle();
- // 獲取所有頁面的句柄,並循環判斷不是當前的句柄
- for (String temhandle : driver.getWindowHandles()) {
- if (!temhandle.equals(handle))
- driver.close();
- driver.switchTo().window(temhandle);
- }
- WebElement xiaomi_link = driver.findElement(By.linkText("小米"));
- xiaomi_link.click();
- Thread.sleep(1000);
- }
- }
上面實現了頁面A,切換到頁面B,同時關閉頁面A,頁面B點擊觸發頁面C,這個過程還需要用for循環判斷一次。所以關於這塊,我建議你單獨寫成一個方 法,例如靜態方法,直接調用這個,就代碼看起來很舒服。關於這個,后面我們會介紹,框架設計部分,肯定要寫不同的方法進行調用。