Selenium UI自动化解决iframe定位问题
2017-04-19 19:25
134 查看
更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢!
原文链接:http://www.cnblogs.com/zishi/p/6735116.html
一个阴雨霏霏的午后,我边听音乐边打开VS2010开始写case。就像大多数人一样,我先打开了一个之前成功的案例,然后把大部分的框架复制+粘贴,这样子很快就完成了第一个并且运行成功。可是在写第二个的时候却出了状况,Selenium无论如何都无法找到页面上的一个很基本的超链接页面元素。这简直是不可思议,因为代码结构和之前成功的两个一模一样,我又迅速的比较了一下页面结构,也是一样!我开始怀疑是否有特殊的js导致Selenium无法运行?排查一番后仍然一无所获。
在这种诡异的情况下,我试图用比较直接的方法去抓元素,比如Xpath定位。于是打开IDE工具,录制再把脚本抠出来,但是用Css和Xpath统统仍旧是失败。我又仔细的把之前成功的两个case代码运行了几遍,发现问题了,原来我最初拿来做样板的case就是错误的!但是它的错误藏得很深,它虽然没有抓到那个元素,但是它抓到另外一个类似的元素并且幸运的每次都可以跑出来类似的结果,实际上这个跑出来的效果和正确的效果是一样的,因此如果不看具体代码是永远不可能被发现的!现在局面变得有些困难了,因为所有三条case都是失败的,而且代码都是错的,这意味着需要推翻之前的思路,重新设计解决方案。
无奈之下,我开始用最基础的方法进行定位:先找到第一层元素A,然后在元素A里找第二层B,这样层层进行到第四层后,代码失效无法跟踪了。这时候能够最后定位到的元素叫做:” iframe” .而我需要定位的超链接元素a还在更深层,到底是什么原因导致无法跟踪失败呢?
我开始翻一些资料,首先是从Confluence上找到一篇关于谨慎使用iframe的文章,虽然读起来似乎很有道理,不过并不能解决我的问题。继续搜索,在csdn上找到一篇关于
Selenium定位Frame的文章(传送门),虽然是用ruby写的,不过非常有参考价值,其中提到了从当前识别的frame switch到需要定位到的frame方法,看到这句话,仿佛一道曙光划破夜空,我想起来之前遇到的一个alert弹出窗口问题,最后就是用switch方法解决的,ok,到这里解决问题的思路已经有了,下面来看看怎么具体实现。
首先还是初始化一个IWebDriver:
private IWebDriver _Driver;
然后令人惊喜的发现,在 SwitchTo() 果然支持frame:
IWebDriver Frame(IWebElement frameElement);
接下来就是具体实现了:
代码写到这里,基本上已经完成了我们用例的功能,接下来需要去验证代码是否成功了,非常凑巧的是,由于代码最后的动作是点击超链接,弹出新的网页,因此又用到一次SwitchTo()的功能,而且这次是SwitchTo().Window,需要去抓一个WindowHandle,好吧,可以当做练手了:
这样最终代码就完成了,包括定位和点击页面元素,最后验证是否跳转到新页面(这里也可以分开写,不过为了大家看的方便,这里就堆在一起了 J ):
最后惯例是总结:
首先是对问题的定位,如果没有唯一id或者无法用xpath等方法抓取的时候,就要去分析一下,是不是有什么特殊的难点?然后是寻找方法,这个可以问同事或者自己查资料,总之不能一直钻牛角尖,各种方向都要探索。
另外一点需要警惕的是对老case的依赖,以为以前的能跑通的就是好的,其实不然。因为时间紧、项目急等各种原因,以前的代码也存在了各种问题漏洞,稍不注意就会吃亏,由此也提醒一下,代码上传后一定要做好Code Review工作,给我们的test case再上一道保险。
作者原创技术文章,转载请注明出处
原文链接:http://www.cnblogs.com/zishi/p/6735116.html
一个阴雨霏霏的午后,我边听音乐边打开VS2010开始写case。就像大多数人一样,我先打开了一个之前成功的案例,然后把大部分的框架复制+粘贴,这样子很快就完成了第一个并且运行成功。可是在写第二个的时候却出了状况,Selenium无论如何都无法找到页面上的一个很基本的超链接页面元素。这简直是不可思议,因为代码结构和之前成功的两个一模一样,我又迅速的比较了一下页面结构,也是一样!我开始怀疑是否有特殊的js导致Selenium无法运行?排查一番后仍然一无所获。
在这种诡异的情况下,我试图用比较直接的方法去抓元素,比如Xpath定位。于是打开IDE工具,录制再把脚本抠出来,但是用Css和Xpath统统仍旧是失败。我又仔细的把之前成功的两个case代码运行了几遍,发现问题了,原来我最初拿来做样板的case就是错误的!但是它的错误藏得很深,它虽然没有抓到那个元素,但是它抓到另外一个类似的元素并且幸运的每次都可以跑出来类似的结果,实际上这个跑出来的效果和正确的效果是一样的,因此如果不看具体代码是永远不可能被发现的!现在局面变得有些困难了,因为所有三条case都是失败的,而且代码都是错的,这意味着需要推翻之前的思路,重新设计解决方案。
无奈之下,我开始用最基础的方法进行定位:先找到第一层元素A,然后在元素A里找第二层B,这样层层进行到第四层后,代码失效无法跟踪了。这时候能够最后定位到的元素叫做:” iframe” .而我需要定位的超链接元素a还在更深层,到底是什么原因导致无法跟踪失败呢?
我开始翻一些资料,首先是从Confluence上找到一篇关于谨慎使用iframe的文章,虽然读起来似乎很有道理,不过并不能解决我的问题。继续搜索,在csdn上找到一篇关于
Selenium定位Frame的文章(传送门),虽然是用ruby写的,不过非常有参考价值,其中提到了从当前识别的frame switch到需要定位到的frame方法,看到这句话,仿佛一道曙光划破夜空,我想起来之前遇到的一个alert弹出窗口问题,最后就是用switch方法解决的,ok,到这里解决问题的思路已经有了,下面来看看怎么具体实现。
首先还是初始化一个IWebDriver:
private IWebDriver _Driver;
然后令人惊喜的发现,在 SwitchTo() 果然支持frame:
IWebDriver Frame(IWebElement frameElement);
接下来就是具体实现了:
//初始化 private IWebDriver _Driver; //等待页面加载 _Driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(120)); //先定位第一层 IWebElement a = _Driver.FindElement(By.ClassName("home-sidebar")); //根据第一层元素定位第二层 IWebElement b = a.FindElement(By.Id("div-gpt-ad-1338866029601-0")); //根据第二层定位了第三层 IWebElement c = b.FindElement(By.TagName("iframe")); //运用SwitchTo定位到具体的frame _Driver.SwitchTo().Frame(c); //从drame里定位最终的元素 _Driver.FindElement(By.Id("aw0")).Click();
代码写到这里,基本上已经完成了我们用例的功能,接下来需要去验证代码是否成功了,非常凑巧的是,由于代码最后的动作是点击超链接,弹出新的网页,因此又用到一次SwitchTo()的功能,而且这次是SwitchTo().Window,需要去抓一个WindowHandle,好吧,可以当做练手了:
string mainWindowHandle = _Driver.CurrentWindowHandle; foreach (string winHandle in _Driver.WindowHandles) { _Driver.SwitchTo().Window(winHandle); if (winHandle != mainWindowHandle) break; }
这样最终代码就完成了,包括定位和点击页面元素,最后验证是否跳转到新页面(这里也可以分开写,不过为了大家看的方便,这里就堆在一起了 J ):
public void Img_Click()
{
//初始化 private IWebDriver _Driver; //等待页面加载 _Driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(120)); //先定位第一层 IWebElement a = _Driver.FindElement(By.ClassName("home-sidebar")); //根据第一层元素定位第二层 IWebElement b = a.FindElement(By.Id("div-gpt-ad-1338866029601-0")); //根据第二层定位了第三层 IWebElement c = b.FindElement(By.TagName("iframe")); //运用SwitchTo定位到具体的frame _Driver.SwitchTo().Frame(c); //从drame里定位最终的元素 _Driver.FindElement(By.Id("aw0")).Click();
//仍旧是等待页面加载
_Driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(120));
//定位当前的handle
string mainWindowHandle = _Driver.CurrentWindowHandle;
//如果handle不同就跳出
foreach (string winHandle in _Driver.WindowHandles)
{
_Driver.SwitchTo().Window(winHandle);
if (winHandle != mainWindowHandle)
break;
}
//结束
}
最后惯例是总结:
首先是对问题的定位,如果没有唯一id或者无法用xpath等方法抓取的时候,就要去分析一下,是不是有什么特殊的难点?然后是寻找方法,这个可以问同事或者自己查资料,总之不能一直钻牛角尖,各种方向都要探索。
另外一点需要警惕的是对老case的依赖,以为以前的能跑通的就是好的,其实不然。因为时间紧、项目急等各种原因,以前的代码也存在了各种问题漏洞,稍不注意就会吃亏,由此也提醒一下,代码上传后一定要做好Code Review工作,给我们的test case再上一道保险。
作者原创技术文章,转载请注明出处
相关文章推荐
- python + selenium webdriver 通过python来模拟鼠标、键盘操作,来解决SWFFileUpload调用系统底层弹出框无法定位问题
- 解决Selenium弹出新页面无法定位元素问题(Unable to locate element)
- 转来的--轻松自动化---selenium-webdriver(python) (七)---定位iframe——转来的
- 关于Selenium自动化的定位问题
- Selenium2学习-013-WebUI自动化实战实例-011-WebElement.getText()值为空问题探索及解决
- UI自动化-解决win7 64位 ODBC数据源找不到SYBASE驱动问题
- Selenium2+python自动化46-js解决click失效问题
- selenium对未在屏幕展示范围内的元素进行操作时,出现元素无法定位的问题解决
- 解决Selenium2Library中的select frame无法选择没有名字,没有id的frame或者iframe的问题
- selenium全自动获取控件定位方式,完美解决ui频繁变动 模块
- selenium时间控件无法定位问题解决方案
- selenium打开新标签页无法定位到元素问题解决办法
- py+selenium IE 定位到元素,但点击不了元素的问题【已解决】
- selenium学习之子页面(iframe)切换以及自动化速度较快的问题
- Robotframework解决Selenium2Library中的select frame无法选择没有name也没有id的frame或者iframe的问题
- selenium +phantomjs 登录126邮箱 iframe定位问题
- Selenium2学习-024-WebUI自动化实战实例-022-网站不同分辨率下页面样式展示兼容性问题解决方案 -- 设置浏览器显示区域大小(无人值守,节约测试成本的福音,BOSS 最爱)
- selenium-java,解决一些加了显性等待和隐性等待都不好使的情况,以及给UI自动化加上暂停功能
- JBuilder Editor中光标不能正确定位问题的解决
- 多层嵌套Iframe的自适应问题解决