[Watir]異常對象識別

來源:互聯網
上載者:User

5. 異常對象識別(Watir應用解決方案)

Watir基於處理,繼承於web document的對象提供較好的支援方法,但相對於處理windows對象較弱. 就目前從各網站收集的對象來看, 基本上,對於在IE執行個體對象開啟的web標準對象
能夠成功識別與操作,其它的脫離當前IE視窗,開啟的所有彈出框都不能正常識別。其中,彈出框對象佔有異常對象識別中很大一部分。
目前碰到的彈出框, 我把他們分為三大類型:
1, Alerts 警告作用,如:sorry, 目前使用者沒有許可權操作
2, Confirm 需要操作按鈕, 如:你確認要刪除目前記錄?
3, Prompt+ select +confirm  需要使用者輸入,操作查詢或點擊, 最後確認, 如:Download/upload (瀏覽+選擇檔案)

下面給出,上面幾種彈出框watir實現識別與操作的方法,
5.1. 彈出框基於autoIT + 線程實現方式

此種方法,對於第一、二種彈出框操作較有效,
因點擊某個link/button等對象,而彈出的視窗(大部分彈出框可應用此種方式來實現。)

1, 定義方法

def check_for_popups
    autoit = WIN32OLE.new('AutoItX3.Control')
    #
   
    # Do forever - assumes popups could occur anywhere/anytime in your application.
    loop do
        # Look for window with given title. Give up after 1 second.
       
        ret = autoit.WinWait('訊息 -- 網頁對話方塊', '', 1)
        #ret = WinActivate("Microsoft Internet Explorer", "")
#autoit.ControlClick("Microsoft Internet Explorer", "", "[CLASS:Button; INSTANCE:1]", 2)
       
        puts(ret)
        #
        # If window found, send appropriate keystroke (e.g. {enter}, {Y}, {N}).
       
        if (ret==1) then autoit.Send("{Enter}") end
       
        #
        # Take a rest to avoid chewing up cycles and give another thread a go.
        # Then resume the loop.
        sleep(3)
    end
  end

2, 程式體代碼

ie.button(:name, "signin").click_no_wait

sleep(20)

$popup = Thread.new { check_for_popups }  # start popup handler

at_exit { Thread.kill($popup) }

 

5.2. Call 另一ruby檔案

對於第二種彈出框,像安全警告點擊, 並不通過操作與點擊任何對象, 即呈現快顯視窗。
我嘗試用3.1方法來實現,不成功。用下面方法替代:

1, 在watir/WindowHelper.rb檔案中增加方法

   def push_security_alert_yes_cn
        @autoit.WinWait "安全警報", ""
        @autoit.Send "{TAB}"
        @autoit.Send "{TAB}"
        @autoit.Send "{SPACE}"
      End

2, 定義另一調用檔案 tmp.rb
require 'watir/WindowHelper'
helper = WindowHelper.new
helper.push_security_alert_cn_yes

3, 在開啟安全URL之前,啟動調用ruby檔案

require 'rubygems'
require 'watir'   # the watir controller
require 'win32ole'
require 'watir/WindowHelper'

Thread.new{system('ruby c:/tmp.rb')} #你定義tmp檔案存放路徑
ie = Watir::IE.new
ie.goto("http://www.alipay.com.cn/")
5.3. 修改架構底層

此種方法,針對彈出框3.

舉例一, 上傳下載檔案
1, 修改底層代碼input_elements.rb檔案,
類 FileField中, 方法set.
為了支援中文,有一句替換修改為:

system("rubyw -e /"require 'win32ole'; @autoit=WIN32OLE.new('AutoItX3.Control');waitresult=@autoit.WinWait'選擇檔案', '', 15; sleep 1; if waitresult == 1/" -e /"@autoit.ControlSetText '選擇檔案', '', 'Edit1', '#{setPath}'; @autoit.ControlSend '選擇檔案', '', 'Button2', '{ENTER}';/" -e /"end/"")

2, 定義方法
def save_file(filepath)
    ai = WIN32OLE.new("AutoItX3.Control")
    ai.WinWait("檔案下載", "", 5)
    ai.ControlFocus("檔案下載", "", "儲存(&S)")
    sleep 1
    ai.ControlClick("檔案下載", "", "儲存(&S)", "left")
    ai.WinWait("另存新檔", "", 5)
    sleep 1
    ai.ControlSend("另存新檔", "", "Edit1",filepath)
    ai.ControlClick("另存新檔", "", "儲存(&S)", "left")
    ai.WinWait("下載完畢", "", 5)
    ai.ControlClick("下載完畢", "", "關閉")
  end

3, 程式體代碼:
ie.file_field(:name, "xlsfile").set("c://samenameobject.html")
#上傳你所指定的檔案


ie.span(:text, "匯出Excel表").click_no_wait
save_file("C://abc.xls")
#下載到你所指定的路徑

 

針對彈出框3, 需要使用者介入查詢並操作:
舉例二, 中供crm中類目與客戶選擇的彈出框,與第一種實現方式不同在於,
用到autoit中WinActivate與ControlClick方法,

require 'rubygems'
require 'watir'   # the watir controller
 require 'watir/WindowHelper'
 
require 'win32ole'

def check_for_popups
 
autoit = WIN32OLE.new('AutoItX3.Control')

loop do
      ret = autoit.Winwait("選擇 -- 網頁對話方塊", "", 1)
      puts ret
     if (ret==1) then
       autoit.WinActivate("[CLASS:Internet Explorer_TridentDlgFrame]", "")
      autoit.Send("{TAB}")
      autoit.Send("{TAB}")

      #autoit.Send("湖州")
      #autoit.Send("{ASC 2709}")
      #autoit.SendUnicode("a")
      #autoit.ClipPut ("杭")
      #autoit.ClipGet
      #autoit.ToolTip "This is a tooltip杭州", 0, 0
      #autoit.Sleep 2000  
     
      autoit.Send("{TAB}")
      autoit.Send("{TAB}")
      autoit.Send("{Enter}")

      autoit.WinActivate("[CLASS:Internet Explorer_TridentDlgFrame]", "")
      autoit.ControlClick("選擇 -- 網頁對話方塊", "", "[CLASS:Internet Explorer_TridentLstBox; INSTANCE:2]", 2)

      autoit.Send("{TAB}")
      autoit.Send("{Enter}")

      autoit.Send("{TAB}")
      autoit.Send("{TAB}")
      autoit.Send("{TAB}")
      autoit.Send("{TAB}")
      autoit.Send("{Enter}")
    end
    sleep(3)
  end

end

ie=Watir::IE.new
ie.goto("http://10.2.6.4:5100/bin/member/signin")
#ie.goto("http://10.2.6.4:5100/")

#ie.element_by_xpath("//span[contains(text(), 'Main Road Nijmegen')]").click

ie.text_field(:name, "id").set("mhl1805") 
ie.text_field(:name, "password").set("zxcvbnm")

ie.button(:name, "signin").click

ie.frame(:name, "left").link(:url, "http://10.2.6.4:5100/v3/help_cust.htm").click

ie.frame(:name, "left").link(:text, "新簽中供客戶").click

 # start popup handler

ie.frame(:name, "right").frame(:name, "rtop").button(:value, "選擇客戶").click_no_wait
sleep(20)

$popup = Thread.new { check_for_popups }

at_exit { Thread.kill($popup) }

針對第三種popup window, 如果需要與使用者互動,且需要輸入中文時,若用autoit sendkey對待中文支援(但官方文檔說支援中文輸入, 網上有不少人和我遇到同樣問題),尚沒有找到有效方案,有待進一步跟進。

   除上述彈出框需要特殊處理外,watir中也有一些擴充tag,或第三方控制項需要特殊處理的,
   像:
5.4. web HTML編輯器
中文站的html編輯器提供: 操作ID或name操作起來較方便直接

require 'rubygems'
require 'watir'   # the watir controller
require 'watir/WindowHelper'
require 'win32ole'
ie=Watir::IE.new

ie=Watir::IE.attach(:title, /阿里助手/)
 
ie.text_field(:name, "_fmo.a._0.s").set("mhl1805") 
ie.document.getElementByid("_editor").contentWindow.focus()
ie.send_keys("abcsadfasfd")

但也碰到有些web頁面,不提供任何ID,只能用autoIT方法來send tab實現

require 'rubygems'
require 'watir'   # the watir controller
require 'watir/WindowHelper'
require 'win32ole'

     

ie=Watir::IE.new

#ie=Watir::IE.attach(:title, /Alibaba/)

ie.goto('http://us.my.alibaba.com/product/buyoffer/post_buying_lead.htm')

ie.text_field(:name, "_fmp.bu._0.su").set("mhl1805") 
ie.text_field(:name, "_fmp.bu._0.su").set("中國人") 

ie.checkbox(:id, "detailDesc").set
ie.checkbox(:id, "detailDesc").focus()
ie.send_keys("/t"*9)
ie.send_keys('Hello Worldabcdef')

5.5. 對象識別其它常用TAG內建方法引用

如:IE.div , ie.span, ie.cell, ie.table方法,可以實現點擊操作,取值操作等.
另外提供QTP類似描述性編程,同類型對象統計:

ie.buttons.each { |b| puts b.to_s }
 puts ie.checkboxes.length  
 puts ie.links.length 
 puts ie.buttons.length等等 

對於常用的innertext屬性, 在watir中已經封裝到方法,可以直接引用。如:
ruby在對象識別底層,封裝了innertext
實現,調用方法text即可:
如:puts ie.div(:id, "intelligentWord").link(:id, index.to_s).text

最後:返迴文本與原始碼,用下面方法:
puts ie.text()
puts ie.html() 

5.6. 識別對象Regex支援
 
當然,ruby提供強大的Regex支援,如:屬性標識正則
ie=Watir::IE.attach(:title, /Alibaba/)

Ruby的Regex以"//"作為基本架構,運算式內容位於"/"之間。運算式返回一個RegExp的對象。
運算式的一般規則:
/a/匹配字元a。
//?/匹配特殊字元?。特殊字元包括^, $, ? , ., /, /, [, ], {, }, (, ), +, *.
.匹配任一字元,例如/a./匹配ab和ac。
/[ab]c/匹配ac和bc,[]之間代表範圍。例如:/[a-z]/ , /[a-zA-Z0-9]/。
/[^a-zA-Z0-9]/匹配不在該範圍內的字串。
/[/d]/代表任一數字,/[/w]/代表任意字母,數字或者_,/[/s]/代表空白字元,包括空格,TAB和換行。
/[/D]/,/[/W]/,/[/S]/均為上述的否定情況。

關於正則其它用法,請參照《watir技術集錦》
5.7. 最後攻略

總之,對於對象識別與操作,要藉助於上述文檔中的, 靈活運用autoit, xpath與異常對象操作方法。對於watir不支援的windows控制項,想到第一個方法,就是採用第三方autoit技術,來類比鍵盤或滑鼠操作。
對於操作web對象,watir不支援特殊tag,除了擴充其底層代碼外,只能深深研究一下xpath了.
最後,再搞不定,就只能到watir group裡諮詢高人了,呵呵。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.