在實際的自動化測試過程當中,咱們會碰見許多須要對窗口進行處理的狀況。好比,點擊刪除某條信息的時候系統會顯示一個Alert框。或者點擊某個超連接時會在瀏覽器中打開一個新的頁面。這一篇,來和你們分享一下Selenium WebDriver窗口處理相關的API。那麼,仍是照例先看一下本文主要涉及到的話題:html
Selenium WebDriver處理窗口能力主要是由WebDriver對象的SwitchTo()方法返回的對象提供的。該對象實現了ITargetLocator接口,也基本涵蓋了本文全部描述的全部狀況(即對彈出窗口,JS模態窗口,內嵌框架的處理)。咱們能夠經過如下代碼獲取當前驅動的ITargetLocator對象:git
1 /// <summary> 2 /// demo1 : 獲取目標定位對象 3 /// </summary> 4 [Fact(DisplayName = "Cnblogs.WindowProcess.Demo1", Skip = "Just Demo")] 5 public void WindowProcess_Demo1() 6 { 7 // 1. 獲取窗口定位對象 8 IWebDriver driver = new FirefoxDriver(); 9 //省略部分代碼... ... 10 ITargetLocator locator = driver.SwitchTo(); 11 //後續操做... ... 12 driver.Close(); 13 }
ITargetLocator接口的定義以下所示,這裏我先簡要的介紹一下這些方法的做用(本文後面會逐個介紹):github
1 // Summary: 2 // Defines the interface through which the user can locate a given frame or 3 // window. 4 public interface ITargetLocator 5 { 6 IWebElement ActiveElement(); 7 IAlert Alert(); 8 IWebDriver DefaultContent(); 9 IWebDriver Frame(int frameIndex); 10 IWebDriver Frame(IWebElement frameElement); 11 IWebDriver Frame(string frameName); 12 IWebDriver ParentFrame(); 13 IWebDriver Window(string windowName); 14 }
如上一小節所述,Selenium WebDriver對彈出窗口的處理主要是經過ITargetLocator.Window方法。下面我就來向你們介紹一下Selenium WebDriver中經常使用的窗口定位方式:編程
參照ITargetLocator.Window方法的定義,該方法接受一個窗口的名稱。所以咱們能夠經過窗口的名稱切換到該窗口(前提是開發人員定義了這個窗口的名字):瀏覽器
1 // 1. 獲取窗口定位對象 2 IWebDriver driver = new FirefoxDriver(); 3 //省略部分代碼... ... 4 ITargetLocator locator = driver.SwitchTo(); 5 driver = locator.Window("windowName"); 6 //後續操做... ... 7 driver.Quit();
咱們能夠經過上面的代碼切換窗口,可是問題來了,咱們怎麼獲取到窗口的名字呢?全部的瀏覽器都有執行JS腳本的命令行工具,咱們只須要輸入「window.name」即可以看見當前窗口的名字了,下圖是我在Firebug中的操做:框架
不少狀況下,開發人員是不會爲每個彈出的窗口定義名稱的(實際上也沒有這個必要)。那麼,咱們就須要用其餘的方式來定位咱們的目標窗口了,下面的代碼使用了窗口句柄和標題定位須要訪問的窗口,咱們能夠經過WebDriver對象的WindowHandles屬性獲取當前瀏覽器打開的全部句柄,在根據頁面的特定條件(這裏是用的標題)來判斷哪個句柄是須要操做的界面句柄。通常的狀況下,咱們須要保存當前的頁面句柄,這樣能夠方便後操做完成以後能準確的返回當前頁面。Demo的最後驗證了操做頁面的標題是否正確,代碼以下:工具
1 /// <summary> 2 /// demo2 : 根據標題定位元素 3 /// </summary> 4 [Fact(DisplayName = "Cnblogs.WindowProcess.Demo2")] 5 public void WindowProcess_Demo2() 6 { 7 var articleName = "[小北De編程手記] : Lesson 02 - Selenium For C# 之 核心對象"; 8 9 _output.WriteLine("Step 01 : 啓動瀏覽器並打開Lesson 01 - Selenium For C#"); 10 IWebDriver driver = new FirefoxDriver(); 11 driver.Url = "http://www.cnblogs.com/NorthAlan/p/5155915.html"; 12 13 _output.WriteLine("Step 02 : 點擊連接打開新頁面。"); 14 var lnkArticle02 = driver.FindElement(By.LinkText(articleName)); 15 lnkArticle02.Click(); 16 17 _output.WriteLine("Step 03 : 根據標題獲取新頁面的句柄。"); 18 var oldWinHandle = driver.CurrentWindowHandle; 19 foreach (var winHandle in driver.WindowHandles) 20 { 21 driver.SwitchTo().Window(winHandle); 22 if (driver.Title.Contains(articleName)) 23 { 24 break; 25 } 26 } 27 28 _output.WriteLine("Step 04 : 驗證新頁面標題是否正確。"); 29 var articleTitle = driver.FindElement(By.Id("cb_post_title_url")); 30 Assert.Equal<string>(articleName, articleTitle.Text); 31 32 _output.WriteLine("Step 05 : 關閉瀏覽器。"); 33 driver.Quit(); 34 }
值得說明的是,第22行代碼使用了Title的內容作爲判斷是不是新開的頁面的條件,這裏你也能夠根據實際的須要使用Url或是頁面內容... ...等其餘條件進行判斷。佈局
稍有Web編程經驗的人都應該知道JavaScript能夠彈出模態對話框。在介紹處理這些彈出的窗體以前咱們先回顧一下瀏覽器內置的彈出框都有哪些類型:post
好了,如今咱們開始介紹如何處理這些彈出框。上面咱們提到過ITargetLocator.Alert方法能夠用來處理模態窗口。該方法的返回對象實現了IAlert接口:測試
1 // Summary: 2 // Defines the interface through which the user can manipulate JavaScript alerts. 3 public interface IAlert 4 { 5 string Text { get; } 6 void Accept(); 7 void Dismiss(); 8 void SendKeys( string keysToSend); 9 void SetAuthenticationCredentials( string userName, string password); 10 }
在此,須要澄清一下,以前介紹的四種彈出窗口都是用實現了IAlert接口的對象描述的(也就是說Confirm,Prompt,AuthenticationCredentials均可以用實現了IAlert接口的對象進行處理):
是否是 so... ... easy? 下面仍是照例看一下具體的使用代碼:
1 IAlert alert = driver.SwitchTo().Alert(); //轉到彈出框 2 alert.Accept(); //肯定:Alert , Confirm, Prompt 3 alert.Dismiss(); //取消:Confirm, Prompt 4 var text = alert.Text; //獲取提示內容:Alert , Confirm, Prompt 5 alert.SendKeys("input text."); //輸入提示文本:Prompt
本文的最後,我來介紹一下關於網頁內嵌框架的處理。早期的一些B/S系統會用iFrame和Frame進行佈局和頁面的嵌套。以前也有利用iFrame構建全局彈出框的設計方式。所以,若是大家的產品已經有多年的歷史。那麼,你可能會須要處理這部分的內容。其實Frame和iFrame的處理和窗口很相似,這裏我簡單的給出一個Demo:
1 ITargetLocator tagetLocator = driver.SwitchTo(); 2 tagetLocator.Frame(1); //frame index. 3 tagetLocator.Frame("frameName"); //frame frame name. 4 5 IWebElement frame = driver.FindElement(By .Id("frameId or iframeId" )); 6 tagetLocator.Frame(frame); 7 tagetLocator.DefaultContent();
從上面的代碼中能夠看到,可使用index,frame name,或者frame對象把Driver切換到Frame上。
總結:本文主要介紹如何利用Selenium WebDriver核心的ITargetLocator接口處理各類窗口。
《Selenium For C#》的相關文章:Click here.
說明:Demo地址:https://github.com/DemoCnblogs/Selenium