[小北De編程手記] : Lesson 07 - Selenium For C# 之 窗口處理

  在實際的自動化測試過程當中,咱們會碰見許多須要對窗口進行處理的狀況。好比,點擊刪除某條信息的時候系統會顯示一個Alert框。或者點擊某個超連接時會在瀏覽器中打開一個新的頁面。這一篇,來和你們分享一下Selenium WebDriver窗口處理相關的API。那麼,仍是照例先看一下本文主要涉及到的話題:html

  • 窗口處理接口:ITargetLocator
  • 瀏覽器彈出窗口的處理(新頁面)
  • JavaScript彈出框的處理:Alert, Confirm, Prompt
  • 內嵌框架的處理:Frame , iFrame

(一)窗口處理接口:ITargetLocator

  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

  • ActiveElement:獲取當前焦點所在的元素,若是沒有持有焦點的元素將返回Body元素(這個方法與窗口處理無關)。
  • Alert:切換到JS彈出的模態窗口。
  • DefaultContent:獲取第一個頁面上的Frame,當有iFrames的時候將獲取主頁面的Document。
  • Frame:此方法有三個重載的實現,用來切換到到Frame。
  • ParentFrame:選中獲取當前頁面的父輩Frame。
  • Window:切換窗口。
 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或是頁面內容... ...等其餘條件進行判斷。佈局

(三)JavaScript彈出框的處理

  稍有Web編程經驗的人都應該知道JavaScript能夠彈出模態對話框。在介紹處理這些彈出的窗體以前咱們先回顧一下瀏覽器內置的彈出框都有哪些類型:post

  • Alert:只有文字和一條提示信息以及一個確認按鈕(用於提示用戶)。
  • Confirm:較Alert多了一個取消按鈕(用於向用戶確認信息)。
  • Prompt:較Confirm多了一個文本輸入框(向用戶確認信息的同時能夠獲取用戶輸入)
  • AuthenticationCredentials:用於輸入用戶名和密碼的窗口(下圖中沒有給出)。

  好了,如今咱們開始介紹如何處理這些彈出框。上面咱們提到過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接口的對象進行處理):

  • Text:獲取彈出框文本信息(適用於全部模態窗口)  
  • Accept:點擊肯定按鈕(適用於全部模態窗口)
  • Dismiss:點擊取消按鈕(適用於Confirm,Prompt,AuthenticationCredentials)
  • SendKeys:輸入文本信息(適用於Prompt)
  • SetAuthenticationCredentials:設置用戶名和密碼(適用於AuthenticationCredentials)

  是否是 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接口處理各類窗口。

  • 窗口處理接口:ITargetLocator
  • 瀏覽器彈出窗口的處理(新頁面)
  • JavaScript彈出框的處理:Alert, Confirm, Prompt
  • 內嵌框架的處理:Frame , iFrame

《Selenium For C#》的相關文章:Click here.

說明:Demo地址:https://github.com/DemoCnblogs/Selenium

 

若是您認爲這篇文章還不錯或者有所收穫,能夠點擊右下角的 【推薦】按鈕,由於你的支持是我繼續寫做,分享的最大動力!
做者:小北@North
來源:http://www.cnblogs.com/NorthAlan
聲明:本博客原創文字只表明本人工做中在某一時間內總結的觀點或結論,與本人所在單位沒有直接利益關係。非商業,未受權,貼子請以現狀保留,轉載時必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
相關文章
相關標籤/搜索