-
php 执行linux 命令
2008-12-10 19:23:54
by leshui
dargoon项目,自动化跑测试用例
ini_set("display_errors", "On");
error_reporting(E_ALL);
include_once("lib.test.php");
$lib=new libtest();
$lib->db_conn();
//测试时间段角本;
$array_case=file("testcase/time_case.txt");
//$array_case[0]="'sssss'";
$sql="select * from device_service where dev_service_id=6";
$array_db=$lib->getall($sql);
$sc_name=$array_db[0]["scrīpt_name"];
echo $sc_name."------------------------------------";
$logname="log_".time().".log";$al_lgos="";
foreach ($array_case as $k=>$case){
$al_lgos="";
//修改数据库
$upsql="update device_service set run_time_range=\"".trim($case)."\" where dev_service_id=6 limit 1";
$lib->db_excute($upsql);
sleep(1);
//执行 agent ====================================
exec("/home/qjy/src/agent/aliprobe -d /home/qjy/src/agent/cps/ -a 0.0.0.0:7777 -m 10.2.6.21:6000 -i 1 -v3 --debug > sagent.txt &");
sleep(10);
//kill agent ===================================
exec("netstat -nlp > test.txt ");
sleep(2);
$array_agent=file("test.txt");
//根据端口号 0.0.0.0:7777 kill 线程
foreach ($array_agent as $k1=>$v1){
if (ereg("0.0.0.0:7777",$v1)){
if (ereg ("([0-9]{1,10})/python", $v1, $regs)){
$pid=$regs[1];
exec("kill -9 ".$pid);
sleep(1);
}
}
}
sleep(2);
//分析日志 =======================================
//是否存在 $sc_name
$al_lgos.=$case." ============================== \r\n";
$array_agent_logs=file("sagent.txt");
$err=0; $ok=0; $check=0; $error_lgos="";
foreach ($array_agent_logs as $keys=>$agent_logs){
if (ereg($sc_name,$agent_logs)){
//$al_lgos.="已检测试到".$sc_name." ||||| ".$agent_logs." \r\n";
if (eregi("Loading check: ".$sc_name,$agent_logs)){
//存在 说明发送成功
//eregi("(Loading check: ".$sc_name.").*?",$agent_logs,$args);
$al_lgos.="发送成功 "." ||||| ".$agent_logs."\r\n";
$ok=1;
}
$check=1;
}
if (eregi("ERROR",$agent_logs)){
$error_lgos.="**********错误 **************:"." ||||| ".$agent_logs." \r\n";
}
}
if ($check==0){
$al_lgos.="====未检测试到====".$sc_name." \r\n";
}
if ($ok==0){
$al_lgos.="----------角本".$sc_name." 没有发送成功--------- \r\n";
}
$al_lgos.=$error_lgos;
$al_lgos.=" end ======================================== \r\n";
$al_lgos.="\r\n";
//输出分析日志 =======================================
$handle = fopen("analysis/".$logname, 'a');
fwrite($handle, $al_lgos);
fclose($handle);
//break;
} -
ruby正则表达式快速指南
2008-12-09 09:28:43
by jiale
[abc] A single character: a, b or c
[^abc] Any single character but a, b, or c
[a-z] Any single character in the range a-z
[a-zA-Z] Any single character in the range a-z or A-Z
^ Start of string
$ End of string
(...) Capture everything enclosed. Any single character
\s Any whitespace character
\S Any non-whitespace character
\d Any digit
\D Any non-digit
\w Any word character (letter, number, or underscore)
\W Any non-word character(a|b) a or b
a? Zero or one of a
a* Zero or more of a
a+ One or more of a
a{3} Exactly 3 of a
a{3,} 3 or more of a
a{3,6} Between 3 and 6 of a -
kill process(ruby)
2008-11-24 09:35:52
def kill_process(name)
begin
wmi = WIN32OLE.connect("winmgmts://")
processes = wmi.ExecQuery("select * from win32_process where name='#{name}'")
for process in processes
process.terminate()
sleep 0.2
end
rescue => err
$LOG.fatal(err)
raise err
end
end -
bat获取ruby安装路径
2008-11-24 09:19:50
picassoWR的install程序希望在ruby安装完成后,获取ruby的安装路径并写入到path环境变量中,bat可以通过REG QUERY方法获取ruby的安装路径
for /f "skip=4 tokens=1,2 delims=:" %%a in ('reg query HKLM\SOFTWARE\RubyInstaller /v Path') do (
set RubyPathL=%%a
set RubyPathR=%%b
)
set RubyPath=%RubyPathL:~-1%:%RubyPathR%将RubyPath写入Path环境变量,bat需要通过更新注册表的方式更新path环境变量
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v path /t REG_SZ /d "%PATH%" /f
-
批处理抓取页面中图片对象
2008-11-23 20:37:59
By Wiston Li
watir底层中很多集合类代码如:buttons, divs, links, spans等等,方便用户用each方法来枚举。
例如下面代码,把所有image生成保存到本地。
require 'watir' browser = Watir::IE.new browser.goto('http://twitter.com') idx = 0 browser.images.each do |x| idx += 1 location = 'c:\tmp\file-' + idx.to_s + '.jpg' x.save(location) end
-
扩展watir底层,调用visible返回对象是否可见
2008-11-23 20:31:08
By Wiston Li
在用developer toolbar inspect一个对象时,属性display= none or visibility= hidden 或其父对象是hidden时,此对象在页面上显示是invisible的。
下面的方法扩展element类,并修复1.5.6bug,在写watir脚本时,即可调用object.visible?方法.
class Watir::Element
def visible?
ōbject = document
while object
begin
if object.currentstyle.invoke('visibility') =~ /^hidden$/i
return false
end
if object.currentstyle.invoke('display') =~ /^none$/i
return false
end
if object.invoke('isDisabled')
return false
end
rescue WIN32OLERuntimeError
end
ōbject = object.parentElement
end
true
end
endwatir脚本:
require 'watir'
include Watir
ie = IE.new
ie.goto("www.someplace.com")
button = ie.button(:id, 'somebutton')
if button.visible? '调用visible方法
button.click
else
ie.close
end -
获取选择框页面对象的value值
2008-11-23 19:50:14
By Wiston Li
在对页面中选择框对象进行操作时,页面显示的对象对应其item属性,如:checkbox, radiobox,select list等,但程序逻辑判断处理时,实现上是取item对应的value值,那么watir自动化脚本时,如何取到相应的value?
页面代码:
<input type="radio" name="email_frequency" value="daily">Daily Email</
input>
<input type="radio" name="email_frequency" value="weekly">Weekly
Email</input>
<input type="radio" name="email_frequency" value="monthly">Monthly
Email</input>watir脚本:
def get_values_by_name(name)
value_list = []
@browser.document.getElementsByName(name).each do |el|
value_list << el.attributes('value').value
end
return value_list
end用上述方法即可访问到value。但其调用getElementsByName,会访问到所有对象,后续,将研究一下@o.invoke来试试,直接封装到底层,只是针对某个web对象来操作.扩展watir功能。
-
watir自动化测试结果报告输出
2008-11-23 18:47:22
By Wiston Li
我们知道,ruby安装好后,其gem包已经安装log4r,在开发watir自动化脚本时可以引用,非常方便
代码问题定位,log定制,异常栈输出。但是针对用例执行时对于检查点与步骤信息,可以用HTML加简单CSS
友好显示输出结果,不过,要想做到很强大,最终还是要写到数据库中,方便查询和统计。
引用代码:
# Load classes
require 'rubygems'
require 'watir'
# The main test
begin
# Create the new report
r = CLReport.new()
testReport = r.createReport('C:\\testlocation\\reports\\Examplescrīpt')
# Start browser
browser = Watir::IE.new
browser.goto('http://www.blabla.com')
# --- START TEST ---
# Do a check and report the result
if (1 > 0)
r.addtoReport(testReport, 'Check if 1 is bigger than 0', 'PASSED', '1 is indeed bigger than 0')
else
r.addtoReport(testReport, 'Check if 1 is bigger than 0', 'FAILED', '1 is NOT bigger than 0!')
end
# Do another check and report the result
if (2 > 1)
r.addtoReport(testReport, 'Check if 2 is bigger than 1', 'PASSED', '2 is indeed bigger than 1')
else
r.addtoReport(testReport, 'Check if 2 is bigger than 1', 'FAILED', '2 is NOT bigger than 1!')
end
# --- END TEST ---
# Close browser
browser.close
# Finish the report
r.finishReport(testReport)
rescue
# Send crash info to report
r.addtoReport(testReport, 'Test crashed with reason '+$!, 'FAILED', 'Test crashed!')
# Finish the report
r.finishReport(testReport)
endCLReport类代码,请参见附件中(点文件菜单访问)。
-
[watir] 在watir中读取ini文件
2008-11-23 16:29:10
--------by nish
在window系统中,ini文件是一个很重要的配置文件,很多软件都通过ini文件的方式来进行参数的配置。在参考了网上gdsx in #ruby-lang中的一部分代码,写了读取ini文件的函数,该函数支持正则等,同时改进了原先代码中不支持等于号后有"="的情况。代码如下:
def read_ini_file(filename)
input = ""
File.open(filename){|f| input = f.read}
tamed = {}
# split data on city names, throwing out surrounding brackets
input = input.split(/\[([^\]]+)\]/)[1..-1]
# sort the data into key/value pairs
input.inject([]) {|tary, field|
tary << field
if(tary.length == 2)
# we have a key and value; put 'em to use
tamed[tary[0]] = tary[1].sub(/^\s+/,'').sub(/\s+$/,'')
# pass along a fresh temp-array
tary.clear
end
tary
}
tamed.dup.each { |tkey, tval|
tvlist = tval.split(/[\r\n]+/)
tamed[tkey] = tvlist.inject({}) { |hash, val|
array = val.split(/=/)
k = array[0]
v = array[1..-1].join("=")
k = k.strip
v= v.strip unless v.nil?
v =" " if v.nil?
first = v[0,1]
last = v[-1,1]
flag = first + last
case flag
when "\"\""
v = v[1..-2]
when "//"
v = /#{v[1..-2]}/
end
hash[k]=v
hash
}
}
tamed
end
假设ini文件如下:
[test]
key1 = /test/
key2 = "xxxxx"
[test2]
key1 = xxxx
key2 = yyyyy
则通过上述函数,读取后的内容为(返回的结果为一个Hash)
result={
"test"={
"key1" = /test/,
"key2" = "xxxxx"
},
"test2"={
"key1" ="xxxx",
"key2" = "yyyyy"
}
}
-
[watir] watir中close方法的改进
2008-11-23 16:22:18
------by nish
在watir中,默认的close的方法是通过调用ole的quit方法来实现的。但是由于quit方法需要执行一定时间。在多次运行的过程中,经常会出现ole错误,远程连接已经断开的错误。出现这个错误的原因是因为close方法中的quit方法还没有将ole对象完全destroy从而导致。
找到原因后,改进的方法也就很简单,就是在close方法中加入判断,知道要关闭的IE对象的ole对象完全destroy后才退出close方法。可以通过以下的代码实现:
def close
@closing = true
@ie.quit
begin
while
@ie.HWND
end
rescue WIN32OLERuntimeError
end
end该方法通过在调用quit方法后,再去不断的调用hwnd方法,知道ole对象销毁报错后退出程序的执行。
-
[rails学习] 在rails中使用thickbox.js
2008-10-22 17:36:46
----by Nish
thickbox.js是一个基于jquery的很不错的插件,但是由于rails默认的使用的是Prototype这个Ajax库,所以在rails中简单的通过以下代码,会出现jquery与Prototype的冲突。
<%= javascrīpt_include_tag 'jquery' %>
<%= javascrīpt_include_tag 'thickbox'%>
<%= stylesheet_link_tag "thickbox" %>目前有2种方法可以解决上面的方法:
第一种是在引入上述js库中,增加一行代码 <scrīpt> jQuery.noConflict(); </scrīpt> ,即上述代码改为:
<%= javascrīpt_include_tag 'jquery' %>
<%= javascrīpt_include_tag 'thickbox'%>
<%= stylesheet_link_tag "thickbox" %><scrīpt> jQuery.noConflict(); </scrīpt>
第二种方式是使用jrails代替默认的 Prototype库。jrais可以通过下面命令进行安装
ruby ./scrīpt/plugin install http://ennerchi.googlecode.com/svn/trunk/plugins/jrails 安装完成后,会自动把jrails用的js文件拷贝到Javascrīpt文件夹下,然后删除所有Prototype库所带的的js文件,通过下面的代码就可以正常的使用thickbox,并且,默认的,rails用的ajax库改成了jquery
<%= javascrīpt_include_tag :default%>
<%= javascrīpt_include_tag 'thickbox'%>
<%= stylesheet_link_tag "thickbox" %>或者
<%= javascrīpt_include_tag 'jquery','jquery-ui','jrails'%>
<%= javascrīpt_include_tag 'thickbox'%>
<%= stylesheet_link_tag "thickbox" %> -
ruby设置windows环境变量
2008-10-08 11:25:23
by jiale
ruby可以使用win32ole.new("Wscrīpt.Shell")的Environment操作windows环境变量
获取环境变量:
win32ole.new("Wscrīpt.Shell").Environment(type).Item(name)
type:system(系统)、user(用户)
name:环境变量名
设置环境变量:
vbs的做法:
可以直接使用
win32ole.new("Wscrīpt.Shell").Environment(type).item(name) = value
但在ruby中item(name) = value会抛语法异常
ruby的做法:
win32ole.new("Wscrīpt.Shell").Environment(type)["item",name] = value
或者使用setproperty方法
win32ole.new("Wscrīpt.Shell").Environment(type).setproperty("item", name, value)
-
ruby获取目标页面源文件
2008-10-08 09:58:03
by jiale
#获取http源文件
require 'net/http'
def get_httpsource(searchurl)
begin
url = URI.parse(searchurl)
res = Net::HTTP.get(url)
return res
rescue => err
puts err
raise err
end
end -
Ruby获取当前的执行文件的路径和目录
2008-10-08 09:53:21
by jiale
获得当前执行文件的文件名:
__FILE__
获得当前文件的目录
File.dirname(__FILE__)
获得当前执行文件的完整路径(绝对路径)
require ‘pathname’
Pathname.new(__FILE__).realpath获得当前执行文件的目录完整路径(绝对路径)
require ‘pathname’
Pathname.new(File.dirname(__FILE__)).realpath -
批量点击链接(去重)
2008-09-24 19:26:45
by jack
日前忽然有人问我,想把一个页面上的搜索结果链接都点一遍分别检查,这个脚本怎么写
想想这个需求很简单,就顺手用descrīption对象写了,以口碑网搜索结果为例,脚本如下:
SystemUtil.Run "http://bendi.koubei.com/search/searchlocal.html?option.key=%D1%C5%CA%CB%D4%B7&option.cityname=%BA%BC%D6%DD&searchFlag=1&city=2595"
Set ōDesc = Descrīption.Create()oDesc("micclass").Value="Link"
oDesc("url").Value="http://hangzhou.koubei.com/store/detail--storeId-.*"Set Lists = Browser("title:=雅虎口碑.*").Page("title:=雅虎口碑.*").ChildObjects(oDesc)
NumberOfLists = Lists.Count()For i = 0 To NumberOfLists - 1
Lists(i).click
……
Next点击的都是http://hangzhou.koubei.com/store/detail--storeId-这种格式的链接,也就是结果链接的统一格式
这里有个点要注意:descrīption对象默认就是支持正则表达式的,可以用正则表达式作为属性值
但是很快就反馈回来一个问题:页面上有重复的链接,这样实际是存在重复点击的;在结果比对时出现了点问题
想了想,就再加入了一段去重的处理,修改脚本如下:
SystemUtil.Run "http://bendi.koubei.com/search/searchlocal.html?option.key=%D1%C5%CA%CB%D4%B7&option.cityname=%BA%BC%D6%DD&searchFlag=1&city=2595"
Dim arrClickedLink()
ReDim Preserve arrClickedLink(0)Set ōDesc = Descrīption.Create()
oDesc("micclass").Value="Link"
oDesc("url").Value="http://hangzhou.koubei.com/store/detail--storeId-.*"Set Lists = Browser("title:=雅虎口碑.*").Page("title:=雅虎口碑.*").ChildObjects(oDesc)
NumberOfLists = Lists.Count()For i = 0 To NumberOfLists - 1
sCurrentLink = Lists(i).getroproperty("url")
If not isClickedLink(sCurrentLink) Then
Lists(i).click
……
End If
NextFunction isClickedLink(url)
iClickedLinkLen = ubound(arrClickedLink)
For n=0 to iClickedLinkLen
If url = arrClickedLink(n) Then
isClickedLink = True
Exit Function
End If
NextReDim Preserve arrClickedLink(iClickedLinkLen+1)
arrClickedLink(iClickedLinkLen+1) = url
isClickedLink = FalseEnd Function
-
利用托盘程序显示自动化执行进度
2008-09-17 11:12:36
by jiale
在自动化执行过程中需要显示自动化执行的进度,如果使用msgbox,就需要人工干预,且无法一直显示执行进度并实时刷新,理想的结果是脱离qtp且能够实时得到执行的进度。
在自动化执行过程中将执行进度写入文本文件,利用windos托盘程序,实时读某文件,且利用托盘程序并可显示或隐藏进度窗口。
vb托盘程序在网上可以轻易找到,不再附上。
-
webtable对象,利用嵌套字典对象来转化,从而具有逻辑意义
2008-09-10 20:25:07
by Wiston Li页面中存有大量的webtable,利用getcelldata方法,需要指定行、列的index. 但若在页面上用户
进行操作上排序,数据排列将发生变化,下面的方法,利用嵌套字典对象来转化,从而具有逻辑意义
表现访问单元格的值,从而减少参考物理单元格。(数据表如附件所示:)
Dim oDataTable
Dim solarExch
Dim nRowsset ōDataTable=objIdentifyPage ("阿里助手","n").WebTable("text:=操作指南.*","index:=0").WebTable("text:=选择.*")
Set solarExch = CreateObject("scrīpting.Dictionary")
nRows=oDataTable.rowcount
For nRow=2 to nRows
symbolKey =oDataTable.getcelldata(nRow,2)
solarExch.add symbolkey, createObject("scrīpting.Dictionary")
solarExch(symbolKey).add "quantity", oDataTable.getcelldata(nRow,3)
solarExch(symbolKey).add "price", oDataTable.getcelldata(nRow,4)
solarExch(symbolKey).add "oneprice", oDataTable.getcelldata(nRow,5)
solarExch(symbolKey).add "highprice", oDataTable.getcelldata(nRow,6)
solarExch(symbolKey).add "situation", oDataTable.getcelldata(nRow,7)
Nextmsgbox solarExch("asf").item("oneprice")'显示附土中,asf(关键词)这一行,一口价的值,并不依赖当前行列的顺序,即便重新排序。
msgbox solarExch("试纸").item("price") -
QTP api中大小写敏感的bug
2008-09-10 19:38:20
by wiston li
qtp中提供对webtable对象操作一系列的api方法,今天在对childitem使用时,令我非常晕的是,曾经使用过多次这个方法,今天突然不奏效了,原因就是很简单,传递的web object的class name大小写是敏感的,
在help里查了半天,也没有具体定义说明,故我称其bug.
dim oDataTable, iRows
Set ōDataTable = objIdentifyPage (sTitle,"n").
WebTable("text:=选 词.*", "index:=0").WebTable("text:=选择.*", "index:=0")
iRows= oDataTable.RowCountIf iRows >=2 then
Call reportManager("Pass", "webtable中数据记录检查", "当前数据表中有数据","有记录存在!","")Set ōWebLink =objIdentifyPage (sTitle,"n").WebTable("text:=选 词.*", "index:=0").WebTable("text:=选择.*", "index:=0").childItem(winGetRandNum(2, iRows), 2, "Link", 0 ) ' 如果使用childItem(winGetRandNum(2, iRows), 2, "link", 0 ),QTP即会报错。
oWebLink.click
objCloseIE sTitle,"1"else
Call reportManager("Warning", "webtable中数据记录检查", "当前数据表中有数据","没有记录存在, 数据已被误操作删除,请为此关键词准备竞价数据!","")
end if -
如何修改QTP脚本默认打开/保存的目录?
2008-08-20 19:44:04
By Wiston Li
QTP脚本开发,每次都要打开文件夹,却总是默认从C:\Program Files\Mercury Interactive\QuickTest Professional\Tests来找文件,
但基于框架开发的脚本,是保存在src\case里的,今天捣腾了一下,其默认的目录是可以修改的,
修改注册表:
1, HKEY_current_user\software\MI\QTP\mictest\TestsDirectory
2, HKEY_local_machine\software\MI\QTP\mictest\TestsDirectory
修改为:
D:\svn\10_QAArchitech_scrīpts\src
重启QTP,看一下,再打开文件是不是已经修改自定义的目录?是不是操作使用起来很爽。。。
节约个几秒是几秒,不要把心情弄槽。。。
-
异常对象识别(Watir应用解决方案)
2008-08-11 19:29:18
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}"
End2, 定义另一调用文件 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)
endend
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')]").clickie.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").clickie.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.newie=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. 识别对象正则表达式支持
当然,ruby提供强大的正则表达式支持,如:属性标识正则
ie=Watir::IE.attach(:title, /Alibaba/)Ruby的正则表达式以"//"作为基本框架,表达式内容位于"/"之间。表达式返回一个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里咨询高人了,呵呵。尚没有碰到其它更好方法。。。