[小北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
声明:本博客原创文字只表明本人工做中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未受权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文链接。
相关文章
相关标签/搜索