super-test 1.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGE.txt +9 -0
- data/README.txt +13 -0
- data/bin/idb +19 -0
- data/bin/ii +113 -0
- data/bin/istart_mock +36 -0
- data/bin/istop_mock +16 -0
- data/bin/kk +181 -0
- data/bin/rubyatp +42 -0
- data/bin/start_mock +36 -0
- data/bin/stop_mock +16 -0
- data/bin/xgo +45 -0
- data/conf/conf.rb +11 -0
- data/conf/db03.yml +31 -0
- data/conf/db13.yml +37 -0
- data/conf/db19.yml +33 -0
- data/conf/online.yml +32 -0
- data/conf/super_test.yml +40 -0
- data/conf/system.yml +26 -0
- data/conf/sz00.yml +31 -0
- data/conf/sz06.yml +34 -0
- data/conf/wise00.yml +11 -0
- data/data/case.house +0 -0
- data/data/char.house +0 -0
- data/data/images/Bluehills.jpg +0 -0
- data/data/images/Sunset.jpg +0 -0
- data/data/images/Waterlilies.jpg +0 -0
- data/data/images/Winter.jpg +0 -0
- data/data/query.house +18595 -0
- data/data/user.house +8 -0
- data/lib/action/module/check_action.rb +58 -0
- data/lib/action/module/cnnt_action.rb +161 -0
- data/lib/action/module/datacenter_action.rb +48 -0
- data/lib/action/module/http_pack_helper.rb +163 -0
- data/lib/action/module/httpserver_action.rb +297 -0
- data/lib/action/module/inc.rb +21 -0
- data/lib/action/module/mcpack_action.rb +57 -0
- data/lib/action/module/sql_action.rb +84 -0
- data/lib/action/module/ssh_action.rb +37 -0
- data/lib/action/system/user_action.rb +180 -0
- data/lib/common/appium_helper.rb +217 -0
- data/lib/common/atp_helper.rb +74 -0
- data/lib/common/atp_report.rb +344 -0
- data/lib/common/data_house.rb +405 -0
- data/lib/common/data_model.rb +87 -0
- data/lib/common/http/assert_helper.rb +343 -0
- data/lib/common/http/fix_hpricot.rb +118 -0
- data/lib/common/http/html_helper.rb +362 -0
- data/lib/common/http/http_helper.rb +469 -0
- data/lib/common/http/multipart.rb +81 -0
- data/lib/common/isandbox_helper.rb +195 -0
- data/lib/common/json_helper.rb +43 -0
- data/lib/common/mock_helper.rb +168 -0
- data/lib/common/mtop_helper.rb +141 -0
- data/lib/common/myconf_helper.rb +49 -0
- data/lib/common/mylog_helper.rb +77 -0
- data/lib/common/pairwise.rb +121 -0
- data/lib/common/query_house.rb +89 -0
- data/lib/common/report_helper.rb +97 -0
- data/lib/common/robot_helper.rb +85 -0
- data/lib/common/socket/check.rb +325 -0
- data/lib/common/socket/conf_modifier.rb +149 -0
- data/lib/common/socket/context.rb +55 -0
- data/lib/common/socket/data.rb +392 -0
- data/lib/common/socket/data_helper.rb +41 -0
- data/lib/common/socket/env.rb +317 -0
- data/lib/common/socket/inc.rb +24 -0
- data/lib/common/socket/log.rb +213 -0
- data/lib/common/socket/log4s.rb +58 -0
- data/lib/common/socket/log_helper.rb +332 -0
- data/lib/common/socket/my_sql.rb +77 -0
- data/lib/common/socket/net.rb +74 -0
- data/lib/common/socket/network.rb +115 -0
- data/lib/common/socket/rlib/conf_modifier.rb +130 -0
- data/lib/common/socket/rlib/data_helper.rb +33 -0
- data/lib/common/socket/rlib/log_helper.rb +303 -0
- data/lib/common/socket/rlib/process_helper.rb +91 -0
- data/lib/common/socket/stub.rb +276 -0
- data/lib/common/socket/util.rb +266 -0
- data/lib/patterns/inc.rb +10 -0
- data/lib/patterns/mc_base_pattern.rb +474 -0
- data/lib/patterns/some_pattern.rb +145 -0
- data/lib/super_test.rb +114 -0
- data/log/super_test.log +0 -0
- data/log/super_test.log.wf +0 -0
- data/test/cover_me.rb +6 -0
- data/tool/jenny +0 -0
- data/tool/mcsend/mcsend2 +0 -0
- data/tool/mcsend/mcsend2_shead +0 -0
- data/tool/mcserver/conf/mcserver.conf +77 -0
- data/tool/mcserver/conf/mcserverauthip +17 -0
- data/tool/mcserver/mcserver +0 -0
- data/tool/mcserver/mcserver_trans +0 -0
- data/tool/mysql +0 -0
- data/tool/net/mcsend/mcsend +0 -0
- data/tool/net/mcsend/mcsend_trans +0 -0
- data/tool/net/mcsend/nshead.data +7 -0
- data/tool/net/mcsend/res_nshead.data +7 -0
- data/tool/net/my_client/my_client +0 -0
- data/tool/net/tsclient/client.tcl +205 -0
- data/tool/others/kk +190 -0
- data/tool/others/rubyatp +42 -0
- data/tool/others/supertest_install.sh +34 -0
- data/tool/trip/idb +0 -0
- data/tool/ts-agent/nshead.bft +12 -0
- data/tool/ts-agent/server.conf +10 -0
- data/tool/ts-agent/server.tcl +376 -0
- metadata +275 -0
@@ -0,0 +1,87 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
#
|
4
|
+
# Author:: hanyu
|
5
|
+
# Date:: 2009.5.7
|
6
|
+
|
7
|
+
if __FILE__ == $0
|
8
|
+
$LIB_ROOT = "#{File.dirname(__FILE__)}/.."
|
9
|
+
$TEST_ROOT = "#{$LIB_ROOT}/.."
|
10
|
+
$: << "#{$LIB_ROOT}"
|
11
|
+
require 'common/log_helper'
|
12
|
+
require 'common/config_helper'
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
# User 表示一个用户
|
17
|
+
# 目前的实现只是一个普通的数据模型,没有行为
|
18
|
+
class User
|
19
|
+
|
20
|
+
attr_accessor :name, :password, :url, :portrait, :sex
|
21
|
+
|
22
|
+
# 创建User
|
23
|
+
# - name 用户名,必填项
|
24
|
+
# - password 密码,选填项,默认值 passme123
|
25
|
+
# - url url前缀名,选填项,默认与name相同
|
26
|
+
# - portrait 头像加密串,选填项,默认为nil
|
27
|
+
# - sex 性别,1男,2女,默认值1
|
28
|
+
#
|
29
|
+
# Example #1:
|
30
|
+
#
|
31
|
+
# user_A = User.new "ruguo"
|
32
|
+
# user_B = User.new "ruguo2","1234"
|
33
|
+
# user_C = User.new "ruguo4","1234","ruguo","fl3k2jr23jr5o2u5o214"
|
34
|
+
def initialize(name, password=ConfigHelper::CONF['default_password'], url=name, portrait=nil, sex=1)
|
35
|
+
# 用户名
|
36
|
+
@name = name
|
37
|
+
# 用户密码
|
38
|
+
@password = password
|
39
|
+
# 空间url
|
40
|
+
@url = url
|
41
|
+
# 头像加密串 uid+uname
|
42
|
+
@portrait = portrait
|
43
|
+
# 性别
|
44
|
+
@sex = sex
|
45
|
+
end
|
46
|
+
|
47
|
+
# 重载之,方便日志打印
|
48
|
+
#
|
49
|
+
# Example #1:
|
50
|
+
#
|
51
|
+
# user = User.new "ruguo","pass","ruguo"
|
52
|
+
# puts user
|
53
|
+
# # => #<User:0x00000000b19220 @name="ruguo", @password="pass", @space_url="ruguo", @portrait=nil>
|
54
|
+
def to_s
|
55
|
+
inspect
|
56
|
+
end
|
57
|
+
|
58
|
+
# 重载==,方便User对象之间的比较
|
59
|
+
#
|
60
|
+
# Example #1:
|
61
|
+
#
|
62
|
+
# a = User.new "ruguo","pass","ruguo"
|
63
|
+
# b = User.new "ruguo","pass33","ruguo33"
|
64
|
+
# c = User.new "ruguo11","pass33","ruguo33"
|
65
|
+
# d = Object.new
|
66
|
+
#
|
67
|
+
# puts a == b #=> true
|
68
|
+
# puts a == c #=> false
|
69
|
+
# puts a == d #=> false
|
70
|
+
def ==(obj)
|
71
|
+
obj.kind_of?(User) and obj.name == @name
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
if __FILE__ == $0
|
77
|
+
u = User.new "ruguo","pass","ruguo"
|
78
|
+
p u
|
79
|
+
puts u
|
80
|
+
b = User.new "ruguo","pass33","ruguo33"
|
81
|
+
c = User.new "ruguo1","pass","ruguo33"
|
82
|
+
d = Object.new
|
83
|
+
puts u == b
|
84
|
+
puts u == c
|
85
|
+
puts u == d
|
86
|
+
end
|
87
|
+
|
@@ -0,0 +1,343 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
#
|
4
|
+
# Author:: hanyu
|
5
|
+
# Date:: 2009.5.7
|
6
|
+
|
7
|
+
if __FILE__ == $0
|
8
|
+
$LIB_ROOT = "#{File.dirname(__FILE__)}/.."
|
9
|
+
$TEST_ROOT = "#{$LIB_ROOT}/.."
|
10
|
+
$: << "#{$LIB_ROOT}"
|
11
|
+
require 'common/log_helper'
|
12
|
+
require 'common/config_helper'
|
13
|
+
require 'common/http_helper'
|
14
|
+
require 'common/html_helper'
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
# case中尽量使用经过封装的assert
|
19
|
+
#
|
20
|
+
# - 扩展assert方法,支持html、json等解析
|
21
|
+
# - 自定义上层可读message
|
22
|
+
# - 打印可读日志
|
23
|
+
module AssertHelper
|
24
|
+
|
25
|
+
# === 功能:
|
26
|
+
# 验证返回码是200
|
27
|
+
#
|
28
|
+
# === 参数解释:
|
29
|
+
# - msg 失败之后的提示文字
|
30
|
+
#
|
31
|
+
# === Example:
|
32
|
+
# Example:
|
33
|
+
# get "hi.baidu.com"
|
34
|
+
# assert_ok
|
35
|
+
def assert_ok(msg=nil)
|
36
|
+
return if @is_press
|
37
|
+
raise "must send http request before assert!" if @response == nil
|
38
|
+
msg = "assert_ok fail!" if msg.nil?
|
39
|
+
assert_equal @response.code, "200", msg
|
40
|
+
$log.debug "assert_ok success!"
|
41
|
+
end
|
42
|
+
|
43
|
+
# === 功能:
|
44
|
+
# 验证HTTP请求的返回码
|
45
|
+
#
|
46
|
+
# === 参数解释:
|
47
|
+
# - code Fixnum,返回码
|
48
|
+
# - msg 失败之后的提示文字
|
49
|
+
#
|
50
|
+
# === Example:
|
51
|
+
# Example:
|
52
|
+
# get "http://www.google.com/not_exist_page"
|
53
|
+
# assert_code 404
|
54
|
+
def assert_code(code, msg=nil)
|
55
|
+
return if @is_press
|
56
|
+
raise "must send http request before assert!" if @response == nil
|
57
|
+
msg = "assert_code fail!" if msg.nil?
|
58
|
+
assert_equal @response.code, code.to_s, msg
|
59
|
+
$log.debug "assert_code code[#{code}] success!"
|
60
|
+
end
|
61
|
+
|
62
|
+
# === 功能:
|
63
|
+
# 验证重定向
|
64
|
+
#
|
65
|
+
# === 参数解释:
|
66
|
+
# - url 要跳转的url
|
67
|
+
# - msg 失败之后的提示文字
|
68
|
+
#
|
69
|
+
# === Example:
|
70
|
+
# Example:
|
71
|
+
# get "http://hi.baidu.com/sys/not_exist_page"
|
72
|
+
# assert_redirected_to "error.html"
|
73
|
+
def assert_redirected_to(url, msg=nil)
|
74
|
+
return if @is_press
|
75
|
+
raise "must send http request before assert!" if @response == nil
|
76
|
+
msg = "assert_redirected_to fail!" if msg.nil?
|
77
|
+
assert_equal @response.code, "302", msg
|
78
|
+
assert @response.header.key?("Location"), msg
|
79
|
+
assert_equal @response.header["Location"], url, msg
|
80
|
+
$log.debug "assert_redirected_to url[#{url}] success!"
|
81
|
+
end
|
82
|
+
|
83
|
+
# === 功能:
|
84
|
+
# grep方式匹配
|
85
|
+
#
|
86
|
+
# === 参数解释:
|
87
|
+
# - regexp 正则表达式
|
88
|
+
# - msg 失败之后的提示文字
|
89
|
+
#
|
90
|
+
# === Example:
|
91
|
+
# get "http://hi.baidu.com/"
|
92
|
+
# assert_grep /百度空间/
|
93
|
+
#
|
94
|
+
def assert_grep(regexp, msg=nil)
|
95
|
+
return if @is_press
|
96
|
+
raise "must send http request before assert!" if @response == nil
|
97
|
+
msg = "assert_grep fail!" if msg.nil?
|
98
|
+
assert_match regexp, @response.body, msg
|
99
|
+
$log.debug "assert_grep regexp[#{regexp}] success!"
|
100
|
+
end
|
101
|
+
|
102
|
+
# === 功能:
|
103
|
+
# 见 assert_grep
|
104
|
+
def assert_no_grep(regexp,msg=nil)
|
105
|
+
return if @is_press
|
106
|
+
raise "must send http request before assert!" if @response == nil
|
107
|
+
msg = "assert_no_grep fail!" if msg.nil?
|
108
|
+
exp = /#{Regexp.escape(regexp)}/ if String === regexp
|
109
|
+
assert_no_match exp, @response.body, msg
|
110
|
+
$log.debug "assert_no_grep regexp[#{regexp}] success!"
|
111
|
+
end
|
112
|
+
|
113
|
+
# === 功能:
|
114
|
+
# 断言包含某字符串
|
115
|
+
#
|
116
|
+
# === 参数解释:
|
117
|
+
# - str 字符串,不能是正则表达式
|
118
|
+
# - msg 失败之后的提示文字
|
119
|
+
#
|
120
|
+
# === Example:
|
121
|
+
# get "http://hi.baidu.com/"
|
122
|
+
# assert_has "百度空间", "something wrong!"
|
123
|
+
def assert_has(str,msg=nil)
|
124
|
+
return if @is_press
|
125
|
+
assert find_has?(str), msg
|
126
|
+
$log.debug "assert_has str[#{str}] success!"
|
127
|
+
end
|
128
|
+
# === 功能:
|
129
|
+
# 与assert_has相反
|
130
|
+
def assert_has_not(str,msg=nil)
|
131
|
+
return if @is_press
|
132
|
+
assert !find_has?(str), msg
|
133
|
+
$log.debug "assert_has_not str[#{str}] success!"
|
134
|
+
end
|
135
|
+
|
136
|
+
# === 功能:
|
137
|
+
# 断言元素存在
|
138
|
+
#
|
139
|
+
# === 参数解释:
|
140
|
+
# - xpath 定位,可以使xpath or selector
|
141
|
+
# - msg 失败之后的提示文字
|
142
|
+
#
|
143
|
+
def assert_exist(xpath, msg=nil, &blk)
|
144
|
+
return if @is_press
|
145
|
+
msg = "assert_exist xpath[#{xpath}] fail!" if msg.nil?
|
146
|
+
assert find_exist?(xpath,&blk), msg
|
147
|
+
$log.debug "assert_exist xpath[#{xpath}] success!"
|
148
|
+
end
|
149
|
+
|
150
|
+
# === 功能:
|
151
|
+
# 断言元素不存在
|
152
|
+
#
|
153
|
+
# === 参数解释:
|
154
|
+
# - xpath 定位,可以使xpath or selector
|
155
|
+
# - msg 失败之后的提示文字
|
156
|
+
#
|
157
|
+
def assert_no_exist(xpath, msg=nil, &blk)
|
158
|
+
return if @is_press
|
159
|
+
msg = "assert_no_exist xpath[#{xpath}]" if msg.nil?
|
160
|
+
assert_false find_exist?(xpath,&blk), msg
|
161
|
+
$log.debug "assert_no_exist xpath[#{xpath}] success!"
|
162
|
+
end
|
163
|
+
|
164
|
+
# === 功能:
|
165
|
+
# 验证某元素内text的内容
|
166
|
+
#
|
167
|
+
# === 参数解释:
|
168
|
+
# - xpath 定位,可以使xpath or selector
|
169
|
+
# - regexp 期待的结果,可以是正则表达式
|
170
|
+
# - msg 失败之后的提示文字
|
171
|
+
#
|
172
|
+
# === Example:
|
173
|
+
# Example #1:
|
174
|
+
# get "http://hi.baidu.com/"
|
175
|
+
# assert_text "#m_space", "更多精彩空间"
|
176
|
+
#
|
177
|
+
def assert_text(xpath, regexp, msg=nil, &blk)
|
178
|
+
return if @is_press
|
179
|
+
raise "must send http request before assert!" if @response == nil
|
180
|
+
expect = find_text xpath, &blk
|
181
|
+
msg = "assert_text xpath[#{xpath}] regexp[#{regexp}] fail!" if msg.nil?
|
182
|
+
assert_match regexp, expect, msg
|
183
|
+
$log.debug "assert_text xpath[#{xpath}] regexp[#{regexp}] success!"
|
184
|
+
end
|
185
|
+
|
186
|
+
# === 功能:
|
187
|
+
# 见 assert_text
|
188
|
+
def assert_no_text(xpath, regexp, msg=nil, &blk)
|
189
|
+
return if @is_press
|
190
|
+
raise "must send http request before assert!" if @response == nil
|
191
|
+
expect = find_text xpath, &blk
|
192
|
+
exp = /#{Regexp.escape(regexp)}/ if String === regexp
|
193
|
+
msg = "assert_no_text xpath[#{xpath}] regexp[#{regexp}] fail!" if msg.nil?
|
194
|
+
assert_no_match exp, expect, msg
|
195
|
+
$log.debug "assert_no_text xpath[#{xpath}] regexp[#{regexp}] success!"
|
196
|
+
end
|
197
|
+
|
198
|
+
# === 功能:
|
199
|
+
# 验证某元素的html片段的内容
|
200
|
+
#
|
201
|
+
# === 参数解释:
|
202
|
+
# - xpath 定位,可以使xpath or selector
|
203
|
+
# - regexp 期待的结果,可以是正则表达式
|
204
|
+
# - msg 失败之后的提示文字
|
205
|
+
#
|
206
|
+
# === Example:
|
207
|
+
# Example #1:
|
208
|
+
# get "http://hi.baidu.com/"
|
209
|
+
# assert_html "#m_space", "更多精彩空间"
|
210
|
+
#
|
211
|
+
# Example #2:
|
212
|
+
# get "http://hi.baidu.com/"
|
213
|
+
# assert_html "//div[@id='m_space']", "更多精彩空间"
|
214
|
+
def assert_html(xpath, regexp, msg=nil, &blk)
|
215
|
+
return if @is_press
|
216
|
+
raise "must send http request before assert!" if @response == nil
|
217
|
+
expect = find_html xpath, &blk
|
218
|
+
msg = "assert_html xpath[#{xpath}] regexp[#{regexp}] fail!" if msg.nil?
|
219
|
+
assert_match regexp, expect, "assert_html xpath[#{xpath}] regexp[#{regexp}] fail!"
|
220
|
+
$log.debug "assert_html xpath[#{xpath}] regexp[#{regexp}] success!"
|
221
|
+
end
|
222
|
+
|
223
|
+
# === 功能:
|
224
|
+
# 见 assert_html
|
225
|
+
def assert_no_html(xpath, regexp, msg=nil, &blk)
|
226
|
+
return if @is_press
|
227
|
+
raise "must send http request before assert!" if @response == nil
|
228
|
+
expect = find_html xpath, &blk
|
229
|
+
exp = /#{Regexp.escape(regexp)}/ if String === regexp
|
230
|
+
msg = "assert_no_html xpath[#{xpath}] regexp[#{regexp}] fail!" if msg.nil?
|
231
|
+
assert_no_match exp, expect, msg
|
232
|
+
$log.debug "assert_no_html xpath[#{xpath}] regexp[#{regexp}] success!"
|
233
|
+
end
|
234
|
+
|
235
|
+
# === 功能:
|
236
|
+
# 验证某Element的属性值
|
237
|
+
#
|
238
|
+
# === 参数解释:
|
239
|
+
# - xpath 定位,可以使xpath or selector
|
240
|
+
# - attr 属性名
|
241
|
+
# - regexp 期待的结果,可以是正则表达式
|
242
|
+
# - msg 失败之后的提示文字
|
243
|
+
#
|
244
|
+
# === Example:
|
245
|
+
# Example:
|
246
|
+
# get "http://hi.baidu.com/"
|
247
|
+
# assert_attr "div#m_space div.t1 a.grnlk", "href" "http://hi.baidu.com/hi/more/wonderful/"
|
248
|
+
# # html代码片段
|
249
|
+
# # <div id="m_space">
|
250
|
+
# # <div class="t1">
|
251
|
+
# # <a href="http://hi.baidu.com/hi/more/wonderful/" target="_blank" class="grnlk"><img src="http://img.baidu.com/hi/img/index/i1.gif" border="0" align="top"> 空间中的海外华人 </a>
|
252
|
+
# # ...
|
253
|
+
def assert_attr(xpath, attr, regexp, msg=nil, &blk)
|
254
|
+
return if @is_press
|
255
|
+
raise "must send http request before assert!" if @response == nil
|
256
|
+
expect = find_attr xpath, attr, &blk
|
257
|
+
msg = "assert_attr xpath[#{xpath}] attr[#{attr}] regexp[#{regexp}] fail!" if msg.nil?
|
258
|
+
assert_match regexp, expect, msg
|
259
|
+
$log.debug "assert_attr xpath[#{xpath}] attr[#{attr}] regexp[#{regexp}] success!"
|
260
|
+
end
|
261
|
+
|
262
|
+
# === 功能:
|
263
|
+
# 见 assert_attr
|
264
|
+
def assert_no_attr(xpath, attr, regexp, msg=nil, &blk)
|
265
|
+
return if @is_press
|
266
|
+
raise "must send http request before assert!" if @response == nil
|
267
|
+
expect = find_attr xpath, attr, &blk
|
268
|
+
exp = /#{Regexp.escape(regexp)}/ if String === regexp
|
269
|
+
msg = "assert_no_attr xpath[#{xpath}] attr[#{attr}] regexp[#{regexp}] fail!" if msg.nil?
|
270
|
+
assert_no_match exp, expect, msg
|
271
|
+
$log.debug "assert_no_attr xpath[#{xpath}] attr[#{attr}] regexp[#{regexp}] success!"
|
272
|
+
end
|
273
|
+
|
274
|
+
# === 功能:
|
275
|
+
# 验证匹配的个数,如当前页某栏目的内容数
|
276
|
+
#
|
277
|
+
# === 参数解释:
|
278
|
+
# - xpath 定位,可以使xpath or selector
|
279
|
+
# - size 期待的结果,Fixnum
|
280
|
+
# - msg 失败之后的提示文字
|
281
|
+
#
|
282
|
+
# === Example:
|
283
|
+
# Example:
|
284
|
+
# get "http://hi.baidu.com/"
|
285
|
+
# assert_size "div#m_space ul li", 12
|
286
|
+
# # 百度空间首页,精彩空间栏会出12个推荐空间
|
287
|
+
def assert_size(xpath, size, msg=nil, &blk)
|
288
|
+
return if @is_press
|
289
|
+
raise "must send http request before assert!" if @response == nil
|
290
|
+
expect = find_size xpath, &blk
|
291
|
+
msg = "assert_size xpath[#{xpath}] size[#{size}] expect[#{expect}] fail!" if msg.nil?
|
292
|
+
assert expect == size, msg
|
293
|
+
$log.debug "assert_size xpath[#{xpath}] size[#{size}] expect[#{expect}] success!"
|
294
|
+
end
|
295
|
+
|
296
|
+
# === 功能:
|
297
|
+
# 验证某元素不含有非预计的儿子节点
|
298
|
+
#
|
299
|
+
# === 参数解释:
|
300
|
+
# - xpath 父亲节点的定位,可以使xpath or selector
|
301
|
+
# - children 预计的儿子节点名字的集合,如%w{title author body}
|
302
|
+
# - msg 失败之后的提示文字
|
303
|
+
#
|
304
|
+
# === Example:
|
305
|
+
# Example:
|
306
|
+
# get "http://hi.baidu.com/"
|
307
|
+
# assert_children "head", %w{title script link meta}
|
308
|
+
# #=> assert_children xpath[head] has children[["title", "script", "link", "meta"]], AND has other children[["style"]]!.
|
309
|
+
#
|
310
|
+
def assert_children(xpath, children, msg=nil, &blk)
|
311
|
+
return if @is_press
|
312
|
+
raise "must send http request before assert!" if @response == nil
|
313
|
+
expect = find_children xpath,children, &blk
|
314
|
+
|
315
|
+
msg = "assert_children xpath[#{xpath}] has children[#{children}], AND has other children[#{expect}]!" if msg.nil?
|
316
|
+
assert expect.empty?, msg
|
317
|
+
$log.debug "assert_children xpath[#{xpath}] children[#{children}] success!"
|
318
|
+
end
|
319
|
+
|
320
|
+
end
|
321
|
+
|
322
|
+
|
323
|
+
if __FILE__ == $0
|
324
|
+
class MyTest
|
325
|
+
include AssertHelper
|
326
|
+
include HttpHelper
|
327
|
+
|
328
|
+
def initialize
|
329
|
+
@cookies = {}
|
330
|
+
end
|
331
|
+
|
332
|
+
def test
|
333
|
+
get "http://www.baidu.com/"
|
334
|
+
doc = Hpricot(@response.body)
|
335
|
+
s = doc.search("div#u")
|
336
|
+
p s
|
337
|
+
puts s.html
|
338
|
+
puts s.attr("id")
|
339
|
+
end
|
340
|
+
end
|
341
|
+
Test.new.test
|
342
|
+
end
|
343
|
+
|
@@ -0,0 +1,118 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
#
|
4
|
+
# Author:: hanyu
|
5
|
+
# Date:: 2009.9.6
|
6
|
+
|
7
|
+
|
8
|
+
# hack Hpricot
|
9
|
+
# 因为 Hpricot 将实体字符进行了反转义,这个过程存在很多的编码问题,解决起来不太容易,
|
10
|
+
# 而且这种反转义可能并不是我们需要的,所以去掉了
|
11
|
+
module Hpricot # :nodoc:
|
12
|
+
def self.uxs(str)
|
13
|
+
str.to_s.force_encoding("gbk")
|
14
|
+
#gsub(/\&(\w+);/){ [NamedCharacters[$1] || ??].pack("U*") }
|
15
|
+
#gsub(/\&\#(\d+);/){ [$1.to_i].pack("U*").encode("gbk") }.force_encoding("gbk")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
# 基于hpricot (0.8.2)修改,如果版本发生变化,可能会有问题
|
21
|
+
|
22
|
+
|
23
|
+
# 尝试fix Hpricot在解析xpath的时候 对带冒号的字符串匹配有问题
|
24
|
+
# 可能会存在引入新bug的风险,对Hpricot的解析方式没有完全搞懂
|
25
|
+
module Hpricot
|
26
|
+
module Traverse
|
27
|
+
def search(expr, &blk)
|
28
|
+
if Range === expr
|
29
|
+
return Elements.expand(at(expr.begin), at(expr.end), expr.exclude_end?)
|
30
|
+
end
|
31
|
+
last = nil
|
32
|
+
nodes = [self]
|
33
|
+
done = []
|
34
|
+
expr = expr.to_s
|
35
|
+
hist = []
|
36
|
+
until expr.empty?
|
37
|
+
expr = clean_path(expr)
|
38
|
+
expr.gsub!(%r!^//!, '')
|
39
|
+
|
40
|
+
case expr
|
41
|
+
when %r!^/?\.\.!
|
42
|
+
last = expr = $'
|
43
|
+
nodes.map! { |node| node.parent }
|
44
|
+
when %r!^[>/]\s*!
|
45
|
+
last = expr = $'
|
46
|
+
nodes = Elements[*nodes.map { |node| node.children if node.respond_to? :children }.flatten.compact]
|
47
|
+
when %r!^\+!
|
48
|
+
last = expr = $'
|
49
|
+
nodes.map! do |node|
|
50
|
+
siblings = node.parent.children
|
51
|
+
siblings[siblings.index(node)+1]
|
52
|
+
end
|
53
|
+
nodes.compact!
|
54
|
+
when %r!^~!
|
55
|
+
last = expr = $'
|
56
|
+
nodes.map! do |node|
|
57
|
+
siblings = node.parent.children
|
58
|
+
siblings[(siblings.index(node)+1)..-1]
|
59
|
+
end
|
60
|
+
nodes.flatten!
|
61
|
+
when %r!^[|,]!
|
62
|
+
last = expr = " #$'"
|
63
|
+
nodes.shift if nodes.first == self
|
64
|
+
done += nodes
|
65
|
+
nodes = [self]
|
66
|
+
else
|
67
|
+
#puts "++++++++++++++++"
|
68
|
+
#p expr
|
69
|
+
m = expr.match(%r!^([#.]?)([a-z0-9\\*_-]*)!i).to_a
|
70
|
+
#p m
|
71
|
+
after = $'
|
72
|
+
#p after
|
73
|
+
#mt = after[%r!:[a-z0-9\\*_-]+!i, 0]
|
74
|
+
mt = after[%r!^:[a-z0-9\\*_-]+!i, 0]
|
75
|
+
#p mt
|
76
|
+
oop = false
|
77
|
+
if mt and not (mt == ":not" or Traverse.method_defined? "filter[#{mt}]")
|
78
|
+
after = $'
|
79
|
+
m[2] += mt
|
80
|
+
expr = after
|
81
|
+
end
|
82
|
+
if m[1] == '#'
|
83
|
+
oid = get_element_by_id(m[2])
|
84
|
+
nodes = oid ? [oid] : []
|
85
|
+
expr = after
|
86
|
+
else
|
87
|
+
m[2] = "*" if after =~ /^\(\)/ || m[2] == "" || m[1] == "."
|
88
|
+
ret = []
|
89
|
+
nodes.each do |node|
|
90
|
+
case m[2]
|
91
|
+
when '*'
|
92
|
+
node.traverse_element { |n| ret << n }
|
93
|
+
else
|
94
|
+
if node.respond_to? :get_elements_by_tag_name
|
95
|
+
ret += [*node.get_elements_by_tag_name(m[2])] - [*(node unless last)]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
nodes = ret
|
100
|
+
end
|
101
|
+
last = nil
|
102
|
+
end
|
103
|
+
|
104
|
+
hist << expr
|
105
|
+
break if hist[-1] == hist[-2]
|
106
|
+
nodes, expr = Elements.filter(nodes, expr)
|
107
|
+
end
|
108
|
+
nodes = done + nodes.flatten.uniq
|
109
|
+
if blk
|
110
|
+
nodes.each(&blk)
|
111
|
+
self
|
112
|
+
else
|
113
|
+
Elements[*nodes]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|