以下是我用robotframework + selenium2library做自动化测试遇到的一些问题,及解决方法。对于初学者应该有些帮助。

一、 对于元素的外层包括frame/iframe标签的。一定要先select  frame name=xxx,然后再操作元素。

Select frame name=新建个案

click element  id=  xxxxx

 

 

二、 对于window.showModalDialog()模式打开的新窗口 Eg.点击“支付详情”的“详情”,出来一个新页面。如何定位呢?单纯的select window title=payDetail page  是定位不到新窗口的。解决办法如下:

第一句话取的Id就是要点击按钮的Id,已经实验过,网上的经验也说明,直接click element id=xxx 是没有效果的。要用下面的第一句javascript执行点击按钮。  

 

robotFrameworks_frame|window终级解决法_子窗口

 

为了防止图片不能观看还是贴一下码吧:

robotFrameworks_frame|window终级解决法_下拉框_02

 

三、对于例子2 新打开的窗口没有title,用url不能定位到,如何解决呢? 比如:点击“充值退款”出现如图窗口。Select window url=xxxx 根本定位不了。  

robotFrameworks_frame|window终级解决法_子窗口_03

 

方法1:网上有大神在selenium的源码里添加了几个关键字。这样我们就可以使用了。

操作如下: D:\Python27\Lib\site-packages\robotframework_selenium2library-1.1.0-py2.7.egg\Selenium2Library\locators  (根据自身情况而定) 中的windowmanager.py 增加了方法      

def select_by_handle(self, browser, toHandle):
browser.switch_to_window(toHandle)
def get_window_handles(self, browser):
return [ window_info[0] for window_info in self._get_window_infos(browser) ]
def get_current_window_handle(self, browser):
return browser.get_current_window_handle()
D:\Python27\Lib\site-packages\robotframework_selenium2library-1.1.0-py2.7.egg\Selenium2Library\keywords 中的_browsermanagement.py 增加如下方法
def select_window_by_handle(self, locator=None):
self._window_manager.select_by_handle(self._current_browser(), locator)
def get_window_handles(self):
"""Returns and logs handles of all windows known to the browser."""
return self._log_list(self._window_manager.get_window_handles(self._current_browser()))
def get_current_window_handle(self):
"""Returns and logs handle of current window known to the browser."""
return self._log_list(self._window_manager.get_current_window_handle(self._current_browser()))

方法2:

如果是点击链接(Link),按钮(Button)或者元素(Element)而产生新的窗口(不是新的标签页,这个可以在IE中设置总是产生新的Window窗口),一般需要先切换到子窗口做些子任务,然后回到父窗口。一般俩窗口切换Select Window就够了,但是有时候会有意外参与的窗口,比如有意外的子窗口在子任务期间产生,或者父窗口-子窗口-父窗口-新子窗口的重复过程中有子窗口没有及时关闭,回到父窗口不一定可靠。 

下面的关键字用了一个新的思路:在点击产生新窗口前后,拿所有window handles做差异比较,找出新来的那个handle,如果没找到则关键字失败。

Index Item From List
[Arguments] ${element} @{items}
${index}= Set Variable ${0}
: FOR ${item} IN @{items}
Return From Keyword If '${element}' == '${item}' ${index}
${index}= Set Variable ${index + 1}
Return From Keyword ${-1}
Get New Window Handle
[Arguments] @{win_all}
@{win_all_curr}= Get Window Handles
${idx}= Set Variable ${-1}
: FOR ${win} IN @{win_all_curr}
${idx}= Index Item From List ${win} @{win_all}
Return From Keyword If ${idx} == ${-1} ${win}
Should Be True 0 == 1 #No win handle or no new handle

Click Out Child Window And Select It
[Arguments] ${item} ${item_type}=Link
${win_curr}= Get Current Window Handle
@{win_hds}= Get Window Handles
Run Keyword Click ${item_type} ${item}
${win_child}= Get New Window Handle @{win_hds}
Select Window By Handle ${win_child}
[Return] ${win_curr} ${win_child}

 方法3:

Selenium 2中,Browser对应浏览器实例进程,Window对应标签页。

当用Open Browser方法打开一个新的浏览器,这个浏览器下的各个标签页就构成了多个Window,每个Window都有一个window_info[]依次保存handle,id,name,title,url。Robot Framework的作者可能出于简化技术性使用的考虑,仅提供name,title,url之类的用户可见量用于Select Window,不使用唯一性更好的handle(其实很容易加进去)。

所以, 在Robot中切换到指定的window,可以先Switch Browser | ${open_browser_index} 到指定的浏览器实例(firefox,IE或者chrome),然后调用Select Window到指定的window。但如果name,title和url都不能够唯一确定,就不能正确完成这个动作。特别是很多弹出窗口,这些参数都是省掉的,怎么办呢?

我的设计是比较执行触发新窗口的动作前后所有的windows handles,找出新出来的哪一个。因为browser.get_window_handles()的范围是本browser进程管理的windows,且Robot不是并发的,所以新的窗口能够保证唯一性。

Get New Window Handle关键字:

robotFrameworks_frame|window终级解决法_子窗口_04

 

switch to new window关键字:

 

robotFrameworks_frame|window终级解决法_子窗口_05

使用举例:

robotFrameworks_frame|window终级解决法_父窗口_06

 

==============================分割线==================================

按上述添加上,然后可以使用他新添加的关键字了。   网上大神只写了办法,没有说明他的关键字的使用方法。 我研究了下用法,实验成功。具体脚本如下。

 

解释:

@{b} get window handles

Select window by handle  ${b[1]}

 

四、特殊下拉框的选择   对于这种下拉框,一拉啥没有。

 

robotFrameworks_frame|window终级解决法_下拉框_07

 

代码中也没有任何可操作的select option标签等。如何是好。 既然下拉框,那就总可以选择。我们输入一个名“王XX”,下拉框自动出现这样。

 

robotFrameworks_frame|window终级解决法_父窗口_08

 

但是怎么选择上?代码实在没有相应的元素来操作啊。 不过,我们操作键盘,向下键,enter键,即可成功选择。 那问题就变成如何在robotframework+selenium2library中操作键盘。api给的很简单,press key  xxxx。 查了向下键的ascii为40,enter键的为13.但是久经试验都不对。网上说可以考虑看下selenium的源码中向下键的标识用“\ue015”,好奇怪,我也不懂,就用了,果真对了。 相应脚本:  

robotFrameworks_frame|window终级解决法_父窗口_09

 

robotFrameworks_frame|window终级解决法_子窗口_10

 

有了键盘操作,一系列的特殊下拉框应该没有问题了。 对于一些不能用ascii码操作键盘的,可以查下selenium的源码,,看看源码里对某个键的表示到底是什么。    

五、对于页面弹个框 类似于网页弹出的这样的框。应该更准确的说,是alert(“”)弹出的对话框。

 

robotFrameworks_frame|window终级解决法_子窗口_11

 

两步即可:  

 

robotFrameworks_frame|window终级解决法_下拉框_12

 

robotFrameworks_frame|window终级解决法_下拉框_13

 

六、对于在jenkins上运行出现奇怪错误。

对于一些测试用例,明明本地和远程robotframework都跑的很顺畅,在jenkins上构建就一直出这样的错误: WebDriverException: Message: u'unknown error: Element is not clickable at point (69, 444). Other element would receive the click: 这种鬼错误,很烦躁。  

解决办法: Click  element  xxx  换成 execute javascript  document.getElementById('xxx').click() 基本换成javascript执行,都会轻松通过。

如果元素没有ID的话,要用css定位的话,我用的jquery来执行。 Execute javascript  $(“css”).click()。