mechanize 0.4.2 → 0.4.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 +8 -11
- data/EXAMPLES +8 -8
- data/NOTES +30 -0
- data/lib/mechanize.rb +2 -1
- data/lib/mechanize/cookie.rb +70 -43
- data/lib/mechanize/form.rb +11 -2
- data/lib/mechanize/form_elements.rb +2 -0
- data/lib/mechanize/mech_version.rb +1 -1
- data/lib/mechanize/module.rb +37 -0
- data/lib/mechanize/page.rb +22 -12
- data/test/htdocs/button.jpg +0 -0
- data/test/htdocs/form_test.html +11 -1
- data/test/servlets.rb +2 -1
- data/test/tc_forms.rb +34 -5
- data/test/tc_mech.rb +30 -2
- data/test/tc_parsing.rb +3 -1
- metadata +72 -71
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 0.4.3
|
2
|
+
|
3
|
+
* Added syntactic sugar for finding things
|
4
|
+
* Fixed bug with HttpOnly option in cookies
|
5
|
+
* Fixed a bug with cookie date parsing
|
6
|
+
* Defaulted dropdown lists to the first element
|
7
|
+
* Added unit tests
|
8
|
+
|
1
9
|
== 0.4.2
|
2
10
|
|
3
11
|
* Added support for iframes
|
@@ -8,32 +16,21 @@
|
|
8
16
|
== 0.4.1
|
9
17
|
|
10
18
|
* Added support for file uploading
|
11
|
-
|
12
19
|
* Added support for frames (Thanks Gabriel[mailto:leerbag@googlemail.com])
|
13
|
-
|
14
20
|
* Added more unit tests
|
15
|
-
|
16
21
|
* Fixed some bugs
|
17
22
|
|
18
23
|
== 0.4.0
|
19
24
|
|
20
25
|
* Added more unit tests
|
21
|
-
|
22
26
|
* Added a cookie jar with better cookie support, included expiration of cookies
|
23
27
|
and general cookie security.
|
24
|
-
|
25
28
|
* Updated mechanize to use built in net/http if ruby version is new enough.
|
26
|
-
|
27
29
|
* Added support for meta refresh tags
|
28
|
-
|
29
30
|
* Defaulted form actions to 'GET'
|
30
|
-
|
31
31
|
* Fixed various bugs
|
32
|
-
|
33
32
|
* Added more unit tests
|
34
|
-
|
35
33
|
* Added a response code exception
|
36
|
-
|
37
34
|
* Thanks to Brian Ellin (brianellin@gmail.com) for:
|
38
35
|
Added support for CA files, and support for 301 response codes
|
39
36
|
|
data/EXAMPLES
CHANGED
@@ -8,8 +8,8 @@
|
|
8
8
|
agent = WWW::Mechanize.new { |a| a.log = Logger.new("mech.log") }
|
9
9
|
agent.user_agent_alias = 'Mac Safari'
|
10
10
|
page = agent.get("http://www.google.com/")
|
11
|
-
search_form = page.forms.
|
12
|
-
search_form.fields.
|
11
|
+
search_form = page.forms.with.name("f").first
|
12
|
+
search_form.fields.name("q").first.value = "Hello"
|
13
13
|
search_results = agent.submit(search_form)
|
14
14
|
puts search_results.body
|
15
15
|
|
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
agent = WWW::Mechanize.new {|a| a.log = Logger.new(STDERR) }
|
20
20
|
page = agent.get('http://rubyforge.org/')
|
21
|
-
link = page.links.
|
21
|
+
link = page.links.text(/Log In/).first
|
22
22
|
page = agent.click(link)
|
23
23
|
form = page.forms[1]
|
24
24
|
form.fields.find {|f| f.name == 'form_loginname'}.value = ARGV[0]
|
@@ -36,13 +36,13 @@ This example uploads one image as two different images to flickr.
|
|
36
36
|
agent = WWW::Mechanize.new
|
37
37
|
page = agent.get('http://flickr.com/signin/flickr/')
|
38
38
|
form = page.forms.first
|
39
|
-
form.fields.
|
40
|
-
form.fields.
|
39
|
+
form.fields.name('email').first.value = ARGV[0]
|
40
|
+
form.fields.name('password').first.value = ARGV[1]
|
41
41
|
page = agent.submit(form)
|
42
|
-
page = agent.click
|
42
|
+
page = agent.click page.links.text('Upload').first
|
43
43
|
form = page.forms.first
|
44
|
-
img1 = form.file_uploads.
|
45
|
-
img2 = form.file_uploads.
|
44
|
+
img1 = form.file_uploads.name('file1').first
|
45
|
+
img2 = form.file_uploads.name('file2').first
|
46
46
|
|
47
47
|
img1.file_name = img2.file_name = ARGV[2]
|
48
48
|
File.open(ARGV[2], "r") { |f|
|
data/NOTES
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
= Mechanize Release Notes
|
2
|
+
|
3
|
+
== 0.4.3
|
4
|
+
|
5
|
+
The new syntax for finding things like forms, fields, frames, etcetera looks
|
6
|
+
like this:
|
7
|
+
|
8
|
+
page.links.with.text 'Some Text'
|
9
|
+
|
10
|
+
The preceding statement will find all links in a page with the text
|
11
|
+
'Some Text'. This can be applied to form fields as well:
|
12
|
+
|
13
|
+
form.fields.with.name 'email'
|
14
|
+
|
15
|
+
These can be chained as well like this:
|
16
|
+
|
17
|
+
form.fields.with.name('email').and.with.value('blah@domain.com')
|
18
|
+
|
19
|
+
'with' and 'and' can be omitted, and the old way is still supported. The
|
20
|
+
following statements all do the same thing:
|
21
|
+
|
22
|
+
form.fields.find_all { |f| f.name == 'email' }
|
23
|
+
form.fields.with.name('email')
|
24
|
+
form.fields.name('email')
|
25
|
+
form.fields(:name => 'email')
|
26
|
+
|
27
|
+
Regular expressions are also supported:
|
28
|
+
|
29
|
+
form.fields.with.name(/email/)
|
30
|
+
|
data/lib/mechanize.rb
CHANGED
@@ -19,6 +19,7 @@ require 'logger'
|
|
19
19
|
require 'webrick'
|
20
20
|
require 'date'
|
21
21
|
require 'web/htmltools/xmltree' # narf
|
22
|
+
require 'mechanize/module'
|
22
23
|
require 'mechanize/parsing'
|
23
24
|
require 'mechanize/cookie'
|
24
25
|
require 'mechanize/form'
|
@@ -143,8 +144,8 @@ class Mechanize
|
|
143
144
|
end
|
144
145
|
|
145
146
|
def submit(form, button=nil)
|
147
|
+
form.add_button_to_query(button) if button
|
146
148
|
query = form.build_query
|
147
|
-
button.add_to_query(query) if button
|
148
149
|
|
149
150
|
uri = to_absolute_uri(URI::escape(form.action))
|
150
151
|
case form.method.upcase
|
data/lib/mechanize/cookie.rb
CHANGED
@@ -1,54 +1,81 @@
|
|
1
1
|
module WWW
|
2
2
|
class Cookie
|
3
3
|
attr_reader :name, :value, :path, :domain, :expires, :secure
|
4
|
-
def initialize(
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
def initialize(cookie)
|
5
|
+
@name = cookie[:name]
|
6
|
+
@value = cookie[:value]
|
7
|
+
@path = cookie[:path]
|
8
|
+
@domain = cookie[:domain]
|
9
|
+
@expires = cookie[:expires]
|
10
|
+
@secure = cookie[:secure]
|
11
|
+
@string = "#{cookie[:name]}=#{URI::escape(cookie[:value])}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def Cookie::parse(uri, raw_cookie, &block)
|
15
|
+
esc = raw_cookie.gsub(/(expires=[^,]*),([^;]*(;|$))/i) { "#{$1}#{$2}" }
|
16
|
+
esc.split(/,/).each do |cookie_text|
|
17
|
+
cookie_values = Hash.new
|
18
|
+
cookie = Hash.new
|
19
|
+
cookie_text.split(/; /).each do |data|
|
20
|
+
name, value = data.split('=', 2)
|
21
|
+
next unless name
|
22
|
+
cookie[name] = value ? URI::unescape(value) : nil
|
23
|
+
end
|
11
24
|
|
12
|
-
|
13
|
-
|
14
|
-
|
25
|
+
cookie_values[:path] = cookie.delete(
|
26
|
+
cookie.keys.find { |k| k.downcase == "path" }
|
27
|
+
) || uri.path
|
15
28
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
29
|
+
expires_key = cookie.keys.find { |k| k.downcase == "expires" }
|
30
|
+
if expires_key
|
31
|
+
time = nil
|
32
|
+
expires_val = cookie.delete(expires_key)
|
33
|
+
[ '%A %d-%b-%y %T %Z',
|
34
|
+
'%a, %d-%b-%Y %T %Z',
|
35
|
+
'%a %d %b %Y %T %Z'
|
36
|
+
].each { |fmt|
|
37
|
+
begin
|
38
|
+
time = DateTime.strptime(expires_val, fmt)
|
39
|
+
rescue ArgumentError
|
40
|
+
else
|
41
|
+
break
|
42
|
+
end
|
43
|
+
}
|
44
|
+
time = DateTime.parse(expires_val) if time == nil
|
45
|
+
cookie_values[:expires] = time
|
46
|
+
end
|
20
47
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
# Set the domain name of the cookie
|
30
|
-
domain_key = cookie.keys.find { |k| k.downcase == "domain" }
|
31
|
-
if domain_key
|
32
|
-
domain = cookie.delete(domain_key)
|
33
|
-
domain.sub!(/^\./, '')
|
34
|
-
if url.host =~ /#{domain}$/
|
35
|
-
@domain = domain
|
48
|
+
secure_key = cookie.keys.find { |k| k.downcase == "secure" }
|
49
|
+
if secure_key
|
50
|
+
cookie_values[:secure] = true
|
51
|
+
cookie.delete(secure_key)
|
52
|
+
else
|
53
|
+
cookie_values[:secure] = false
|
36
54
|
end
|
37
|
-
else
|
38
|
-
@domain = url.host
|
39
|
-
end
|
40
55
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
56
|
+
# Set the domain name of the cookie
|
57
|
+
domain_key = cookie.keys.find { |k| k.downcase == "domain" }
|
58
|
+
if domain_key
|
59
|
+
domain = cookie.delete(domain_key)
|
60
|
+
domain.sub!(/^\./, '')
|
61
|
+
|
62
|
+
# Reject cookies not for this domain
|
63
|
+
next unless uri.host =~ /#{domain}$/
|
64
|
+
cookie_values[:domain] = domain
|
65
|
+
else
|
66
|
+
cookie_values[:domain] = uri.host
|
67
|
+
end
|
68
|
+
|
69
|
+
# Delete the http only option
|
70
|
+
# http://msdn.microsoft.com/workshop/author/dhtml/httponly_cookies.asp
|
71
|
+
http_only = cookie.keys.find { |k| k.downcase == 'httponly' }
|
72
|
+
cookie.delete(http_only) if http_only
|
73
|
+
|
74
|
+
cookie.each { |k,v|
|
75
|
+
cookie_values[:name] = k.strip
|
76
|
+
cookie_values[:value] = v.strip
|
77
|
+
}
|
78
|
+
yield Cookie.new(cookie_values)
|
52
79
|
end
|
53
80
|
end
|
54
81
|
|
data/lib/mechanize/form.rb
CHANGED
@@ -18,7 +18,7 @@ module WWW
|
|
18
18
|
attr_reader :form_node, :elements_node
|
19
19
|
attr_accessor :method, :action, :name
|
20
20
|
|
21
|
-
|
21
|
+
attr_finder :fields, :buttons, :file_uploads, :radiobuttons, :checkboxes
|
22
22
|
attr_reader :enctype
|
23
23
|
|
24
24
|
def initialize(form_node, elements_node)
|
@@ -28,6 +28,7 @@ module WWW
|
|
28
28
|
@action = @form_node.attributes['action']
|
29
29
|
@name = @form_node.attributes['name']
|
30
30
|
@enctype = @form_node.attributes['enctype'] || 'application/x-www-form-urlencoded'
|
31
|
+
@clicked_buttons = []
|
31
32
|
|
32
33
|
parse
|
33
34
|
end
|
@@ -48,7 +49,7 @@ module WWW
|
|
48
49
|
}
|
49
50
|
end
|
50
51
|
|
51
|
-
def build_query
|
52
|
+
def build_query(buttons = [])
|
52
53
|
query = {}
|
53
54
|
|
54
55
|
fields().each do |f|
|
@@ -76,9 +77,17 @@ module WWW
|
|
76
77
|
raise "multiple radiobuttons are checked in the same group!"
|
77
78
|
end
|
78
79
|
end
|
80
|
+
|
81
|
+
@clicked_buttons.each { |b|
|
82
|
+
b.add_to_query(query)
|
83
|
+
}
|
79
84
|
|
80
85
|
query
|
81
86
|
end
|
87
|
+
|
88
|
+
def add_button_to_query(button)
|
89
|
+
@clicked_buttons << button
|
90
|
+
end
|
82
91
|
|
83
92
|
def request_data
|
84
93
|
query_params = build_query()
|
@@ -90,6 +90,7 @@ module WWW
|
|
90
90
|
|
91
91
|
def initialize(name, node)
|
92
92
|
@name = name
|
93
|
+
@value = nil
|
93
94
|
@options = []
|
94
95
|
|
95
96
|
# parse
|
@@ -100,6 +101,7 @@ module WWW
|
|
100
101
|
@value = value if n.attributes['selected']
|
101
102
|
end
|
102
103
|
}
|
104
|
+
@value = @options.first if @value == nil
|
103
105
|
end
|
104
106
|
end
|
105
107
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Module
|
2
|
+
def attr_finder(*syms)
|
3
|
+
syms.each do |sym|
|
4
|
+
class_eval %{ def #{sym.to_s}(hash = nil)
|
5
|
+
if hash == nil
|
6
|
+
@#{sym.to_s}
|
7
|
+
else
|
8
|
+
@#{sym.to_s}.find_all do |t|
|
9
|
+
found = true
|
10
|
+
hash.each_key \{ |key|
|
11
|
+
found = false if t.send(key.to_sym) != hash[key]
|
12
|
+
\}
|
13
|
+
found
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Array
|
23
|
+
def with
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
alias :and :with
|
28
|
+
|
29
|
+
def method_missing(meth_sym, arg)
|
30
|
+
if arg.class == Regexp
|
31
|
+
find_all { |e| e.send(meth_sym) =~ arg }
|
32
|
+
else
|
33
|
+
find_all { |e| e.send(meth_sym) == arg }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
data/lib/mechanize/page.rb
CHANGED
@@ -21,6 +21,15 @@ module WWW
|
|
21
21
|
# body = page.watches
|
22
22
|
class Page
|
23
23
|
attr_accessor :uri, :cookies, :response, :body, :code, :watch_for_set
|
24
|
+
attr_finder :frames, :iframes, :links, :forms, :meta, :watches
|
25
|
+
|
26
|
+
# Alias our finders so that we can lazily parse the html
|
27
|
+
alias :find_frames :frames
|
28
|
+
alias :find_iframes :iframes
|
29
|
+
alias :find_links :links
|
30
|
+
alias :find_forms :forms
|
31
|
+
alias :find_meta :meta
|
32
|
+
alias :find_watches :watches
|
24
33
|
|
25
34
|
def initialize(uri=nil, cookies=[], response=nil, body=nil, code=nil)
|
26
35
|
@uri, @cookies, @response, @body, @code = uri, cookies, response, body, code
|
@@ -30,6 +39,7 @@ module WWW
|
|
30
39
|
@forms = nil
|
31
40
|
@meta = nil
|
32
41
|
@watches = nil
|
42
|
+
@root = nil
|
33
43
|
end
|
34
44
|
|
35
45
|
def header
|
@@ -40,14 +50,14 @@ module WWW
|
|
40
50
|
@response['Content-Type']
|
41
51
|
end
|
42
52
|
|
43
|
-
def forms
|
53
|
+
def forms(*args)
|
44
54
|
parse_html() unless @forms
|
45
|
-
|
55
|
+
find_forms(*args)
|
46
56
|
end
|
47
57
|
|
48
|
-
def links
|
58
|
+
def links(*args)
|
49
59
|
parse_html() unless @links
|
50
|
-
|
60
|
+
find_links(*args)
|
51
61
|
end
|
52
62
|
|
53
63
|
def root
|
@@ -58,24 +68,24 @@ module WWW
|
|
58
68
|
# This method watches out for a particular tag, and will call back to the
|
59
69
|
# class specified for the tag in the watch_for_set method. See the example
|
60
70
|
# in this class.
|
61
|
-
def watches
|
71
|
+
def watches(*args)
|
62
72
|
parse_html() unless @watches
|
63
|
-
|
73
|
+
find_watches(*args)
|
64
74
|
end
|
65
75
|
|
66
|
-
def meta
|
76
|
+
def meta(*args)
|
67
77
|
parse_html() unless @meta
|
68
|
-
|
78
|
+
find_meta(*args)
|
69
79
|
end
|
70
80
|
|
71
|
-
def frames
|
81
|
+
def frames(*args)
|
72
82
|
parse_html() unless @frames
|
73
|
-
|
83
|
+
find_frames(*args)
|
74
84
|
end
|
75
85
|
|
76
|
-
def iframes
|
86
|
+
def iframes(*args)
|
77
87
|
parse_html() unless @iframes
|
78
|
-
|
88
|
+
find_iframes(*args)
|
79
89
|
end
|
80
90
|
|
81
91
|
private
|
Binary file
|
data/test/htdocs/form_test.html
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
<html>
|
2
2
|
<head><title>Page Title</title></head>
|
3
3
|
<body>
|
4
|
-
<h1>
|
4
|
+
<h1>Post Form 1</h1>
|
5
5
|
<form name="post_form1" method="post" action="/form_post">
|
6
6
|
<table>
|
7
7
|
<tr>
|
@@ -24,8 +24,13 @@
|
|
24
24
|
<td><input type="checkbox" name="likes ham" /></td>
|
25
25
|
</tr>
|
26
26
|
</table><br />
|
27
|
+
<select name="country">
|
28
|
+
<option value="USA">USA</option>
|
29
|
+
<option value="CANADA">CANADA</option>
|
30
|
+
</select><br />
|
27
31
|
<input type="submit" value="Submit" />
|
28
32
|
</form>
|
33
|
+
<h1>Get Form 1</h1>
|
29
34
|
<form name="get_form1" method="get" action="/form_post">
|
30
35
|
<table>
|
31
36
|
<tr>
|
@@ -48,10 +53,12 @@
|
|
48
53
|
<td><input type="checkbox" name="likes ham" /></td>
|
49
54
|
</tr>
|
50
55
|
</table><br />
|
56
|
+
<input type="image" name="button" value="button" src="button.jpg" />
|
51
57
|
<input type="submit" value="Submit" />
|
52
58
|
</form>
|
53
59
|
|
54
60
|
<!-- Get ant post to a form with a space in the name -->
|
61
|
+
<h1>Post Form 2</h1>
|
55
62
|
<form name="post_form2" method="post" action="/form post">
|
56
63
|
<table>
|
57
64
|
<tr>
|
@@ -76,6 +83,7 @@
|
|
76
83
|
</table><br />
|
77
84
|
<input type="submit" value="Submit" />
|
78
85
|
</form>
|
86
|
+
<h1>Get Form 2</h1>
|
79
87
|
<form name="get_form2" method="get" action="/form post">
|
80
88
|
<table>
|
81
89
|
<tr>
|
@@ -102,6 +110,7 @@
|
|
102
110
|
</form>
|
103
111
|
|
104
112
|
<!-- forms with parameters in the action -->
|
113
|
+
<h1>Post Form 3</h1>
|
105
114
|
<form name="post_form3" method="post" action="/form_post?great day=yes&one=two">
|
106
115
|
<table>
|
107
116
|
<tr>
|
@@ -126,6 +135,7 @@
|
|
126
135
|
</table><br />
|
127
136
|
<input type="submit" value="Submit" />
|
128
137
|
</form>
|
138
|
+
<h1>Get Form 3</h1>
|
129
139
|
<form name="get_form3" method="get" action="/form_post?great day=yes&one=two">
|
130
140
|
<table>
|
131
141
|
<tr>
|
data/test/servlets.rb
CHANGED
@@ -94,10 +94,11 @@ class ManyCookiesAsStringTest < WEBrick::HTTPServlet::AbstractServlet
|
|
94
94
|
name_cookie = WEBrick::Cookie.new("name", "Aaron")
|
95
95
|
name_cookie.path = "/"
|
96
96
|
name_cookie.expires = Time.now + 86400
|
97
|
+
name_cookie.domain = 'localhost'
|
97
98
|
cookies << name_cookie
|
98
99
|
cookies << name_cookie
|
99
100
|
cookies << name_cookie
|
100
|
-
cookies << name_cookie
|
101
|
+
cookies << "#{name_cookie}; HttpOnly"
|
101
102
|
|
102
103
|
expired_cookie = WEBrick::Cookie.new("expired", "doh")
|
103
104
|
expired_cookie.path = "/"
|
data/test/tc_forms.rb
CHANGED
@@ -4,7 +4,6 @@ require 'webrick'
|
|
4
4
|
require 'test/unit'
|
5
5
|
require 'rubygems'
|
6
6
|
require 'mechanize'
|
7
|
-
require 'servlets'
|
8
7
|
require 'test_includes'
|
9
8
|
|
10
9
|
class FormsMechTest < Test::Unit::TestCase
|
@@ -17,13 +16,18 @@ class FormsMechTest < Test::Unit::TestCase
|
|
17
16
|
assert_not_nil(post_form, "Post form is null")
|
18
17
|
assert_equal("post", post_form.method.downcase)
|
19
18
|
assert_equal("/form_post", post_form.action)
|
20
|
-
|
19
|
+
|
20
|
+
assert_equal(2, post_form.fields.size)
|
21
|
+
|
21
22
|
assert_equal(1, post_form.buttons.size)
|
22
23
|
assert_equal(2, post_form.radiobuttons.size)
|
23
24
|
assert_equal(2, post_form.checkboxes.size)
|
24
25
|
assert_not_nil(post_form.fields.find { |f| f.name == "first_name" },
|
25
26
|
"First name field was nil"
|
26
27
|
)
|
28
|
+
assert_not_nil(post_form.fields.find { |f| f.name == "country" },
|
29
|
+
"Country field was nil"
|
30
|
+
)
|
27
31
|
assert_not_nil(
|
28
32
|
post_form.radiobuttons.find { |f| f.name == "gender" && f.value == "male"},
|
29
33
|
"Gender male button was nil"
|
@@ -39,6 +43,11 @@ class FormsMechTest < Test::Unit::TestCase
|
|
39
43
|
assert_not_nil(post_form.checkboxes.find { |f| f.name == "likes ham" },
|
40
44
|
"couldn't find likes ham checkbox")
|
41
45
|
|
46
|
+
# Find the select list
|
47
|
+
s = post_form.fields.find { |f| f.name == "country" }
|
48
|
+
assert_equal(2, s.options.length)
|
49
|
+
assert_equal("USA", s.value)
|
50
|
+
|
42
51
|
# Now set all the fields
|
43
52
|
post_form.fields.find { |f| f.name == "first_name" }.value = "Aaron"
|
44
53
|
post_form.radiobuttons.find { |f|
|
@@ -48,7 +57,7 @@ class FormsMechTest < Test::Unit::TestCase
|
|
48
57
|
page = agent.submit(post_form, post_form.buttons.first)
|
49
58
|
|
50
59
|
# Check that the submitted fields exist
|
51
|
-
assert_equal(
|
60
|
+
assert_equal(4, page.links.size, "Not enough links")
|
52
61
|
assert_not_nil(
|
53
62
|
page.links.find { |l| l.text == "likes ham:on" },
|
54
63
|
"likes ham check box missing"
|
@@ -61,6 +70,10 @@ class FormsMechTest < Test::Unit::TestCase
|
|
61
70
|
page.links.find { |l| l.text == "gender:male" },
|
62
71
|
"gender field missing"
|
63
72
|
)
|
73
|
+
assert_not_nil(
|
74
|
+
page.links.find { |l| l.text == "country:USA" },
|
75
|
+
"select box not submitted"
|
76
|
+
)
|
64
77
|
end
|
65
78
|
|
66
79
|
def test_get
|
@@ -71,7 +84,7 @@ class FormsMechTest < Test::Unit::TestCase
|
|
71
84
|
assert_equal("get", get_form.method.downcase)
|
72
85
|
assert_equal("/form_post", get_form.action)
|
73
86
|
assert_equal(1, get_form.fields.size)
|
74
|
-
assert_equal(
|
87
|
+
assert_equal(2, get_form.buttons.size)
|
75
88
|
assert_equal(2, get_form.radiobuttons.size)
|
76
89
|
assert_equal(2, get_form.checkboxes.size)
|
77
90
|
assert_not_nil(get_form.fields.find { |f| f.name == "first_name" },
|
@@ -92,6 +105,10 @@ class FormsMechTest < Test::Unit::TestCase
|
|
92
105
|
assert_not_nil(get_form.checkboxes.find { |f| f.name == "likes ham" },
|
93
106
|
"couldn't find likes ham checkbox")
|
94
107
|
|
108
|
+
# Set up the image button
|
109
|
+
img = get_form.buttons.find { |f| f.name == "button" }
|
110
|
+
img.x = "9"
|
111
|
+
img.y = "10"
|
95
112
|
# Now set all the fields
|
96
113
|
get_form.fields.find { |f| f.name == "first_name" }.value = "Aaron"
|
97
114
|
get_form.radiobuttons.find { |f|
|
@@ -101,7 +118,7 @@ class FormsMechTest < Test::Unit::TestCase
|
|
101
118
|
page = agent.submit(get_form, get_form.buttons.first)
|
102
119
|
|
103
120
|
# Check that the submitted fields exist
|
104
|
-
assert_equal(
|
121
|
+
assert_equal(6, page.links.size, "Not enough links")
|
105
122
|
assert_not_nil(
|
106
123
|
page.links.find { |l| l.text == "likes ham:on" },
|
107
124
|
"likes ham check box missing"
|
@@ -114,6 +131,18 @@ class FormsMechTest < Test::Unit::TestCase
|
|
114
131
|
page.links.find { |l| l.text == "gender:male" },
|
115
132
|
"gender field missing"
|
116
133
|
)
|
134
|
+
assert_not_nil(
|
135
|
+
page.links.find { |l| l.text == "button.y:10" },
|
136
|
+
"Image button missing"
|
137
|
+
)
|
138
|
+
assert_not_nil(
|
139
|
+
page.links.find { |l| l.text == "button.x:9" },
|
140
|
+
"Image button missing"
|
141
|
+
)
|
142
|
+
assert_not_nil(
|
143
|
+
page.links.find { |l| l.text == "button:button" },
|
144
|
+
"Image button missing"
|
145
|
+
)
|
117
146
|
end
|
118
147
|
|
119
148
|
def test_post_with_space_in_action
|
data/test/tc_mech.rb
CHANGED
@@ -62,8 +62,36 @@ class MechMethodsTest < Test::Unit::TestCase
|
|
62
62
|
page = agent.get("http://localhost:#{@port}/google.html")
|
63
63
|
search = page.forms.find { |f| f.name == "f" }
|
64
64
|
assert_not_nil(search)
|
65
|
-
assert_not_nil(search.fields.
|
66
|
-
assert_not_nil(search.fields
|
65
|
+
assert_not_nil(search.fields.name('q').first)
|
66
|
+
assert_not_nil(search.fields(:name => 'hl').first)
|
67
67
|
assert_not_nil(search.fields.find { |f| f.name == 'ie' })
|
68
68
|
end
|
69
|
+
|
70
|
+
def test_click
|
71
|
+
agent = WWW::Mechanize.new { |a| a.log = Logger.new(nil) }
|
72
|
+
agent.user_agent_alias = 'Mac Safari'
|
73
|
+
page = agent.get("http://localhost:#{@port}/frame_test.html")
|
74
|
+
link = page.links.text("Form Test").first
|
75
|
+
assert_not_nil(link)
|
76
|
+
page = agent.click(link)
|
77
|
+
assert_equal("http://localhost:#{@port}/form_test.html",
|
78
|
+
agent.history.last.uri.to_s)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_new_find
|
82
|
+
agent = WWW::Mechanize.new { |a| a.log = Logger.new(nil) }
|
83
|
+
page = agent.get("http://localhost:#{@port}/frame_test.html")
|
84
|
+
assert_equal(3, page.frames.size)
|
85
|
+
|
86
|
+
find_orig = page.frames.find_all { |f| f.name == 'frame1' }
|
87
|
+
find1 = page.frames.with.name('frame1')
|
88
|
+
find2 = page.frames.name('frame1')
|
89
|
+
find3 = page.frames(:name => 'frame1')
|
90
|
+
|
91
|
+
find_orig.zip(find1, find2, find3).each { |a,b,c,d|
|
92
|
+
assert_equal(a, b)
|
93
|
+
assert_equal(a, c)
|
94
|
+
assert_equal(a, d)
|
95
|
+
}
|
96
|
+
end
|
69
97
|
end
|
data/test/tc_parsing.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.11
|
2
|
+
rubygems_version: 0.8.11
|
3
3
|
specification_version: 1
|
4
4
|
name: mechanize
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.4.
|
7
|
-
date: 2006-04-
|
6
|
+
version: 0.4.3
|
7
|
+
date: 2006-04-26 00:00:00 -07:00
|
8
8
|
summary: Mechanize provides automated web-browsing
|
9
9
|
require_paths:
|
10
|
-
- lib
|
10
|
+
- lib
|
11
11
|
email: aaronp@rubyforge.org
|
12
12
|
homepage: mechanize.rubyforge.org
|
13
13
|
rubyforge_project: mechanize
|
@@ -18,83 +18,84 @@ bindir: bin
|
|
18
18
|
has_rdoc: true
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
24
25
|
version:
|
25
26
|
platform: ruby
|
26
27
|
signing_key:
|
27
28
|
cert_chain:
|
28
|
-
post_install_message:
|
29
29
|
authors:
|
30
|
-
- Aaron Patterson
|
30
|
+
- Aaron Patterson
|
31
31
|
files:
|
32
|
-
- test/
|
33
|
-
- test/
|
34
|
-
- test/
|
35
|
-
- test/
|
36
|
-
- test/
|
37
|
-
- test/tc_forms.rb
|
38
|
-
- test/
|
39
|
-
- test/tc_links.rb
|
40
|
-
- test/
|
41
|
-
- test/tc_parsing.rb
|
42
|
-
- test/
|
43
|
-
- test/
|
44
|
-
- test/
|
45
|
-
- test/
|
46
|
-
- test/
|
47
|
-
- test/
|
48
|
-
- test/htdocs/
|
49
|
-
- test/htdocs/
|
50
|
-
- test/htdocs/find_link.html
|
51
|
-
- test/htdocs/
|
52
|
-
- test/htdocs/
|
53
|
-
- test/htdocs/
|
54
|
-
- test/htdocs/iframe_test.html
|
55
|
-
-
|
56
|
-
- lib/mechanize
|
57
|
-
- lib/mechanize
|
58
|
-
- lib/mechanize/
|
59
|
-
- lib/mechanize/
|
60
|
-
- lib/mechanize/
|
61
|
-
- lib/mechanize/
|
62
|
-
- lib/mechanize/
|
63
|
-
- lib/mechanize/
|
64
|
-
- lib/mechanize/
|
65
|
-
- lib/mechanize/
|
66
|
-
- lib/mechanize/
|
67
|
-
- lib/mechanize/net-overrides/net
|
68
|
-
- lib/mechanize/net-overrides/net/
|
69
|
-
-
|
70
|
-
-
|
71
|
-
-
|
72
|
-
-
|
32
|
+
- test/htdocs
|
33
|
+
- test/README
|
34
|
+
- test/server.rb
|
35
|
+
- test/servlets.rb
|
36
|
+
- test/tc_cookies.rb
|
37
|
+
- test/tc_forms.rb
|
38
|
+
- test/tc_frames.rb
|
39
|
+
- test/tc_links.rb
|
40
|
+
- test/tc_mech.rb
|
41
|
+
- test/tc_parsing.rb
|
42
|
+
- test/tc_response_code.rb
|
43
|
+
- test/tc_upload.rb
|
44
|
+
- test/tc_watches.rb
|
45
|
+
- test/test_includes.rb
|
46
|
+
- test/test_mech.rb
|
47
|
+
- test/ts_mech.rb
|
48
|
+
- test/htdocs/button.jpg
|
49
|
+
- test/htdocs/file_upload.html
|
50
|
+
- test/htdocs/find_link.html
|
51
|
+
- test/htdocs/form_test.html
|
52
|
+
- test/htdocs/frame_test.html
|
53
|
+
- test/htdocs/google.html
|
54
|
+
- test/htdocs/iframe_test.html
|
55
|
+
- test/htdocs/index.html
|
56
|
+
- lib/mechanize
|
57
|
+
- lib/mechanize.rb
|
58
|
+
- lib/mechanize/cookie.rb
|
59
|
+
- lib/mechanize/form.rb
|
60
|
+
- lib/mechanize/form_elements.rb
|
61
|
+
- lib/mechanize/mech_version.rb
|
62
|
+
- lib/mechanize/module.rb
|
63
|
+
- lib/mechanize/net-overrides
|
64
|
+
- lib/mechanize/page.rb
|
65
|
+
- lib/mechanize/page_elements.rb
|
66
|
+
- lib/mechanize/parsing.rb
|
67
|
+
- lib/mechanize/net-overrides/net
|
68
|
+
- lib/mechanize/net-overrides/net/http.rb
|
69
|
+
- lib/mechanize/net-overrides/net/https.rb
|
70
|
+
- lib/mechanize/net-overrides/net/protocol.rb
|
71
|
+
- README
|
72
|
+
- EXAMPLES
|
73
|
+
- CHANGELOG
|
74
|
+
- LICENSE
|
75
|
+
- NOTES
|
73
76
|
test_files: []
|
74
|
-
|
75
77
|
rdoc_options:
|
76
|
-
- --main
|
77
|
-
- README
|
78
|
-
- --title
|
79
|
-
- "'WWW::Mechanize RDoc'"
|
78
|
+
- "--main"
|
79
|
+
- README
|
80
|
+
- "--title"
|
81
|
+
- "'WWW::Mechanize RDoc'"
|
80
82
|
extra_rdoc_files:
|
81
|
-
- README
|
82
|
-
- EXAMPLES
|
83
|
-
- CHANGELOG
|
84
|
-
- LICENSE
|
83
|
+
- README
|
84
|
+
- EXAMPLES
|
85
|
+
- CHANGELOG
|
86
|
+
- LICENSE
|
87
|
+
- NOTES
|
85
88
|
executables: []
|
86
|
-
|
87
89
|
extensions: []
|
88
|
-
|
89
90
|
requirements: []
|
90
|
-
|
91
91
|
dependencies:
|
92
|
-
- !ruby/object:Gem::Dependency
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
92
|
+
- !ruby/object:Gem::Dependency
|
93
|
+
name: ruby-web
|
94
|
+
version_requirement:
|
95
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
96
|
+
requirements:
|
97
|
+
-
|
98
|
+
- ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 1.1.0
|
101
|
+
version:
|