Watir对Dom Tree有超强的能力,但一旦超出了它的势力范围,比如 javascrīpt popup box,它就无能为力了。
解决这个问题的思路是启动另外一个进程,利用第三方工具(AutoIt),来完成对这些对象的操作。
Watir安装已经自带了AutoIt,但它的辅助方法还不太好。主要是缺少判断是否有box弹出的方法。
附件里提供有两个scrīpt,一个是作为另外一个进程运行的脚本clickJsDialogButton.rb,它的功能描述如下
1) 探测pop box
2) 如果发现了popup box,click "enter" key, or "escape" key.
"enter" key 和click OK button效果一样
"escape" key 和click Cancel button效果一样
1# argument: {ENTER}, or{ESCAPE}
2# return 0(true) if there is a box pops up, 1(false) if not.
3require'watir/WindowHelper'
4
5AutoItRetTimeout=0
6AutoItRetSucceed=1
7
8DefaultTimeOut=30
9
10IETitle="Microsoft Internet Explorer"
11PRESSKEY=ARGV.shift
12
13autoit =WIN32OLE.new('AutoItX3.Control')
14foundAndClicked =false
15
16ret = autoit.WinWaitIETitle,"",DefaultTimeOut
17ifret==AutoItRetSucceed# 0 timeout, 1 succeed
18 autoit.SendPRESSKEY
19 foundAndClicked=true
20end
21
22
23ShellExitTrue=0
24ShellExitFalse=1
25
26exitfoundAndClicked ?ShellExitTrue:ShellExitFalse
还有一个是提供操纵popup box的jsDlg.rb
module Everbright
module Util
# module JsDialog helps to handle javascrīpt popup box.
#
# Javascrīpt popup box is out of the control of Watir::IE,
# so we cannot detect/click an javascrīpt box by a Watir::IE instance.
#
# Basically, methods of JsDlg accept an block by running which there
# will pops up an javascrīpt dialog box. Then you can click "OK" or "Cancel" button of it.
#
# Also you can detect whether or not there will pop up a dialog box by method JsDlg.popAlertbox?.
# This method is especially useful to
test input validation.
module JsDlg
# click button of a pop-up js dialog box
# button can be
# :OK
# :CANCEL
#
# return thread
def clickJsDialogButton(button)
path = File.join(File.dirname(__FILE__), "clickJsDialogButton.rb")
key = button==:OK ? "{ENTER}" :
button==:CANCEL ? "{ESCAPE}" : nil
raise "buton can only be :OK or :CANCEL" if key.nil?
#puts "cmd = "+"ruby \"#{path}\" \"#{key}\""
t = Thread.new { system("ruby \"#{path}\" \"#{key}\"") }
return t
end
def toClickAlertOk #:yield:
clickJsDialogButton(:OK)
yield
end
def toClickConfirmOk #:yield:
clickJsDialogButton(:OK)
yield
end
def toClickConfirmCancel #:yield:
clickJsDialogButton(:CANCEL)
yield
end
# Whether running the block leads an alert dialog box pops up?
# if yes, click "OK" button of the alert dialog box and return true
# if no, return false
def popAlertBox?(&block)
path = File.join(File.dirname(__FILE__), "clickJsDialogButton.rb")
ret = true
t = Thread.new { ret = system("ruby \"#{path}\" \"{ENTER}\"") }
block.call
t.join
return ret
end
module_function :toClickAlertOk, :toClickConfirmOk, :toClickConfirmCancel
module_function :popAlertBox?, :clickJsDialogButton
end
end
end
使用JsDlg,操纵popup box就非常简单了,比如删除操作往往都会弹出一个confirm窗口
JsDlg.toClickConfirmOK {
ie.button(:caption, /delete/).click
}
在输入了一些非法数据后,
测试提交form时有alertbox弹出
assert_true(JsDlg.popAlertBox?{ ie.button(:caption, /Submit/).click })
注意,这里并没有处理prompt窗口。因为在我的测试中一直也没有用到