天天看點

robotFrameworks_frame|window終級解決法

以下是我用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終級解決法

三、對于例子2 新打開的視窗沒有title,用url不能定位到,如何解決呢? 比如:點選“充值退款”出現如圖視窗。Select window url=xxxx 根本定位不了。  

robotFrameworks_frame|window終級解決法

方法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終級解決法

switch to new window關鍵字:

robotFrameworks_frame|window終級解決法

使用舉例:

robotFrameworks_frame|window終級解決法

==============================分割線==================================

按上述添加上,然後可以使用他新添加的關鍵字了。   網上大神隻寫了辦法,沒有說明他的關鍵字的使用方法。 我研究了下用法,實驗成功。具體腳本如下。

解釋:

@{b} get window handles

Select window by handle  ${b[1]}

四、特殊下拉框的選擇   對于這種下拉框,一拉啥沒有。

robotFrameworks_frame|window終級解決法

代碼中也沒有任何可操作的select option标簽等。如何是好。 既然下拉框,那就總可以選擇。我們輸入一個名“王XX”,下拉框自動出現這樣。

robotFrameworks_frame|window終級解決法

但是怎麼選擇上?代碼實在沒有相應的元素來操作啊。 不過,我們操作鍵盤,向下鍵,enter鍵,即可成功選擇。 那問題就變成如何在robotframework+selenium2library中操作鍵盤。api給的很簡單,press key  xxxx。 查了向下鍵的ascii為40,enter鍵的為13.但是久經試驗都不對。網上說可以考慮看下selenium的源碼中向下鍵的辨別用“\ue015”,好奇怪,我也不懂,就用了,果真對了。 相應腳本:  

robotFrameworks_frame|window終級解決法
robotFrameworks_frame|window終級解決法

有了鍵盤操作,一系列的特殊下拉框應該沒有問題了。 對于一些不能用ascii碼操作鍵盤的,可以查下selenium的源碼,,看看源碼裡對某個鍵的表示到底是什麼。    

五、對于頁面彈個框 類似于網頁彈出的這樣的框。應該更準确的說,是alert(“”)彈出的對話框。

robotFrameworks_frame|window終級解決法

兩步即可:  

robotFrameworks_frame|window終級解決法
robotFrameworks_frame|window終級解決法

六、對于在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()。