mechanize 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of mechanize might be problematic. Click here for more details.
- data/CHANGELOG +18 -0
- data/EXAMPLES +4 -4
- data/NOTES +32 -0
- data/lib/mechanize.rb +27 -17
- data/lib/mechanize/form.rb +2 -6
- data/lib/mechanize/form_elements.rb +31 -10
- data/lib/mechanize/inspect.rb +95 -0
- data/lib/mechanize/list.rb +11 -1
- data/lib/mechanize/mech_version.rb +1 -1
- data/lib/mechanize/page.rb +0 -4
- data/lib/mechanize/page_elements.rb +0 -4
- data/test/htdocs/tc_bad_links.html +5 -0
- data/test/htdocs/tc_checkboxes.html +19 -0
- data/test/htdocs/tc_pretty_print.html +17 -0
- data/test/htdocs/tc_radiobuttons.html +17 -0
- data/test/htdocs/tc_textarea.html +23 -0
- data/test/tc_authenticate.rb +1 -1
- data/test/tc_bad_links.rb +32 -0
- data/test/tc_checkboxes.rb +69 -0
- data/test/tc_cookies.rb +1 -1
- data/test/tc_errors.rb +1 -1
- data/test/tc_forms.rb +1 -1
- data/test/tc_frames.rb +1 -1
- data/test/tc_links.rb +12 -1
- data/test/tc_mech.rb +1 -1
- data/test/tc_multi_select.rb +1 -1
- data/test/tc_page.rb +1 -1
- data/test/tc_pluggable_parser.rb +1 -1
- data/test/tc_post_form.rb +1 -1
- data/test/tc_pretty_print.rb +29 -0
- data/test/tc_radiobutton.rb +77 -0
- data/test/tc_response_code.rb +2 -2
- data/test/tc_save_file.rb +1 -1
- data/test/tc_select.rb +1 -1
- data/test/tc_textarea.rb +52 -0
- data/test/tc_upload.rb +1 -1
- data/test/ts_mech.rb +5 -0
- metadata +13 -2
data/CHANGELOG
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
= Mechanize CHANGELOG
|
2
2
|
|
3
|
+
== 0.5.3
|
4
|
+
|
5
|
+
* Mechanize#click will now act on the first element of an array. So if an
|
6
|
+
array of links is passed to WWW::Mechanize#click, the first link is clicked.
|
7
|
+
That means the syntax for clicking links is shortened and still supports
|
8
|
+
selecting a link. The following are equivalent:
|
9
|
+
agent.click page.links.first
|
10
|
+
agent.click page.links
|
11
|
+
* Fixed a bug with spaces in href's and get's
|
12
|
+
* Added a tick, untick, and click method to radio buttons so that
|
13
|
+
radiobuttons can be "clicked"
|
14
|
+
* Added a tick, untick, and click method to check boxes so that
|
15
|
+
checkboxes can be "clicked"
|
16
|
+
* Options on Select lists can now be "tick"ed, and "untick"ed.
|
17
|
+
* Fixed a potential bug conflicting with rails. Thanks Eric Kolve
|
18
|
+
* Updated log4r support for a speed increase. Thanks Yinon Bentor
|
19
|
+
* Added inspect methods and pretty printing
|
20
|
+
|
3
21
|
== 0.5.2
|
4
22
|
|
5
23
|
* Fixed a bug with input names that are nil
|
data/EXAMPLES
CHANGED
@@ -17,7 +17,7 @@
|
|
17
17
|
|
18
18
|
agent = WWW::Mechanize.new
|
19
19
|
page = agent.get('http://rubyforge.org/')
|
20
|
-
link = page.links.text(/Log In/)
|
20
|
+
link = page.links.text(/Log In/)
|
21
21
|
page = agent.click(link)
|
22
22
|
form = page.forms[1]
|
23
23
|
form.form_loginname = ARGV[0]
|
@@ -38,10 +38,10 @@ This example uploads one image as two different images to flickr.
|
|
38
38
|
form.email = ARGV[0]
|
39
39
|
form.password = ARGV[1]
|
40
40
|
page = agent.submit(form)
|
41
|
-
page = agent.click page.links.text('Upload')
|
41
|
+
page = agent.click page.links.text('Upload')
|
42
42
|
form = page.forms.first
|
43
|
-
img1 = form.file_uploads.name('file1')
|
44
|
-
img2 = form.file_uploads.name('file2')
|
43
|
+
img1 = form.file_uploads.name('file1')
|
44
|
+
img2 = form.file_uploads.name('file2')
|
45
45
|
|
46
46
|
img1.file_name = img2.file_name = ARGV[2]
|
47
47
|
File.open(ARGV[2], "r") { |f|
|
data/NOTES
CHANGED
@@ -1,5 +1,37 @@
|
|
1
1
|
= Mechanize Release Notes
|
2
2
|
|
3
|
+
== 0.5.3 (Twan)
|
4
|
+
|
5
|
+
Here it is. Mechanize 0.5.3 also named the "Twan" release. There are a few
|
6
|
+
new features, a few fixed bugs, and some other stuff too!
|
7
|
+
|
8
|
+
First, new features. WWW::Mechanize#click has been updated to operate on the
|
9
|
+
first link if an array is passed in. How is this helpful? It allows
|
10
|
+
syntax like this:
|
11
|
+
agent.click page.links.first
|
12
|
+
to be like this:
|
13
|
+
agent.click page.links
|
14
|
+
This trick was actually implemented in WWW::Mechanize::List. If you send a
|
15
|
+
method to WWW::Mechanize::List, and it doesn't know how to respond, it will
|
16
|
+
try calling that method on the first element of the list. But it only does
|
17
|
+
that for methods with no arguments.
|
18
|
+
|
19
|
+
Radio buttons, check boxes, and select lists can now be ticked, unticked, and
|
20
|
+
clicked. Now to select the second radio button from a list, you can do this:
|
21
|
+
form.radiobuttons.name('color')[1].click
|
22
|
+
Mechanize will handle unchecking all of the other radio buttons with the same
|
23
|
+
name.
|
24
|
+
|
25
|
+
Pretty printing has been added so that inspecting mechanize objects is very
|
26
|
+
pretty. Go ahead and try it out!
|
27
|
+
pp page
|
28
|
+
Or even
|
29
|
+
pp page.forms.first
|
30
|
+
|
31
|
+
Now, bugfixes. A bug was fixed when spaces are passed in as part of the URL
|
32
|
+
to WWW::Mechanize#get. Thanks to Eric Kolve, a bug was fixed with methods
|
33
|
+
that conflict with rails. Thanks to Yinon Bentor for sending in a patch to
|
34
|
+
improve Log4r support and a slight speed increase.
|
3
35
|
== 0.5.2
|
4
36
|
|
5
37
|
This release comes with a few cool new features. First, support for select
|
data/lib/mechanize.rb
CHANGED
@@ -29,6 +29,7 @@ require 'mechanize/list'
|
|
29
29
|
require 'mechanize/page'
|
30
30
|
require 'mechanize/page_elements'
|
31
31
|
require 'mechanize/parsing'
|
32
|
+
require 'mechanize/inspect'
|
32
33
|
|
33
34
|
module WWW
|
34
35
|
|
@@ -78,7 +79,7 @@ class Mechanize
|
|
78
79
|
def initialize
|
79
80
|
# attr_accessors
|
80
81
|
@cookie_jar = CookieJar.new
|
81
|
-
@log
|
82
|
+
@log = nil
|
82
83
|
@max_history = nil
|
83
84
|
@open_timeout = nil
|
84
85
|
@read_timeout = nil
|
@@ -224,13 +225,13 @@ class Mechanize
|
|
224
225
|
if url.is_a?(URI)
|
225
226
|
uri = url
|
226
227
|
else
|
227
|
-
uri = URI.parse(url.gsub(/\s/, '%20'))
|
228
|
+
uri = URI.parse(url.strip.gsub(/\s/, '%20'))
|
228
229
|
end
|
229
230
|
|
230
231
|
# construct an absolute uri
|
231
232
|
if uri.relative?
|
232
233
|
if cur_page.uri
|
233
|
-
uri = cur_page.uri + (url.is_a?(URI) ? url : URI::escape(url))
|
234
|
+
uri = cur_page.uri + (url.is_a?(URI) ? url : URI::escape(url.strip))
|
234
235
|
else
|
235
236
|
raise 'no history. please specify an absolute URL'
|
236
237
|
end
|
@@ -246,7 +247,7 @@ class Mechanize
|
|
246
247
|
|
247
248
|
# this is called before the request is sent
|
248
249
|
pre_request_hook = proc {|request|
|
249
|
-
log.debug("query: #{ request_data.inspect }")
|
250
|
+
log.debug("query: #{ request_data.inspect }") if log
|
250
251
|
request.add_field('Content-Type', form.enctype)
|
251
252
|
request.add_field('Content-Length', request_data[0].size.to_s)
|
252
253
|
}
|
@@ -261,7 +262,7 @@ class Mechanize
|
|
261
262
|
def fetch_page(uri, method=:get, cur_page=current_page(), pre_request_hook=nil, request_data=[])
|
262
263
|
raise "unsupported scheme" unless ['http', 'https'].include?(uri.scheme)
|
263
264
|
|
264
|
-
log.info("#{ method.to_s.upcase }: #{ uri.to_s }")
|
265
|
+
log.info("#{ method.to_s.upcase }: #{ uri.to_s }") if log
|
265
266
|
|
266
267
|
page = Page.new(uri)
|
267
268
|
|
@@ -301,7 +302,11 @@ class Mechanize
|
|
301
302
|
unless @cookie_jar.empty?(uri)
|
302
303
|
cookies = @cookie_jar.cookies(uri)
|
303
304
|
cookie = cookies.length > 0 ? cookies.join("; ") : nil
|
304
|
-
log
|
305
|
+
if log
|
306
|
+
cookies.each do |c|
|
307
|
+
log.debug("using cookie: #{c}")
|
308
|
+
end
|
309
|
+
end
|
305
310
|
request.add_field('Cookie', cookie)
|
306
311
|
end
|
307
312
|
|
@@ -322,9 +327,10 @@ class Mechanize
|
|
322
327
|
pre_request_hook.call(request) if pre_request_hook
|
323
328
|
|
324
329
|
# Log specified headers for the request
|
325
|
-
|
326
|
-
|
327
|
-
|
330
|
+
if log
|
331
|
+
request.each_header do |k, v|
|
332
|
+
log.debug("request-header: #{ k } => #{ v }")
|
333
|
+
end
|
328
334
|
end
|
329
335
|
|
330
336
|
# Specify timeouts if given
|
@@ -336,14 +342,18 @@ class Mechanize
|
|
336
342
|
|
337
343
|
http.request(request, *request_data) {|response|
|
338
344
|
|
339
|
-
|
340
|
-
|
341
|
-
|
345
|
+
if log
|
346
|
+
response.each_header {|k,v|
|
347
|
+
log.debug("response-header: #{ k } => #{ v }")
|
348
|
+
}
|
342
349
|
end
|
343
350
|
|
344
|
-
response.
|
345
|
-
|
346
|
-
|
351
|
+
(response.get_fields('Set-Cookie')||[]).each do |cookie|
|
352
|
+
Cookie::parse(uri, cookie) { |c|
|
353
|
+
log.debug("saved cookie: #{c}") if log
|
354
|
+
@cookie_jar.add(c)
|
355
|
+
}
|
356
|
+
end
|
347
357
|
|
348
358
|
response.read_body
|
349
359
|
|
@@ -362,7 +372,7 @@ class Mechanize
|
|
362
372
|
response.code
|
363
373
|
)
|
364
374
|
|
365
|
-
log.info("status: #{ page.code }")
|
375
|
+
log.info("status: #{ page.code }") if log
|
366
376
|
|
367
377
|
if page.respond_to? :watch_for_set
|
368
378
|
page.watch_for_set = @watch_for_set
|
@@ -372,7 +382,7 @@ class Mechanize
|
|
372
382
|
when "200"
|
373
383
|
return page
|
374
384
|
when "301", "302"
|
375
|
-
log.info("follow redirect to: #{ response['Location'] }")
|
385
|
+
log.info("follow redirect to: #{ response['Location'] }") if log
|
376
386
|
return fetch_page(to_absolute_uri(URI.parse(response['Location'].gsub(/ /, '%20')), page), :get, page)
|
377
387
|
else
|
378
388
|
raise ResponseCodeError.new(page.code), "Unhandled response", caller
|
data/lib/mechanize/form.rb
CHANGED
@@ -123,10 +123,6 @@ module WWW
|
|
123
123
|
query
|
124
124
|
end
|
125
125
|
|
126
|
-
def inspect
|
127
|
-
"Form: ['#{@name}' #{@method} #{@action}]"
|
128
|
-
end
|
129
|
-
|
130
126
|
private
|
131
127
|
def parse
|
132
128
|
@fields = WWW::Mechanize::List.new
|
@@ -147,9 +143,9 @@ module WWW
|
|
147
143
|
when 'text', 'password', 'hidden', 'int'
|
148
144
|
@fields << Field.new(node.attributes['name'], node.attributes['value'] || '')
|
149
145
|
when 'radio'
|
150
|
-
@radiobuttons << RadioButton.new(node.attributes['name'], node.attributes['value'], node.attributes.has_key?('checked'))
|
146
|
+
@radiobuttons << RadioButton.new(node.attributes['name'], node.attributes['value'], node.attributes.has_key?('checked'), self)
|
151
147
|
when 'checkbox'
|
152
|
-
@checkboxes << CheckBox.new(node.attributes['name'], node.attributes['value'], node.attributes.has_key?('checked'))
|
148
|
+
@checkboxes << CheckBox.new(node.attributes['name'], node.attributes['value'], node.attributes.has_key?('checked'), self)
|
153
149
|
when 'file'
|
154
150
|
@file_uploads << FileUpload.new(node.attributes['name'], node.attributes['value'])
|
155
151
|
when 'submit'
|
@@ -13,10 +13,6 @@ module WWW
|
|
13
13
|
@name, @value = name, value
|
14
14
|
end
|
15
15
|
|
16
|
-
def inspect
|
17
|
-
"#{name} = #{@value}"
|
18
|
-
end
|
19
|
-
|
20
16
|
def query_value
|
21
17
|
[[@name, @value || '']]
|
22
18
|
end
|
@@ -69,10 +65,32 @@ module WWW
|
|
69
65
|
class RadioButton < Field
|
70
66
|
attr_accessor :checked
|
71
67
|
|
72
|
-
def initialize(name, value, checked)
|
68
|
+
def initialize(name, value, checked, form)
|
73
69
|
@checked = checked
|
70
|
+
@form = form
|
74
71
|
super(name, value)
|
75
72
|
end
|
73
|
+
|
74
|
+
def tick
|
75
|
+
uncheck_peers
|
76
|
+
@checked = true
|
77
|
+
end
|
78
|
+
|
79
|
+
def untick
|
80
|
+
@checked = false
|
81
|
+
end
|
82
|
+
|
83
|
+
def click
|
84
|
+
@checked = !@checked
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
def uncheck_peers
|
89
|
+
@form.radiobuttons.name(name).each do |b|
|
90
|
+
next if b.value == value
|
91
|
+
b.untick
|
92
|
+
end
|
93
|
+
end
|
76
94
|
end
|
77
95
|
|
78
96
|
# This class represents a check box found in a Form. To activate the
|
@@ -115,13 +133,13 @@ module WWW
|
|
115
133
|
# Select no options
|
116
134
|
def select_none
|
117
135
|
@value = []
|
118
|
-
options.each { |o| o.
|
136
|
+
options.each { |o| o.untick }
|
119
137
|
end
|
120
138
|
|
121
139
|
# Select all options
|
122
140
|
def select_all
|
123
141
|
@value = []
|
124
|
-
options.each { |o| o.
|
142
|
+
options.each { |o| o.tick }
|
125
143
|
end
|
126
144
|
|
127
145
|
# Get a list of all selected options
|
@@ -177,7 +195,7 @@ module WWW
|
|
177
195
|
end
|
178
196
|
|
179
197
|
def value=(new)
|
180
|
-
if new.respond_to? :first
|
198
|
+
if new != new.to_s and new.respond_to? :first
|
181
199
|
super([new.first])
|
182
200
|
else
|
183
201
|
super([new.to_s])
|
@@ -187,9 +205,9 @@ module WWW
|
|
187
205
|
|
188
206
|
# This class contains option an option found within SelectList. A
|
189
207
|
# SelectList can have many Option classes associated with it. An option
|
190
|
-
# can be selected by calling Option#
|
208
|
+
# can be selected by calling Option#tick, or Option#click. For example,
|
191
209
|
# select the first option in a list:
|
192
|
-
# select_list.first.
|
210
|
+
# select_list.first.tick
|
193
211
|
class Option
|
194
212
|
attr_reader :value, :selected, :text, :select_list
|
195
213
|
|
@@ -214,6 +232,9 @@ module WWW
|
|
214
232
|
@selected = false
|
215
233
|
end
|
216
234
|
|
235
|
+
alias :tick :select
|
236
|
+
alias :untick :unselect
|
237
|
+
|
217
238
|
# Toggle the selection value of this option
|
218
239
|
def click
|
219
240
|
unselect_peers
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
module WWW
|
4
|
+
# :stopdoc:
|
5
|
+
class Mechanize
|
6
|
+
def pretty_print(q)
|
7
|
+
q.object_group(self) {
|
8
|
+
q.breakable
|
9
|
+
q.pp cookie_jar
|
10
|
+
q.breakable
|
11
|
+
q.pp current_page
|
12
|
+
}
|
13
|
+
end
|
14
|
+
alias :inspect :pretty_print_inspect
|
15
|
+
|
16
|
+
class Page
|
17
|
+
def pretty_print(q)
|
18
|
+
parse_html
|
19
|
+
q.object_group(self) {
|
20
|
+
q.breakable
|
21
|
+
q.group(1, '{url', '}') {q.breakable; q.pp uri }
|
22
|
+
q.breakable
|
23
|
+
q.group(1, '{meta', '}') {
|
24
|
+
@meta.each { |link| q.breakable; q.pp link }
|
25
|
+
}
|
26
|
+
q.breakable
|
27
|
+
q.group(1, '{title', '}') { q.breakable; q.pp title }
|
28
|
+
q.breakable
|
29
|
+
q.group(1, '{iframes', '}') {
|
30
|
+
@iframes.each { |link| q.breakable; q.pp link }
|
31
|
+
}
|
32
|
+
q.breakable
|
33
|
+
q.group(1, '{frames', '}') {
|
34
|
+
@frames.each { |link| q.breakable; q.pp link }
|
35
|
+
}
|
36
|
+
q.breakable
|
37
|
+
q.group(1, '{links', '}') {
|
38
|
+
@links.each { |link| q.breakable; q.pp link }
|
39
|
+
}
|
40
|
+
q.breakable
|
41
|
+
q.group(1, '{forms', '}') {
|
42
|
+
@forms.each { |form| q.breakable; q.pp form }
|
43
|
+
}
|
44
|
+
}
|
45
|
+
end
|
46
|
+
alias :inspect :pretty_print_inspect
|
47
|
+
end
|
48
|
+
|
49
|
+
class Link
|
50
|
+
def pretty_print(q)
|
51
|
+
q.object_group(self) {
|
52
|
+
q.breakable; q.pp text
|
53
|
+
q.breakable; q.pp href
|
54
|
+
}
|
55
|
+
end
|
56
|
+
alias :inspect :pretty_print_inspect
|
57
|
+
end
|
58
|
+
|
59
|
+
class Form
|
60
|
+
def pretty_print(q)
|
61
|
+
q.object_group(self) {
|
62
|
+
q.breakable; q.group(1, '{name', '}') { q.breakable; q.pp name }
|
63
|
+
q.breakable; q.group(1, '{method', '}') { q.breakable; q.pp method }
|
64
|
+
q.breakable; q.group(1, '{action', '}') { q.breakable; q.pp action }
|
65
|
+
q.breakable; q.group(1, '{fields', '}') {
|
66
|
+
@fields.each do |field|
|
67
|
+
q.breakable
|
68
|
+
q.pp field
|
69
|
+
end
|
70
|
+
}
|
71
|
+
q.breakable; q.group(1, '{radiobuttons', '}') {
|
72
|
+
@radiobuttons.each { |b| q.breakable; q.pp b }
|
73
|
+
}
|
74
|
+
q.breakable; q.group(1, '{checkboxes', '}') {
|
75
|
+
@checkboxes.each { |b| q.breakable; q.pp b }
|
76
|
+
}
|
77
|
+
q.breakable; q.group(1, '{file_uploads', '}') {
|
78
|
+
@file_uploads.each { |b| q.breakable; q.pp b }
|
79
|
+
}
|
80
|
+
q.breakable; q.group(1, '{buttons', '}') {
|
81
|
+
@buttons.each { |b| q.breakable; q.pp b }
|
82
|
+
}
|
83
|
+
}
|
84
|
+
end
|
85
|
+
alias :inspect :pretty_print_inspect
|
86
|
+
end
|
87
|
+
|
88
|
+
class RadioButton
|
89
|
+
def pretty_print_instance_variables
|
90
|
+
[:@checked, :@name, :@value]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
# :startdoc:
|
95
|
+
end
|
data/lib/mechanize/list.rb
CHANGED
@@ -24,6 +24,14 @@ module WWW
|
|
24
24
|
# list.name('foo').href('bar.html')
|
25
25
|
#
|
26
26
|
# This code will find all elements with name 'foo' and href 'bar.html'.
|
27
|
+
# If you call a method with no arguments that List does not know how to
|
28
|
+
# respond to, it will try that method on the first element of the array.
|
29
|
+
# This lets you treat the array like the type of object it contains.
|
30
|
+
# For example, you can click the first element in the array just by
|
31
|
+
# saying:
|
32
|
+
# agent.click page.links
|
33
|
+
# Or click the first link with the text "foo"
|
34
|
+
# agent.click page.links.text('foo')
|
27
35
|
class List < Array
|
28
36
|
# This method provides syntax sugar so that you can write expressions
|
29
37
|
# like this:
|
@@ -45,7 +53,9 @@ module WWW
|
|
45
53
|
|
46
54
|
alias :and :with
|
47
55
|
|
48
|
-
def method_missing(meth_sym,
|
56
|
+
def method_missing(meth_sym, *args)
|
57
|
+
return first.send(meth_sym) if args.empty?
|
58
|
+
arg = args.first
|
49
59
|
if arg.class == Regexp
|
50
60
|
WWW::Mechanize::List.new(find_all { |e| e.send(meth_sym) =~ arg })
|
51
61
|
else
|
data/lib/mechanize/page.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
<html>
|
2
|
+
<head><title>tc_checkboxbuttons.html</title></head>
|
3
|
+
<body>
|
4
|
+
<form name="form1" method="post" action="/form_post">
|
5
|
+
Gender:<br />
|
6
|
+
M: <input type="checkbox" name="male" /><br />
|
7
|
+
F: <input type="checkbox" name="female" /><br />
|
8
|
+
Your one favorite color:<br />
|
9
|
+
Green: <input type="checkbox" name="green" /><br />
|
10
|
+
Green: <input type="checkbox" name="green" /><br />
|
11
|
+
Red: <input type="checkbox" name="red" /><br />
|
12
|
+
Blue: <input type="checkbox" name="blue" /><br />
|
13
|
+
Yellow: <input type="checkbox" name="yellow" /><br />
|
14
|
+
Brown: <input type="checkbox" name="brown" /><br />
|
15
|
+
Purple: <input type="checkbox" name="purple" /><br />
|
16
|
+
<input type="submit" value="Submit" />
|
17
|
+
</form>
|
18
|
+
</body>
|
19
|
+
</html>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<html>
|
2
|
+
<head><title>tc_pretty_print.html</title></head>
|
3
|
+
<body>
|
4
|
+
<a href="http://google.com/">Google</a><br />
|
5
|
+
<form method="post" action="/form_post" name="form1">
|
6
|
+
<input type="text" name="first_name"/><br />
|
7
|
+
<input type="password" name="password" /><br />
|
8
|
+
<input type="hidden" name="secret" value="hey" />
|
9
|
+
<input type="checkbox" name="checkme" />
|
10
|
+
<input type="radio" name="r" value="one" /><br />
|
11
|
+
<input type="radio" name="r" value="two" /><br />
|
12
|
+
<input type="submit" value="Submit" />
|
13
|
+
</form>
|
14
|
+
<frame src="http://memepool.com/" />
|
15
|
+
<iframe src="http://memepool.com/" />
|
16
|
+
</body>
|
17
|
+
</html>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<html>
|
2
|
+
<head><title>tc_radiobuttons.html</title></head>
|
3
|
+
<body>
|
4
|
+
<form name="form1" method="post" action="/form_post">
|
5
|
+
Gender:<br />
|
6
|
+
M: <input type="radio" name="gender" value="male" /><br />
|
7
|
+
F: <input type="radio" name="gender" value="female" /><br />
|
8
|
+
Your one favorite color:<br />
|
9
|
+
Green: <input type="radio" name="color" value="green" /><br />
|
10
|
+
Red: <input type="radio" name="color" value="red" /><br />
|
11
|
+
Blue: <input type="radio" name="color" value="blue" /><br />
|
12
|
+
Yellow: <input type="radio" name="color" value="yellow" /><br />
|
13
|
+
Brown: <input type="radio" name="color" value="brown" /><br />
|
14
|
+
<input type="submit" value="Submit" />
|
15
|
+
</form>
|
16
|
+
</body>
|
17
|
+
</html>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<html>
|
2
|
+
<head><title>tc_textarea.html</title></head>
|
3
|
+
<body>
|
4
|
+
<form name="form1" method="post" action="/form_post">
|
5
|
+
<textarea name="text1"></textarea>
|
6
|
+
<br />
|
7
|
+
<input type="submit" value="Submit" />
|
8
|
+
</form>
|
9
|
+
<br />
|
10
|
+
<form name="form2" method="post" action="/form_post">
|
11
|
+
<textarea name="text1">sample text</textarea>
|
12
|
+
<br />
|
13
|
+
<input type="submit" value="Submit" />
|
14
|
+
</form>
|
15
|
+
<br />
|
16
|
+
<form name="form3" method="post" action="/form_post">
|
17
|
+
<textarea name="text1"></textarea>
|
18
|
+
<textarea name="text1">sample text</textarea>
|
19
|
+
<br />
|
20
|
+
<input type="submit" value="Submit" />
|
21
|
+
</form>
|
22
|
+
</body>
|
23
|
+
</html>
|
data/test/tc_authenticate.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'test_includes'
|
7
|
+
|
8
|
+
class TestBadLinks < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
@page = @agent.get("http://localhost:#{PORT}/tc_bad_links.html")
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_space_in_link
|
17
|
+
assert_nothing_raised do
|
18
|
+
@agent.click @page.links.first
|
19
|
+
end
|
20
|
+
assert_match(/alt_text.html$/, @agent.history.last.uri.to_s)
|
21
|
+
assert_equal(2, @agent.history.length)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_space_in_url
|
25
|
+
page = nil
|
26
|
+
assert_nothing_raised do
|
27
|
+
page = @agent.get("http://localhost:#{PORT}/tc_bad_links.html ")
|
28
|
+
end
|
29
|
+
assert_match(/tc_bad_links.html$/, @agent.history.last.uri.to_s)
|
30
|
+
assert_equal(2, @agent.history.length)
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'test_includes'
|
7
|
+
|
8
|
+
class TestCheckBoxes < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
@page = @agent.get("http://localhost:#{PORT}/tc_checkboxes.html")
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_select_one
|
17
|
+
form = @page.forms.first
|
18
|
+
form.checkboxes.name('green').tick
|
19
|
+
assert_equal(true, form.checkboxes.name('green').checked)
|
20
|
+
assert_equal(false, form.checkboxes.name('red').checked)
|
21
|
+
assert_equal(false, form.checkboxes.name('blue').checked)
|
22
|
+
assert_equal(false, form.checkboxes.name('yellow').checked)
|
23
|
+
assert_equal(false, form.checkboxes.name('brown').checked)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_select_all
|
27
|
+
form = @page.forms.first
|
28
|
+
form.checkboxes.each do |b|
|
29
|
+
b.tick
|
30
|
+
end
|
31
|
+
form.checkboxes.each do |b|
|
32
|
+
assert_equal(true, b.checked)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_select_none
|
37
|
+
form = @page.forms.first
|
38
|
+
form.checkboxes.each do |b|
|
39
|
+
b.untick
|
40
|
+
end
|
41
|
+
form.checkboxes.each do |b|
|
42
|
+
assert_equal(false, b.checked)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_tick_one
|
47
|
+
form = @page.forms.first
|
48
|
+
assert_equal(2, form.checkboxes.name('green').length)
|
49
|
+
form.checkboxes.name('green')[1].tick
|
50
|
+
assert_equal(false, form.checkboxes.name('green')[0].checked)
|
51
|
+
assert_equal(true, form.checkboxes.name('green')[1].checked)
|
52
|
+
page = @agent.submit(form)
|
53
|
+
assert_equal(1, page.links.length)
|
54
|
+
assert_equal('green:on', page.links.first.text)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_tick_two
|
58
|
+
form = @page.forms.first
|
59
|
+
assert_equal(2, form.checkboxes.name('green').length)
|
60
|
+
form.checkboxes.name('green')[0].tick
|
61
|
+
form.checkboxes.name('green')[1].tick
|
62
|
+
assert_equal(true, form.checkboxes.name('green')[0].checked)
|
63
|
+
assert_equal(true, form.checkboxes.name('green')[1].checked)
|
64
|
+
page = @agent.submit(form)
|
65
|
+
assert_equal(2, page.links.length)
|
66
|
+
assert_equal('green:on', page.links.first.text)
|
67
|
+
assert_equal('green:on', page.links[1].text)
|
68
|
+
end
|
69
|
+
end
|
data/test/tc_cookies.rb
CHANGED
data/test/tc_errors.rb
CHANGED
data/test/tc_forms.rb
CHANGED
data/test/tc_frames.rb
CHANGED
data/test/tc_links.rb
CHANGED
@@ -9,7 +9,7 @@ class LinksMechTest < Test::Unit::TestCase
|
|
9
9
|
include TestMethods
|
10
10
|
|
11
11
|
def setup
|
12
|
-
@agent = WWW::Mechanize.new
|
12
|
+
@agent = WWW::Mechanize.new
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_find_meta
|
@@ -35,4 +35,15 @@ class LinksMechTest < Test::Unit::TestCase
|
|
35
35
|
assert_equal('no image', page.links.href('no_image.html').first.text)
|
36
36
|
assert_equal('', page.links.href('no_text.html').first.text)
|
37
37
|
end
|
38
|
+
|
39
|
+
def test_click_link
|
40
|
+
@agent.user_agent_alias = 'Mac Safari'
|
41
|
+
page = @agent.get("http://localhost:#{PORT}/frame_test.html")
|
42
|
+
link = page.links.text("Form Test")
|
43
|
+
assert_not_nil(link)
|
44
|
+
assert_equal('Form Test', link.text)
|
45
|
+
page = @agent.click(link)
|
46
|
+
assert_equal("http://localhost:#{PORT}/form_test.html",
|
47
|
+
@agent.history.last.uri.to_s)
|
48
|
+
end
|
38
49
|
end
|
data/test/tc_mech.rb
CHANGED
data/test/tc_multi_select.rb
CHANGED
@@ -102,7 +102,7 @@ class MultiSelectTest < Test::Unit::TestCase
|
|
102
102
|
page = @agent.get("http://localhost:#{PORT}/form_multi_select.html")
|
103
103
|
form = page.forms.first
|
104
104
|
form.list = ['1', 'Aaron']
|
105
|
-
form.fields.name('list').first.options[3].
|
105
|
+
form.fields.name('list').first.options[3].tick
|
106
106
|
assert_equal(['1', 'Aaron', '4'].sort, form.list.sort)
|
107
107
|
page = @agent.submit(form)
|
108
108
|
assert_equal(3, page.links.length)
|
data/test/tc_page.rb
CHANGED
data/test/tc_pluggable_parser.rb
CHANGED
data/test/tc_post_form.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'test_includes'
|
7
|
+
|
8
|
+
class TestPrettyPrint < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_pretty_print
|
16
|
+
@agent.get("http://localhost:#{PORT}/tc_pretty_print.html")
|
17
|
+
pretty_string = @agent.inspect
|
18
|
+
assert_match("{title \"tc_pretty_print.html\"}", pretty_string)
|
19
|
+
assert_match(/\{frames[^"]*"http:\/\/meme/, pretty_string)
|
20
|
+
assert_match(/\{iframes[^"]*"http:\/\/meme/, pretty_string)
|
21
|
+
assert_match(
|
22
|
+
"{links #<WWW::Mechanize::Link \"Google\" \"http://google.com/\">}",
|
23
|
+
pretty_string
|
24
|
+
)
|
25
|
+
assert_match("form1", pretty_string)
|
26
|
+
assert_match("POST", pretty_string)
|
27
|
+
assert_match("{file_uploads}", pretty_string)
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'test_includes'
|
7
|
+
|
8
|
+
class TestRadioButtons < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
@page = @agent.get("http://localhost:#{PORT}/tc_radiobuttons.html")
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_select_one
|
17
|
+
form = @page.forms.first
|
18
|
+
button = form.radiobuttons.name('color')
|
19
|
+
form.radiobuttons.name('color').value('green').tick
|
20
|
+
assert_equal(true, button.value('green').checked)
|
21
|
+
assert_equal(false, button.value('red').checked)
|
22
|
+
assert_equal(false, button.value('blue').checked)
|
23
|
+
assert_equal(false, button.value('yellow').checked)
|
24
|
+
assert_equal(false, button.value('brown').checked)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_select_all
|
28
|
+
form = @page.forms.first
|
29
|
+
button = form.radiobuttons.name('color')
|
30
|
+
form.radiobuttons.name('color').each do |b|
|
31
|
+
b.tick
|
32
|
+
end
|
33
|
+
form.radiobuttons.name('color').value('green').tick
|
34
|
+
assert_equal(true, button.value('green').checked)
|
35
|
+
assert_equal(false, button.value('red').checked)
|
36
|
+
assert_equal(false, button.value('blue').checked)
|
37
|
+
assert_equal(false, button.value('yellow').checked)
|
38
|
+
assert_equal(false, button.value('brown').checked)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_unselect_all
|
42
|
+
form = @page.forms.first
|
43
|
+
button = form.radiobuttons.name('color')
|
44
|
+
form.radiobuttons.name('color').each do |b|
|
45
|
+
b.untick
|
46
|
+
end
|
47
|
+
assert_equal(false, button.value('green').checked)
|
48
|
+
assert_equal(false, button.value('red').checked)
|
49
|
+
assert_equal(false, button.value('blue').checked)
|
50
|
+
assert_equal(false, button.value('yellow').checked)
|
51
|
+
assert_equal(false, button.value('brown').checked)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_click_one
|
55
|
+
form = @page.forms.first
|
56
|
+
button = form.radiobuttons.name('color')
|
57
|
+
form.radiobuttons.name('color').value('green').click
|
58
|
+
assert_equal(true, button.value('green').checked)
|
59
|
+
assert_equal(false, button.value('red').checked)
|
60
|
+
assert_equal(false, button.value('blue').checked)
|
61
|
+
assert_equal(false, button.value('yellow').checked)
|
62
|
+
assert_equal(false, button.value('brown').checked)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_click_twice
|
66
|
+
form = @page.forms.first
|
67
|
+
button = form.radiobuttons.name('color')
|
68
|
+
form.radiobuttons.name('color').value('green').click
|
69
|
+
assert_equal(true, button.value('green').checked)
|
70
|
+
form.radiobuttons.name('color').value('green').click
|
71
|
+
assert_equal(false, button.value('green').checked)
|
72
|
+
assert_equal(false, button.value('red').checked)
|
73
|
+
assert_equal(false, button.value('blue').checked)
|
74
|
+
assert_equal(false, button.value('yellow').checked)
|
75
|
+
assert_equal(false, button.value('brown').checked)
|
76
|
+
end
|
77
|
+
end
|
data/test/tc_response_code.rb
CHANGED
@@ -9,7 +9,7 @@ class ResponseCodeMechTest < Test::Unit::TestCase
|
|
9
9
|
include TestMethods
|
10
10
|
|
11
11
|
def setup
|
12
|
-
@agent = WWW::Mechanize.new
|
12
|
+
@agent = WWW::Mechanize.new
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_redirect
|
@@ -23,7 +23,7 @@ class ResponseCodeMechTest < Test::Unit::TestCase
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_error
|
26
|
-
@agent = WWW::Mechanize.new
|
26
|
+
@agent = WWW::Mechanize.new
|
27
27
|
begin
|
28
28
|
@agent.get("http://localhost:#{PORT}/response_code?code=500")
|
29
29
|
rescue WWW::Mechanize::ResponseCodeError => err
|
data/test/tc_save_file.rb
CHANGED
data/test/tc_select.rb
CHANGED
@@ -82,7 +82,7 @@ class SelectTest < Test::Unit::TestCase
|
|
82
82
|
|
83
83
|
def test_select_with_click
|
84
84
|
@form.list = ['1', 'Aaron']
|
85
|
-
@form.fields.name('list').first.options[3].
|
85
|
+
@form.fields.name('list').first.options[3].tick
|
86
86
|
assert_equal('4', @form.list)
|
87
87
|
page = @agent.submit(@form)
|
88
88
|
assert_equal(1, page.links.length)
|
data/test/tc_textarea.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'test_includes'
|
7
|
+
|
8
|
+
class TestTextArea < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
@page = @agent.get("http://localhost:#{PORT}/tc_textarea.html")
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_empty_text_area
|
17
|
+
form = @page.forms.name('form1').first
|
18
|
+
assert_equal('', form.fields.name('text1').value)
|
19
|
+
form.text1 = 'Hello World'
|
20
|
+
assert_equal('Hello World', form.fields.name('text1').value)
|
21
|
+
page = @agent.submit(form)
|
22
|
+
assert_equal(1, page.links.length)
|
23
|
+
assert_equal('text1:Hello World', page.links[0].text)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_non_empty_textfield
|
27
|
+
form = @page.forms.name('form2').first
|
28
|
+
assert_equal('sample text', form.fields.name('text1').value)
|
29
|
+
page = @agent.submit(form)
|
30
|
+
assert_equal(1, page.links.length)
|
31
|
+
assert_equal('text1:sample text', page.links[0].text)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_multi_textfield
|
35
|
+
form = @page.forms.name('form3').first
|
36
|
+
assert_equal(2, form.fields.name('text1').length)
|
37
|
+
assert_equal('', form.fields.name('text1')[0].value)
|
38
|
+
assert_equal('sample text', form.fields.name('text1')[1].value)
|
39
|
+
form.text1 = 'Hello World'
|
40
|
+
assert_equal('Hello World', form.fields.name('text1')[0].value)
|
41
|
+
assert_equal('sample text', form.fields.name('text1')[1].value)
|
42
|
+
page = @agent.submit(form)
|
43
|
+
assert_equal(2, page.links.length)
|
44
|
+
link = page.links.text('text1:sample text')
|
45
|
+
assert_not_nil(link)
|
46
|
+
assert_equal(1, link.length)
|
47
|
+
|
48
|
+
link = page.links.text('text1:Hello World')
|
49
|
+
assert_not_nil(link)
|
50
|
+
assert_equal(1, link.length)
|
51
|
+
end
|
52
|
+
end
|
data/test/tc_upload.rb
CHANGED
data/test/ts_mech.rb
CHANGED
@@ -34,6 +34,11 @@ require 'tc_select_none'
|
|
34
34
|
require 'tc_select'
|
35
35
|
require 'tc_select_noopts'
|
36
36
|
require 'tc_set_fields'
|
37
|
+
require 'tc_bad_links'
|
38
|
+
require 'tc_radiobutton'
|
39
|
+
require 'tc_checkboxes'
|
40
|
+
require 'tc_pretty_print'
|
41
|
+
require 'tc_textarea'
|
37
42
|
#require 'tc_proxy'
|
38
43
|
#require 'tc_ssl_server'
|
39
44
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: mechanize
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.5.
|
7
|
-
date: 2006-08-
|
6
|
+
version: 0.5.3
|
7
|
+
date: 2006-08-18 00:00:00 -07:00
|
8
8
|
summary: Mechanize provides automated web-browsing
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -35,6 +35,7 @@ files:
|
|
35
35
|
- test/tc_select_all.rb
|
36
36
|
- test/tc_page.rb
|
37
37
|
- test/test_includes.rb
|
38
|
+
- test/tc_checkboxes.rb
|
38
39
|
- test/tc_watches.rb
|
39
40
|
- test/tc_cookies.rb
|
40
41
|
- test/proxy.rb
|
@@ -47,12 +48,14 @@ files:
|
|
47
48
|
- test/tc_select_noopts.rb
|
48
49
|
- test/ssl_server.rb
|
49
50
|
- test/parse.rb
|
51
|
+
- test/tc_pretty_print.rb
|
50
52
|
- test/tc_post_form.rb
|
51
53
|
- test/tc_parsing.rb
|
52
54
|
- test/test_mech.rb
|
53
55
|
- test/tc_errors.rb
|
54
56
|
- test/tc_authenticate.rb
|
55
57
|
- test/README
|
58
|
+
- test/tc_radiobutton.rb
|
56
59
|
- test/tc_form_no_inputname.rb
|
57
60
|
- test/tc_upload.rb
|
58
61
|
- test/tc_cookie_class.rb
|
@@ -61,8 +64,10 @@ files:
|
|
61
64
|
- test/server.rb
|
62
65
|
- test/htdocs
|
63
66
|
- test/tc_ssl_server.rb
|
67
|
+
- test/tc_textarea.rb
|
64
68
|
- test/tc_proxy.rb
|
65
69
|
- test/tc_frames.rb
|
70
|
+
- test/tc_bad_links.rb
|
66
71
|
- test/tc_response_code.rb
|
67
72
|
- test/servlets.rb
|
68
73
|
- test/tc_save_file.rb
|
@@ -79,6 +84,7 @@ files:
|
|
79
84
|
- test/htdocs/bad_form_test.html
|
80
85
|
- test/htdocs/alt_text.html
|
81
86
|
- test/htdocs/frame_test.html
|
87
|
+
- test/htdocs/tc_radiobuttons.html
|
82
88
|
- test/htdocs/form_multi_select.html
|
83
89
|
- test/htdocs/form_set_fields.html
|
84
90
|
- test/htdocs/index.html
|
@@ -87,10 +93,14 @@ files:
|
|
87
93
|
- test/htdocs/no_title_test.html
|
88
94
|
- test/htdocs/button.jpg
|
89
95
|
- test/htdocs/form_multival.html
|
96
|
+
- test/htdocs/tc_bad_links.html
|
97
|
+
- test/htdocs/tc_checkboxes.html
|
98
|
+
- test/htdocs/tc_textarea.html
|
90
99
|
- test/htdocs/form_select_none.html
|
91
100
|
- test/htdocs/form_select_noopts.html
|
92
101
|
- test/htdocs/form_select.html
|
93
102
|
- test/htdocs/form_no_input_name.html
|
103
|
+
- test/htdocs/tc_pretty_print.html
|
94
104
|
- lib/mechanize.rb
|
95
105
|
- lib/mechanize
|
96
106
|
- lib/mechanize/errors.rb
|
@@ -99,6 +109,7 @@ files:
|
|
99
109
|
- lib/mechanize/form_elements.rb
|
100
110
|
- lib/mechanize/net-overrides
|
101
111
|
- lib/mechanize/cookie.rb
|
112
|
+
- lib/mechanize/inspect.rb
|
102
113
|
- lib/mechanize/mech_version.rb
|
103
114
|
- lib/mechanize/list.rb
|
104
115
|
- lib/mechanize/module.rb
|