標籤:
在實際的自動化測試過程中,我們會遇見許多需要對視窗進行處理的情況。比如,點擊刪除某條資訊的時候系統會顯示一個Alert框。或者點擊某個超連結時會在瀏覽器中開啟一個新的頁面。這一篇,來和大家分享一下Selenium WebDriver視窗處理相關的API。那麼,還是照例先看一下本文主要涉及到的話題:
- 視窗處理介面:ITargetLocator
- 瀏覽器快顯視窗的處理(新頁面)
- JavaScript彈出框的處理:Alert, Confirm, Prompt
- 內嵌架構的處理:Frame , iFrame
(一)視窗處理介面:ITargetLocator
Selenium WebDriver處理視窗能力主要是由WebDriver對象的SwitchTo()方法返回的對象提供的。該對象實現了ITargetLocator介面,也基本涵蓋了本文所有描述的所有情況(即對快顯視窗,JS模態視窗,內嵌架構的處理)。我們可以通過以下代碼擷取當前驅動的ITargetLocator對象:
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介面的定義如下所示,這裡我先簡要的介紹一下這些方法的作用(本文後面會逐個介紹):
- 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可以彈出模態對話方塊。在介紹處理這些彈出的表單之前我們先回顧一下瀏覽器內建的彈出框都有哪些類型:
- 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, Prompt3 alert.Dismiss(); //取消:Confirm, Prompt4 var text = alert.Text; //擷取提示內容:Alert , Confirm, Prompt5 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.
- [小北De編程手記] : Lesson 01 - Selenium For C# 之 環境搭建
- [小北De編程手記] : Lesson 02 - Selenium For C# 之 核心對象
- [小北De編程手記] : Lesson 03 - Selenium For C# 之 元素定位
- [小北De編程手記] : Lesson 04 - Selenium For C# 之 API 上
- [小北De編程手記] : Lesson 05 - Selenium For C# 之 API 下
- [小北De編程手記] : Lesson 06 - Selenium For C# 之 流程式控制制
- [小北De編程手記] : Lesson 07 - Selenium For C# 之 視窗處理
- [小北De編程手記] : Lesson 08 - Selenium For C# 之 PageFactory
- [小北De編程手記] : Lesson 09 - Selenium For C# 總結
說明:
沒有超連結的文章寫完發表後,我會添加相應的連結,在此先列出目錄。
Demo地址:https://github.com/DemoCnblogs/Selenium
如果您認為這篇文章還不錯或者有所收穫,可以點擊右下角的
【推薦】按鈕,因為你的支援是我繼續寫作,分享的最大動力!小北@North來源:http://www.cnblogs.com/NorthAlan聲明:本部落格原創文字只代表本人工作中在某一時間內總結的觀點或結論,與本人所在單位沒有直接利益關係。非商業,未授權,貼子請以現狀保留,轉載時必須保留此段聲明,且在文章頁面明顯位置給出原文串連。
[小北De編程手記] : Lesson 07 - Selenium For C# 之 視窗處理