我在刚学watir的时候被js弹出对话框折腾的死去活来,如何处理弹出框的方法网络上一搜一大堆,但是如何点出弹出框的文章却很少。因为如果用click或者click!方法点击会阻塞脚本,不能让脚本执行下去,而click_no_wait方法又不稳定(用ruby186-27_rc2.exe安装的ruby click_no_wait方法根本就不好用),当时差点让我对watir失去了信心。
还好在watir群里(群号25656482)的一位朋友给我提供了另一个替代click_no_wait的方法。
首先建一个ruby文件(我把它命名为ClickHelper.rb),把下面代码考进去。
#File Name: ClickHelper.rb
require 'watir'
require 'Win32API'
module Watir
class Element
def top_edge
assert_exists
assert_enabled
ole_object.getBoundingClientRect.top.to_i
end
def top_edge_absolute
top_edge + page_container.document.parentWindow.screenTop.to_i
end
def left_edge
assert_exists
assert_enabled
ole_object.getBoundingClientRect.left.to_i
end
def left_edge_absolute
left_edge + page_container.document.parentWindow.screenLeft.to_i
end
def right_click
x = left_edge_absolute
y = top_edge_absolute
#puts "x: #{x}, y: #{y}"
WindowsInput.move_mouse(x, y)
WindowsInput.right_click
end
def left_click
x = left_edge_absolute
y = top_edge_absolute
#puts "x: #{x}, y: #{y}"
# need some extra push to get the cursor in the right area
WindowsInput.move_mouse(x + 2, y + 2)
WindowsInput.left_click
end
end
end
module WindowsInput
# Windows API functions
SetCursorPos = Win32API.new('user32','SetCursorPos', 'II', 'I')
SendInput = Win32API.new('user32','SendInput', 'IPI', 'I')
# Windows API constants
INPUT_MOUSE = 0
MOUSEEVENTF_LEFTDOWN = 0x0002
MOUSEEVENTF_LEFTUP = 0x0004
MOUSEEVENTF_RIGHTDOWN = 0x0008
MOUSEEVENTF_RIGHTUP = 0x0010
module_function
def send_input(inputs)
n = inputs.size
ptr = inputs.collect {|i| i.to_s}.join # flatten arrays into single string
SendInput.call(n, ptr, inputs[0].size)
end
def create_mouse_input(mouse_flag)
mi = Array.new(7, 0)
mi[0] = INPUT_MOUSE
mi[4] = mouse_flag
mi.pack('LLLLLLL') # Pack array into a binary sequence usable to SendInput
end
def move_mouse(x, y)
SetCursorPos.call(x, y)
end
def right_click
rightdown = create_mouse_input(MOUSEEVENTF_RIGHTDOWN)
rightup = create_mouse_input(MOUSEEVENTF_RIGHTUP)
send_input( [rightdown, rightup] )
end
def left_click
leftdown = create_mouse_input(MOUSEEVENTF_LEFTDOWN)
leftup = create_mouse_input(MOUSEEVENTF_LEFTUP)
send_input( [leftdown, leftup] )
end
end
这段代码是给watir添加了几个方法(主角Watir模块的left_click方法),其原理就是通过DOM计算出控件的位置,然后再利用Windows的API在那个计算好的坐标模拟一下鼠标点击(left_click是左击,right_click是右击,我好像是在说废话)。
好了我们来测试一下,先建立一个测试用的网页,html代码如下。
<html>
<head>
<script>
function click_me()
{
alert("乖");
}
</script>
<title>test page</title>
</head>
<body>
<input id='btnClickMe' type = 'button' value = 'Click Me!' onclick='click_me()'/>
</body>
</html>
只有一个按钮,点击之后会弹出一个对话框。那我们现在写测试脚本。
require 'watir'
require 'ClickHelper'
ie = Watir::IE.attach(:title, "test page")
ie.button(:id, 'btnClickMe').click
#ie.button(:id, 'btnClickMe').click!
#ie.button(:id, 'btnClickMe').click_no_wait
#ie.button(:id, 'btnClickMe').left_click
puts "Successful"
# Deal with the pop up window.
分别使用四种方法点击button,结果:
click, click!方法都会弹出对话框,但是脚本会停止执行下面的步骤,也就是说不会输出"Successful",甚至脚本会永远卡在那里。
click_no_wait可以输出"Successful",但是不会弹出对话框(这个方法与ruby,watir的版本有关,相信很多人会遇到跟我一样的问题)。
left_click可以弹出对话框,也可以输出"Successful",正是我们想要的效果。
问题貌似要解决了,但是前几天我发现了left_click的一个缺陷,那就是当按钮不在屏幕中显示时按钮就按不到了。
我把一开始的html测试页代码改了一下,增加了点文字,然后把窗口缩放一下,弄成下图的样子。
此时按钮还在页面中,但是再用left_click方法就点不到了
。
但是遇到问题还是要解决的。这时候我想起当我们往文本框输入的时候,页面会自动将文本框调整到浏览器的屏幕中,那么如果按钮也能自动调整进来,那么就可以继续使用left_click了。
于是我查看text_field的set的源代码。在这里插一句,在cmd中输入gem server后,在浏览器地址栏里输127.0.0.1:8808就可以直接查看你已经安装的gem包的api了,非常方便(不要用IE,IE的显示有问题)。
当我看到text_field的set方法的代码时发现他要先执行一个focus的操作。
于是在自己测试脚本上也加上这一句。
require 'watir'
require 'ClickHelper'
ie = Watir::IE.attach(:title, "test page")
ie.button(:id, 'btnClickMe').focus
ie.button(:id, 'btnClickMe').left_click
puts "Successful"
# Deal with the pop up window.
这下果真成功了!脚本会先把按钮调整到屏幕中,然后再点击
!
好了,问题已经解决了,剩下的就是优化一下,把focus封装到left_click里面,这样以后就不用自己写focus了。
观察了一下,在Element类的left_edge方法中添加一句话。
def left_edge
assert_exists
assert_enabled
ole_object.focus # 这句话是我加的
ole_object.getBoundingClientRect.left.to_i
end
为了保证脚本的健壮性,必须保证每次用left_click时被操作的控件都在最前。还好watir有一个方法专门干这件事,那就是bring_to_front。
还是在left_edge里加。
def left_edge
assert_exists
assert_enabled
page_container.bring_to_front # 这句话是我加的
ole_object.focus # 这句话也是我加的
ole_object.getBoundingClientRect.left.to_i
end
大功告成。附修改过后的脚本,嫌麻烦的直接用吧。
- 大小: 53.7 KB
- 大小: 68.6 KB
分享到:
相关推荐
ruby 自动化测试,watir是一个很不错的东西
watir-cn中文语言包 watir-cn中文语言包 watir-cn中文语言包 watir-cn中文语言包 watir-cn中文语言包 watir-cn中文语言包 watir-cn中文语言包 watir-cn中文语言包 watir-cn中文语言包 watir-cn中文语言包 watir-cn...
watir测试框架介绍 watir测试框架介绍 watir测试框架介绍
安装命令:gem install watir --local。
在这里我们先介绍一下如何使用sikuli+jruby+watir-web_driver来实现基于web的自动化测试,因此在开始之前,我们需要安装一些基本工具。在这里下载安装sikuli:http://sikuli.org/download.shtml注意:1,si
开源自动化测试工具组合:Ruby+Watir安装 安装准备: 1. 工具安装包准备: Ruby官方下载地址:http://www.ruby-lang.org/zh_cn/downloads/,稳定版本Ruby 1.8.6 Watir下载地址:...
开源自动化测试工具组合:Ruby+Watir安装 安装准备: 1. 工具安装包准备: Ruby官方下载地址:http://www.ruby-lang.org/zh_cn/downloads/,稳定版本Ruby 1.8.6 Watir下载地址:...
Hi all, I had to rebuild my box and I currently am unable to install Watir. gem install watir ERROR: Error installing watir: activesupport requires Ruby version >= 1.8.7. Which would be fine if ...
watir语法的详细介绍和描述,适合watir初学者。
watir介绍及安装
Watir测试框架介绍、环境配置、API介绍
该文档比较详细地介绍了自动化测试工具watir
ie .sikuli_image(:image=>"1.png").double_click right_click 右击事件 exist? 判断用户元素是否存在 edit = ie.text_field(:name,"username") if edit.exist?() #The highlighted edit.flash ...
压缩包中包含目前2013/01/19最新的安装文件,有rubyinstaller-1.9.2-p136、DevKit-tdm-32-4.5.1-20101214-1400-sfx、rubygems-1.8.24、watir-4.0.2、watir-webdriver-0.6.2等文件,并附上简略安装说明。
公司自动化测试培训ppt,使用语言ruby,自动化测试工具watir,讲解基础api和常用框架
2.本地安装watir-1.4.1.gem,执行gem install watir-1.4.1.gem -l 3.本地安装rubygems-update-1.3.4.gem,执行 gem install rubygems-update-1.3.4.gem 4.更新rubygems,执行update_rubygems (这一步先忽略,有影响...