ruby watir 整理

上一篇 / 下一篇  2011-02-12 16:11:32 / 个人分类:软件测试

v MO&om l Ft*u,k3v/P0转自:http://beike.javaeye.com/blog/351236

`j:nYM)E0

Z%xKr a$g.w05. 异常对象识别(Watir应用解决方案)51Testing软件测试网3fr.`,\w+}6\F*f

51Testing软件测试网F%k~O+vB/RU R

Watir基于处理,继承于webdocument的对象提供较好的支持方法,但相对于处理windows对象较弱. 就目前从各网站收集的对象来看, 基本上,对于在IE实例对象打开的web标准对象
yS%F] ]@3L"L0能够成功识别与操作,其它的脱离当前IE窗口,打开的所有弹出框都不能正常识别。其中,弹出框对象占有异常对象识别中很大一部分。51Testing软件测试网u3E3LK}TZn!D
目前碰到的弹出框, 我把他们分为三大类型:
:O'Lf wj'Cxf$J,Ri01, Alerts 警告作用,如:sorry, 当前用户没有权限操作51Testing软件测试网g8]O4W Q3T9@
2, Confirm 需要操作按钮, 如:你确认要删除当前记录?51Testing软件测试网;D N HsD0a vV
3, Prompt+ select +confirm  需要用户输入,操作查询或点击, 最后确认, 如:Download/upload (浏览+选择文件)51Testing软件测试网}'LBn Y#M

crWBB!j R5pcp0下面给出,上面几种弹出框watir实现识别与操作的方法,51Testing软件测试网$gJ6}\,sb jS
5.1. 弹出框基于autoIT + 线程实现方式

OB2pr`(Z051Testing软件测试网/uND1o4YPi

此种方法,对于第一、二种弹出框操作较有效,51Testing软件测试网3}U(crk9nS%BR
因点击某个link/button等对象,而弹出的窗口(大部分弹出框可应用此种方式来实现。)51Testing软件测试网NDk*Ew*K\AC

51Testing软件测试网2kAVMX L2~]2K)gIe

1, 定义方法

3x k.Ou:j\051Testing软件测试网7m g;U.~bX

def check_for_popups
#X[sf M |#K8r0    autoit = WIN32OLE.new('AutoItX3.Control')51Testing软件测试网[3sr7w wR"A*a,y\!z
    #
'Jj/Tc;]3iZ,tC,wT$k0   51Testing软件测试网%xiCV0M*n
    # Do forever - assumes popups could occur anywhere/anytime in your application.
`.WgZcoa,NL0    loop do51Testing软件测试网kGA d KE
        # Look for window with given title. Give up after 1 second.
z-l%o(dm[;uj0       
:T9^/RUgp&i$]0        ret = autoit.WinWait('消息 -- 网页对话框', '', 1)
l bIjap0        #ret = WinActivate("Microsoft Internet Explorer", "")51Testing软件测试网#B*i _1QE(S.q
#autoit.ControlClick("Microsoft Internet Explorer", "", "[CLASS:Button; INSTANCE:1]", 2)51Testing软件测试网4t%F{5ACx!H!k5m4e
       
)B%W;@MpC{0        puts(ret)51Testing软件测试网%q%[.Ss4I.ox7U
        #51Testing软件测试网 bIPx#JM X
        # If window found, send appropriate keystroke (e.g. {enter}, {Y}, {N}).51Testing软件测试网|4I,bE:dnoK7C3y {
       51Testing软件测试网7?K1} x{Eq1N:A
        if (ret==1) then autoit.Send("{Enter}") end
E:v`\TN^0       
FV&pEY-_0        #
\-\gul4`8u0        # Take a rest to avoid chewing up cycles and give another thread a go.51Testing软件测试网C;T6Pp [X D0sN8}
        # Then resume the loop.51Testing软件测试网] Z4Al5by
        sleep(3)
we^L I1E0    end51Testing软件测试网3D.IQ5li6W
  end51Testing软件测试网Yo3T"]H'vd9m

51Testing软件测试网|J1I uOB.G'E.A5H

51Testing软件测试网b1\:U3UWzJ }
2, 程序体代码

'l!l4Lt;X051Testing软件测试网(n%o J%{B

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

HqAx"n0

|&X"i`q t(y0sleep(20)51Testing软件测试网a1^ K"j(l(JyNr+@

z&d~;X@.c~pb:D0$popup = Thread.new { check_for_popups }  # start popup handler51Testing软件测试网D%gm*ULU

H]ma!D3K0at_exit { Thread.kill($popup) }

;@'kb`}DiNu051Testing软件测试网2Zv{Z%iY8~Q8YCP

 

lqV#sX/{F0

?(z B0\e!X4L051Testing软件测试网 _,_BO~%BQF
5.2. Call 另一ruby文件

PU z,{HR.WA {051Testing软件测试网!XnXra?M

对于第二种弹出框,像安全警告点击, 并不通过操作与点击任何对象, 即呈现弹出窗口。
3j`@0B&bo(B)[0我尝试用3.1方法来实现,不成功。用下面方法替代:

A;v7lu0D(E!T0

JI.P~\b8Y0
!gt2S9|7j)?} n5}01, 在watir/WindowHelper.rb文件中增加方法

&}*w&I!M?[9w6^051Testing软件测试网q?.ds_9Z \

   def push_security_alert_yes_cn
n^ a-t `j0        @autoit.WinWait "安全警报", ""51Testing软件测试网5k8d:e(E ~-g X5VF
        @autoit.Send "{TAB}"
P%Q3]$k6k;ei'BN0        @autoit.Send "{TAB}"51Testing软件测试网Se:ResT
        @autoit.Send "{SPACE}"51Testing软件测试网5KnY F^,P3S
      End

RqLR+Z7B)F?051Testing软件测试网F^ R:d cF#|#e

2, 定义另一调用文件 tmp.rb
-NdH4Bi"Du0require 'watir/WindowHelper'
%q$i_\3y%w%W0helper = WindowHelper.new51Testing软件测试网$U1bQ$mL*sd9v
helper.push_security_alert_cn_yes

+V)b"^V6sv051Testing软件测试网0W2P7}+B*{_$H


,T8b,@0AJ&t%q(h03, 在打开安全URL之前,启动调用ruby文件

"w)^7}h{0

m%P)NpB0require 'rubygems'
e/D8e#rI2[@8t4v3{0require 'watir'   # the watir controller51Testing软件测试网4C \ g'\![n"fK
require 'win32ole'
i7R/jlKTz0require 'watir/WindowHelper'

ah])B:b*N1X051Testing软件测试网4|,Ga4ZM f

51Testing软件测试网W1@}v+c
Thread.new{system('ruby c:\tmp.rb')} #你定义tmp文件存放路径
X6h[2ZrKl0ie = Watir::IE.new
[Q'Jl:fth0U0ie.goto("http://www.alipay.com.cn/")51Testing软件测试网| d]C[{pB
5.3. 修改框架底层51Testing软件测试网,Ri X[1|'~

?-i`9iL0此种方法,针对弹出框3.

i[\ }^0

hM R8W?&C0举例一, 上传下载文件51Testing软件测试网/`:tWh [p
1, 修改底层代码input_elements.rb文件,
O3qqEPyv.e\`e0类 FileField中, 方法set.51Testing软件测试网 ~.yqK k"F/E+y7H
为了支持中文,有一句替换修改为:51Testing软件测试网:u*D&a8[Z3\:R&s$TZ q

51Testing软件测试网6d*F'NUc(X z6C]'hz

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\"")

QC,z5WEj5B9{I051Testing软件测试网'C n/B$o|3W/CB4Md


4^k'u1{+g/xDw%\02, 定义方法51Testing软件测试网 Z kec]fz
def save_file(filepath)51Testing软件测试网 M luv!W^%PS5e
    ai = WIN32OLE.new("AutoItX3.Control")51Testing软件测试网(\ @@)gQ
    ai.WinWait("文件下载", "", 5)51Testing软件测试网 w AQ f8Mmz
    ai.ControlFocus("文件下载", "", "保存(&S)")51Testing软件测试网:K\g9A%k%|
    sleep 1
A VER,Q7o0    ai.ControlClick("文件下载", "", "保存(&S)", "left")
:H1l0F0{2jv z Q0    ai.WinWait("另存为", "", 5)51Testing软件测试网rJ)Z[9H&O?YT
    sleep 1
]W%[h%h|%I K0    ai.ControlSend("另存为", "", "Edit1",filepath)51Testing软件测试网J&k[p%O,[
    ai.ControlClick("另存为", "", "保存(&S)", "left")51Testing软件测试网 Q$@qovN]
    ai.WinWait("下载完毕", "", 5)
?k|O]bF,YZ&f0    ai.ControlClick("下载完毕", "", "关闭")51Testing软件测试网\ZZ(l d~f
  end

Q/HZ7h!J-z9HW0

j|P `1ye7h051Testing软件测试网 TP_1a| [|Oc
3, 程序体代码:51Testing软件测试网/W Yo8W"rC4E$P M
ie.file_field(:name, "xlsfile").set("c:\\samenameobject.html")51Testing软件测试网uMQ T@W
#上传你所指定的文件

I {P9`Bgs0

yRA'w+{qwB051Testing软件测试网+J_QVR0tS
ie.span(:text, "导出Excel表").click_no_wait51Testing软件测试网 c8d"e6Dw I@0}.b
save_file("C:\\abc.xls")51Testing软件测试网:b{(Il\e
#下载到你所指定的路径51Testing软件测试网ON`7w+y!w1sn

;i1UI K Y%r*Z0 51Testing软件测试网IVC|4|@w;M

51Testing软件测试网}*K*t$[*_ W ~(T

针对弹出框3, 需要用户介入查询并操作:
,hx.V _p(N W|b4`0举例二, 中供crm中类目与客户选择的弹出框,与第一种实现方式不同在于,
b Mu,k-{M4r2C4Xb0用到autoit中WinActivate与ControlClick方法,

a eD9e(G051Testing软件测试网+xqUn:^+@w


!_/O QgG*m)e0require 'rubygems'
R$i;I$Jc _0require 'watir'   # the watir controller
(?0kzw!i0 require 'watir/WindowHelper'51Testing软件测试网W+_-_V'ck:L6E ^
 51Testing软件测试网| q'v&N7QqDm!|r.@
require 'win32ole'

6U)W:Jn/b6G+W(g051Testing软件测试网2s6T.[)KA:N }


*p I"OEF,TySC0def check_for_popups
Lm_(Xk(G*S0 
['K6[X.kdc0autoit = WIN32OLE.new('AutoItX3.Control')

K.Qe5k c051Testing软件测试网TZt s4{oO1Sv

loop do
j l:O\br;Y&J%T0      ret = autoit.Winwait("选择 -- 网页对话框", "", 1)
+Xlb's? C yA$j-w0      puts ret
}&t8h4yL0     if (ret==1) then
W$L+l:_8?_b0       autoit.WinActivate("[CLASS:Internet Explorer_TridentDlgFrame]", "")51Testing软件测试网 b1Fs uhb0WS
      autoit.Send("{TAB}")
tYTg~S,fo f uN0      autoit.Send("{TAB}")51Testing软件测试网J lL_v6}

6o7@k%w"s3s0      #autoit.Send("湖州")51Testing软件测试网)D\0k*oEo?
      #autoit.Send("{ASC 2709}")
6rR-}s2}0      #autoit.SendUnicode("a")51Testing软件测试网U*C a(Xg4dQ
      #autoit.ClipPut ("杭")51Testing软件测试网4mmy!@#L^?"^6|5v2^
      #autoit.ClipGet
0BKS7NaGZ/V0      #autoit.ToolTip "This is a tooltip杭州", 0, 0
P@"Y,[]hu0      #autoit.Sleep 2000  51Testing软件测试网qRU'H ?
     51Testing软件测试网#Y_,C q3b c4N
      autoit.Send("{TAB}")51Testing软件测试网)s$Q:V&V;~&{2djj2l2P
      autoit.Send("{TAB}")
h(Y4no@0A0      autoit.Send("{Enter}")

N%~-G oJ.hb4X0

P u:|9z H&K0      autoit.WinActivate("[CLASS:Internet Explorer_TridentDlgFrame]", "")
.R*E!y Hx;{C0      autoit.ControlClick("选择 -- 网页对话框", "", "[CLASS:Internet Explorer_TridentLstBox; INSTANCE:2]", 2)

-WGX:X%v4n+\2f!zH051Testing软件测试网8@3N^o2Y

      autoit.Send("{TAB}")51Testing软件测试网 ju pu!D N HG
      autoit.Send("{Enter}")51Testing软件测试网1K9@w }P[

51Testing软件测试网%weBab3{1a/nT

      autoit.Send("{TAB}")51Testing软件测试网Z }EL*x"sY
      autoit.Send("{TAB}")
)g_^ C`%r0      autoit.Send("{TAB}")
2W*`3?R R"R;p:U?0      autoit.Send("{TAB}")
3x6zjy.a0      autoit.Send("{Enter}")51Testing软件测试网TL]C.kC3O$c
    end51Testing软件测试网)Sey!k] ^B6P
    sleep(3)
+h#Re.AH0  end51Testing软件测试网`H{Tg5^1^^c M

51Testing软件测试网0gCO hg;m

end

)`"Q7O[8~:M051Testing软件测试网{[0]7l({~+h

51Testing软件测试网PSM LaIW
ie=Watir::IE.new
7a6g}x7db9er h0ie.goto("http://10.2.6.4:5100/bin/member/signin")
;^%I an+]:^9r0#ie.goto("http://10.2.6.4:5100/")51Testing软件测试网&p+g0QS[8v?$?&K

51Testing软件测试网W9Gm1M-WU!b

51Testing软件测试网9Dy#G9m:_z
#ie.element_by_xpath("//span[contains(text(), 'Main Road Nijmegen')]").click

6KLEh I,?)^;~Sk0

Y}ab2V V0ie.text_field(:name, "id").set("mhl1805") 
"{$d0V$h3v-{f0ie.text_field(:name, "password").set("zxcvbnm")

enI P w.PC.Z051Testing软件测试网.F ?um.B!G

ie.button(:name, "signin").click51Testing软件测试网J+e6]3?~yzn

51Testing软件测试网5@[J1Lf

51Testing软件测试网}9g%X;Js
ie.frame(:name, "left").link(:url, "http://10.2.6.4:5100/v3/help_cust.htm").click51Testing软件测试网ZT[C;C)y,a#|u

51Testing软件测试网 av,c!p nj,I

ie.frame(:name, "left").link(:text, "新签中供客户").click51Testing软件测试网%s5U{*Le3g @2]

51Testing软件测试网9z xa*G5l'q

 # start popup handler51Testing软件测试网)k'P3lkN.f

!W:n4k3ZU.AZ^h0
0`kJ,CP `wsc0ie.frame(:name, "right").frame(:name, "rtop").button(:value, "选择客户").click_no_wait51Testing软件测试网 p"gm2x&g0k4y?
sleep(20)51Testing软件测试网&Z g/m0B?$f*F?

:v]7f3S(o)I)m{0$popup = Thread.new { check_for_popups }51Testing软件测试网Z%pY._k S:v6W

51Testing软件测试网z%SAH ~,h]

at_exit { Thread.kill($popup) }

tFqN g8cijM051Testing软件测试网|xZUkOOTSN}

针对第三种popup window, 如果需要与用户交互,且需要输入中文时,若用autoit sendkey对待中文支持(但官方文档说支持中文输入, 网上有不少人和我遇到同样问题),尚没有找到有效方案,有待进一步跟进。

`4H3v{R/H0

v^|)O_VI/H0ZcU0   除上述弹出框需要特殊处理外,watir中也有一些扩展tag,或第三方控件需要特殊处理的,51Testing软件测试网S~p7R6q
   像:
] U*n3t1D1BOuOn05.4. web HTML编辑器51Testing软件测试网 w+m|laf
中文站的html编辑器提供: 操作ID或name操作起来较方便直接

r6oSfFQ*K0

'tY(Td R*knN'jm0require 'rubygems'
D ` p5laX,Z~r0require 'watir'   # the watir controller
s}*P8c*Cg0require 'watir/WindowHelper'
m!h3d*n,d+oB7Kk0require 'win32ole'51Testing软件测试网 qaW{/[vt
ie=Watir::IE.new51Testing软件测试网Ts ?VK

O.Fvdt!j&CK0ie=Watir::IE.attach(:title, /阿里助手/)
eN#?G)WU0 51Testing软件测试网qcn xL2o-TP
ie.text_field(:name, "_fmo.a._0.s").set("mhl1805") 
(Fidh+Yk1i0ie.document.getElementByid("_editor").contentWindow.focus()51Testing软件测试网 q0~+Nq+L gfP"x
ie.send_keys("abcsadfasfd")

HB5_7] _:x051Testing软件测试网B!st{&BT

51Testing软件测试网.Lm+q~8dP
但也碰到有些web页面,不提供任何ID,只能用autoIT方法来send tab实现51Testing软件测试网1ChIW$g*h$Y0ly

6qF D6{$z#L9D @0
2kp:pGtn`6z;j0require 'rubygems'51Testing软件测试网+eroS+E9Y A
require 'watir'   # the watir controller
!u"u%m eRl6f0require 'watir/WindowHelper'51Testing软件测试网 ux]Z"W
require 'win32ole'51Testing软件测试网AJL1~&{9?q

r&A%{`z!E{EG0 

p;v8L@j0

a{/Z3{mh3t051Testing软件测试网"i&aQ,x e5P8g&{#S
ie=Watir::IE.new51Testing软件测试网'Oo*v-{t"S(y R

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

6ZV-x x#mG_%e051Testing软件测试网-a3~N]EnL

ie.goto('http://us.my.alibaba.com/product/buyoffer/post_buying_lead.htm')51Testing软件测试网e(q%FK W%r0p [

gH^V t4BP!Un0ie.text_field(:name, "_fmp.bu._0.su").set("mhl1805") 
"Sbo4\,^:x0ie.text_field(:name, "_fmp.bu._0.su").set("中国人") 

-tY.N B;L:L051Testing软件测试网 _q.e-p W7` ti


X6` yNO%}Ji D%l0ie.checkbox(:id, "detailDesc").set
!jb cKr#v2v \0ie.checkbox(:id, "detailDesc").focus()51Testing软件测试网.x&C3@2yK(|
ie.send_keys("\t"*9)
8W3V!Af+t_0ie.send_keys('Hello Worldabcdef')51Testing软件测试网#ZP4K!P \(uaTi

EixRy0
Ma)X/[.F0?05.5. 对象识别其它常用TAG内置方法引用

[Kh6p+[*hTr|$B0

hf`oZj&X0如:IE.div , ie.span, ie.cell, ie.table方法,可以实现点击操作,取值操作等.
Xd?'F;cz1J;~0另外提供QTP类似描述性编程,同类型对象统计:51Testing软件测试网kW5Q4G/r:{{_

51Testing软件测试网;JxSAOI8h%W

ie.buttons.each { |b| puts b.to_s }51Testing软件测试网X!fyOR,Y\"T
 puts ie.checkboxes.length  51Testing软件测试网EVZ$?e*c
 puts ie.links.length 51Testing软件测试网s3a1K,WCudf
 puts ie.buttons.length等等 51Testing软件测试网Y.idYA7z0E$r

51Testing软件测试网 O m Ov8ogwbX

对于常用的innertext属性, 在watir中已经封装到方法,可以直接引用。如:51Testing软件测试网9^T7YIDv4G?o,e
ruby在对象识别底层,封装了innertext51Testing软件测试网z;k6w"UE+yC+M|}
实现,调用方法text即可:
Zrdg kK7v0如:puts ie.div(:id, "intelligentWord").link(:id, index.to_s).text

r_FGN-J0

Z|VCSxF7H0最后:返回文本与源代码,用下面方法:
j%wENF#[3U!_DP0puts ie.text()51Testing软件测试网8tZ.lUK,Vs
puts ie.html() 51Testing软件测试网)SpN3XtG

\EyW6D F@/~+z05.6. 识别对象正则表达式支持
?+m;ZoS/s)z0 
d(q sX:oz#p:T0当然,ruby提供强大的正则表达式支持,如:属性标识正则
H2L@H {8fn0ie=Watir::IE.attach(:title, /Alibaba/)51Testing软件测试网 jf+n%[ YDh0V2P

51Testing软件测试网&B#[lX,pAo*K

Ruby的正则表达式以"//"作为基本框架,表达式内容位于"/"之间。表达式返回一个RegExp的对象。51Testing软件测试网Y&Q!dM'F7oR%V
表达式的一般规则:51Testing软件测试网4cGt'yG$B5n
/a/匹配字符a。
"q#y,iG!i0/\?/匹配特殊字符?。特殊字符包括^, $, ? , ., /, \, [, ], {, }, (, ), +, *.51Testing软件测试网Bt%IYwW
.匹配任意字符,例如/a./匹配ab和ac。51Testing软件测试网1h)ZE5Wp%i4[*gf
/[ab]c/匹配ac和bc,[]之间代表范围。例如:/[a-z]/ , /[a-zA-Z0-9]/。
7?{ nG z0/[^a-zA-Z0-9]/匹配不在该范围内的字符串。51Testing软件测试网*mS8~r"zT5eF ?Ca
/[\d]/代表任意数字,/[\w]/代表任意字母,数字或者_,/[\s]/代表空白字符,包括空格,TAB和换行。51Testing软件测试网OU0U no'O(g U z(C(j
/[\D]/,/[\W]/,/[\S]/均为上述的否定情况。51Testing软件测试网I/~k{"_pJ?NC

!R3^E~+G5}1z0关于正则其它用法,请参照《watir技术集锦》51Testing软件测试网2J7W7J-]mWp6T
5.7. 最后攻略51Testing软件测试网%cIA+g4D QWU#q!X!z d

_m5|)xRP.OQ\0Ov0总之,对于对象识别与操作,要借助于上述文档中的, 灵活运用autoit, xpath与异常对象操作方法。对于watir不支持的windows控件,想到第一个方法,就是采用第三方autoit技术,来模拟键盘或鼠标操作。
E:D7u#j RR0对于操作web对象,watir不支持特殊tag,除了扩展其底层代码外,只能深深研究一下xpath了.51Testing软件测试网^b:`t9l&H0N;k
最后,再搞不定,就只能到watir group里咨询高人了,呵呵。

(r+e,nq9N#f&QCM|M$e0

i)F[u H0尚没有碰到其它更好方法。。。51Testing软件测试网V1h}ag

*o1tf{1e0 

S%} B"Dy051Testing软件测试网[r/s+U L'En1W @-f

 

8[ yj,sh0

]Z,y5Lwq,o3AmI0 51Testing软件测试网-|+z+O$R"KP'J-Z)J

T*soFKaZP'W0一些错误

8Y YTe{0

%G$K?;Q1VL4Y$}0m:p0如果报错 AutoITX3, it helps to make automation happen51Testing软件测试网R#x1te]

51Testing软件测试网M7bwL"r,E'O X

那就在windows 下运行51Testing软件测试网Hd,kB'\o0P m

zP-j#gP$SU0regsvr32 "C:\ruby\lib\ruby\gems\1.8\gems\watir-1.6.2\lib\watir\AutoItX3.dll"51Testing软件测试网],SCk7d\/k-X\QT

51Testing软件测试网 ^[ I}_-Rz6g

 51Testing软件测试网5c'JZ3M1k

51Testing软件测试网2Do3]$tJ1a:D

51Testing软件测试网Y$kjRc.li%j_
Unknown OLE server: `AutoItX3.Control' (WI2OLERuntimeError)
V$k;@{5U4Bq+HN!r"?051Testing软件测试网5gh6HCXp.oOKe3Wz
that might mean you have not resisted the AutoItX3.dll in your computer,
3T?1c"XwOw.rIY N0in current Watir version, AutoItX3.dll has been included in the watir folder,
t:@ ]"@+tA\"n'}0so Run the command in "Run":
NfD4[3[%`_[051Testing软件测试网lV"`\0z&G`
regsvr32 "C:\ruby\lib\ruby\gems\1.8\gems\watir-1.6.2\lib\watir\AutoItX3.dll"51Testing软件测试网]?%F5c!{E7hc ]2A
then you will not get the errors :)
D0X TvwX{(iF oq0
X@ H&rX0learn AutoItX3, please go to http://www.autoitscript.com/autoit3/index.shtml
*EI^$N5Q0I just want to use it to handle the popup windows when writing Watir scripts51Testing软件测试网+V2xX6Ii"N2A%I@

51Testing软件测试网(h0dc6j? Uq+V A N Y6Ld

 51Testing软件测试网;w'k wC KWM


TAG:

 

评分:0

我来说两句

Open Toolbar