mechanize 0.4.3 → 0.4.4
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 +6 -0
- data/NOTES +9 -0
- data/README +3 -0
- data/lib/mechanize.rb +3 -1
- data/lib/mechanize/form.rb +7 -3
- data/lib/mechanize/form_elements.rb +16 -4
- data/lib/mechanize/mech_version.rb +1 -1
- data/test/data/htpasswd +1 -0
- data/test/htdocs/file_upload.html +6 -0
- data/test/htdocs/form_test.html +8 -0
- data/test/server.rb +15 -1
- data/test/tc_authenticate.rb +27 -0
- data/test/tc_forms.rb +22 -4
- data/test/tc_upload.rb +19 -0
- data/test/ts_mech.rb +2 -0
- metadata +77 -72
data/CHANGELOG
CHANGED
data/NOTES
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
= Mechanize Release Notes
|
2
2
|
|
3
|
+
== 0.4.4
|
4
|
+
|
5
|
+
This release of mechanize comes with a new "Option" object that can be
|
6
|
+
accessed from select fields on forms. That means that you can figure out
|
7
|
+
what option to set based on the text in the select field. For example:
|
8
|
+
|
9
|
+
selectlist = form.fields.name('selectlist').first
|
10
|
+
selectlist.value = selectlist.options.find { |o| o.text == 'foo'}.value
|
11
|
+
|
3
12
|
== 0.4.3
|
4
13
|
|
5
14
|
The new syntax for finding things like forms, fields, frames, etcetera looks
|
data/README
CHANGED
@@ -24,6 +24,9 @@ Copyright (c) 2005 by Michael Neumann (mneumann@ntecs.de)
|
|
24
24
|
New Code:
|
25
25
|
Copyright (c) 2006 by Aaron Patterson (aaronp@rubyforge.org)
|
26
26
|
|
27
|
+
This library comes with a shameless plug for employing me (Aaron) programming
|
28
|
+
Ruby, my favorite language!
|
29
|
+
|
27
30
|
== License
|
28
31
|
|
29
32
|
This library is distributed under the GPL. Please see the LICENSE file.
|
data/lib/mechanize.rb
CHANGED
@@ -102,11 +102,13 @@ class Mechanize
|
|
102
102
|
cookies
|
103
103
|
end
|
104
104
|
|
105
|
-
def
|
105
|
+
def basic_auth(user, password)
|
106
106
|
@user = user
|
107
107
|
@password = password
|
108
108
|
end
|
109
109
|
|
110
|
+
alias :basic_authetication :basic_auth
|
111
|
+
|
110
112
|
def get(url)
|
111
113
|
cur_page = current_page() || Page.new
|
112
114
|
|
data/lib/mechanize/form.rb
CHANGED
@@ -148,16 +148,20 @@ module WWW
|
|
148
148
|
string
|
149
149
|
end
|
150
150
|
|
151
|
+
def mime_value_quote(str)
|
152
|
+
str.gsub(/(["\r\\])/){|s| '\\' + s}
|
153
|
+
end
|
154
|
+
|
151
155
|
def param_to_multipart(name, value)
|
152
156
|
return "Content-Disposition: form-data; name=\"" +
|
153
|
-
"#{
|
157
|
+
"#{mime_value_quote(name)}\"\r\n" +
|
154
158
|
"\r\n#{value}\r\n"
|
155
159
|
end
|
156
160
|
|
157
161
|
def file_to_multipart(file)
|
158
162
|
body = "Content-Disposition: form-data; name=\"" +
|
159
|
-
"#{
|
160
|
-
"filename=\"#{file.file_name}\"\r\n" +
|
163
|
+
"#{mime_value_quote(file.name)}\"; " +
|
164
|
+
"filename=\"#{mime_value_quote(file.file_name)}\"\r\n" +
|
161
165
|
"Content-Transfer-Encoding: binary\r\n"
|
162
166
|
if file.mime_type != nil
|
163
167
|
body << "Content-Type: #{file.mime_type}\r\n"
|
@@ -96,12 +96,24 @@ module WWW
|
|
96
96
|
# parse
|
97
97
|
node.each_recursive {|n|
|
98
98
|
if n.name.downcase == 'option'
|
99
|
-
|
100
|
-
@options <<
|
101
|
-
@value = value if
|
99
|
+
option = Option.new(n)
|
100
|
+
@options << option
|
101
|
+
@value = option.value if option.selected
|
102
102
|
end
|
103
103
|
}
|
104
|
-
@value = @options.first if @value == nil
|
104
|
+
@value = @options.first.value if @value == nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class Option
|
109
|
+
attr_reader :value, :selected, :text
|
110
|
+
|
111
|
+
alias :to_s :value
|
112
|
+
|
113
|
+
def initialize(node)
|
114
|
+
@text = node.all_text
|
115
|
+
@value = node.attributes['value']
|
116
|
+
@selected = node.attributes['selected'] ? true : false
|
105
117
|
end
|
106
118
|
end
|
107
119
|
end
|
data/test/data/htpasswd
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
mech:44E/qORekFV0E
|
@@ -7,6 +7,12 @@
|
|
7
7
|
<form enctype="multipart/form-data" action="/file_upload" method="post">
|
8
8
|
Your name: <input type="text" name="name" /><br />
|
9
9
|
File to process: <input name="userfile1" type="file" /><br />
|
10
|
+
<input type="text" name="foo[aaron]" value="test" />
|
11
|
+
<input type="submit" value="Send File" />
|
12
|
+
</form>
|
13
|
+
<form enctype="multipart/form-data" action="/file_upload" method="post">
|
14
|
+
Your name: <input type="text" name="name" /><br />
|
15
|
+
File to process: <input name="green[eggs]" type="file" /><br />
|
10
16
|
<input type="submit" value="Send File" />
|
11
17
|
</form>
|
12
18
|
</body>
|
data/test/htdocs/form_test.html
CHANGED
@@ -19,6 +19,10 @@
|
|
19
19
|
<td>Check this if you are cool:</td>
|
20
20
|
<td><input type="checkbox" name="cool person" /></td>
|
21
21
|
</tr>
|
22
|
+
<tr>
|
23
|
+
<td>Check this if you like green eggs:</td>
|
24
|
+
<td><input type="checkbox" name="green[eggs]" /></td>
|
25
|
+
</tr>
|
22
26
|
<tr>
|
23
27
|
<td>Check this if you like ham:</td>
|
24
28
|
<td><input type="checkbox" name="likes ham" /></td>
|
@@ -48,6 +52,10 @@
|
|
48
52
|
<td>Check this if you are cool:</td>
|
49
53
|
<td><input type="checkbox" name="cool person" /></td>
|
50
54
|
</tr>
|
55
|
+
<tr>
|
56
|
+
<td>Check this if you like green eggs:</td>
|
57
|
+
<td><input type="checkbox" name="green[eggs]" /></td>
|
58
|
+
</tr>
|
51
59
|
<tr>
|
52
60
|
<td>Check this if you like ham:</td>
|
53
61
|
<td><input type="checkbox" name="likes ham" /></td>
|
data/test/server.rb
CHANGED
@@ -2,9 +2,11 @@ require 'webrick'
|
|
2
2
|
require 'servlets'
|
3
3
|
require 'logger'
|
4
4
|
|
5
|
+
base_dir = FileTest.exists?(Dir::pwd + '/test') ? Dir::pwd + '/test' : Dir::pwd
|
6
|
+
|
5
7
|
s = WEBrick::HTTPServer.new(
|
6
8
|
:Port => 2000,
|
7
|
-
:DocumentRoot =>
|
9
|
+
:DocumentRoot => base_dir + "/htdocs",
|
8
10
|
:Logger => Logger.new(nil),
|
9
11
|
:AccessLog => Logger.new(nil)
|
10
12
|
)
|
@@ -17,6 +19,18 @@ s.mount("/form post", FormTest)
|
|
17
19
|
s.mount("/response_code", ResponseCodeTest)
|
18
20
|
s.mount("/file_upload", FileUploadTest)
|
19
21
|
|
22
|
+
htpasswd = WEBrick::HTTPAuth::Htpasswd.new(base_dir + '/data/htpasswd')
|
23
|
+
auth = WEBrick::HTTPAuth::BasicAuth.new(
|
24
|
+
:UserDB => htpasswd,
|
25
|
+
:Realm => 'mechanize',
|
26
|
+
:Logger => Logger.new(nil),
|
27
|
+
:AccessLog => Logger.new(nil)
|
28
|
+
)
|
29
|
+
s.mount_proc('/htpasswd_auth') { |req, res|
|
30
|
+
auth.authenticate(req, res)
|
31
|
+
res.body = "You are authenticated"
|
32
|
+
}
|
33
|
+
|
20
34
|
trap("INT") { s.stop }
|
21
35
|
|
22
36
|
s.start
|
@@ -0,0 +1,27 @@
|
|
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 BasicAuthTest < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def test_auth_success
|
12
|
+
agent = WWW::Mechanize.new { |a| a.log = Logger.new(nil) }
|
13
|
+
agent.basic_auth('mech', 'password')
|
14
|
+
page = agent.get("http://localhost:#{@port}/htpasswd_auth")
|
15
|
+
assert_equal('You are authenticated', page.body)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_auth_failure
|
19
|
+
agent = WWW::Mechanize.new { |a| a.log = Logger.new(nil) }
|
20
|
+
begin
|
21
|
+
page = agent.get("http://localhost:#{@port}/htpasswd_auth")
|
22
|
+
rescue WWW::ResponseCodeError => e
|
23
|
+
assert_equal("401", e.response_code)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/test/tc_forms.rb
CHANGED
@@ -21,7 +21,7 @@ class FormsMechTest < Test::Unit::TestCase
|
|
21
21
|
|
22
22
|
assert_equal(1, post_form.buttons.size)
|
23
23
|
assert_equal(2, post_form.radiobuttons.size)
|
24
|
-
assert_equal(
|
24
|
+
assert_equal(3, post_form.checkboxes.size)
|
25
25
|
assert_not_nil(post_form.fields.find { |f| f.name == "first_name" },
|
26
26
|
"First name field was nil"
|
27
27
|
)
|
@@ -42,11 +42,17 @@ class FormsMechTest < Test::Unit::TestCase
|
|
42
42
|
"couldn't find cool person checkbox")
|
43
43
|
assert_not_nil(post_form.checkboxes.find { |f| f.name == "likes ham" },
|
44
44
|
"couldn't find likes ham checkbox")
|
45
|
+
assert_not_nil(post_form.checkboxes.find { |f| f.name == "green[eggs]" },
|
46
|
+
"couldn't find green[eggs] checkbox")
|
45
47
|
|
46
48
|
# Find the select list
|
47
49
|
s = post_form.fields.find { |f| f.name == "country" }
|
48
50
|
assert_equal(2, s.options.length)
|
49
51
|
assert_equal("USA", s.value)
|
52
|
+
assert_equal("USA", s.options.first.value)
|
53
|
+
assert_equal("USA", s.options.first.text)
|
54
|
+
assert_equal("CANADA", s.options[1].value)
|
55
|
+
assert_equal("CANADA", s.options[1].text)
|
50
56
|
|
51
57
|
# Now set all the fields
|
52
58
|
post_form.fields.find { |f| f.name == "first_name" }.value = "Aaron"
|
@@ -54,14 +60,19 @@ class FormsMechTest < Test::Unit::TestCase
|
|
54
60
|
f.name == "gender" && f.value == "male"
|
55
61
|
}.checked = true
|
56
62
|
post_form.checkboxes.find { |f| f.name == "likes ham" }.checked = true
|
63
|
+
post_form.checkboxes.find { |f| f.name == "green[eggs]" }.checked = true
|
57
64
|
page = agent.submit(post_form, post_form.buttons.first)
|
58
65
|
|
59
66
|
# Check that the submitted fields exist
|
60
|
-
assert_equal(
|
67
|
+
assert_equal(5, page.links.size, "Not enough links")
|
61
68
|
assert_not_nil(
|
62
69
|
page.links.find { |l| l.text == "likes ham:on" },
|
63
70
|
"likes ham check box missing"
|
64
71
|
)
|
72
|
+
assert_not_nil(
|
73
|
+
page.links.find { |l| l.text == "green[eggs]:on" },
|
74
|
+
"green[eggs] check box missing"
|
75
|
+
)
|
65
76
|
assert_not_nil(
|
66
77
|
page.links.find { |l| l.text == "first_name:Aaron" },
|
67
78
|
"first_name field missing"
|
@@ -86,7 +97,7 @@ class FormsMechTest < Test::Unit::TestCase
|
|
86
97
|
assert_equal(1, get_form.fields.size)
|
87
98
|
assert_equal(2, get_form.buttons.size)
|
88
99
|
assert_equal(2, get_form.radiobuttons.size)
|
89
|
-
assert_equal(
|
100
|
+
assert_equal(3, get_form.checkboxes.size)
|
90
101
|
assert_not_nil(get_form.fields.find { |f| f.name == "first_name" },
|
91
102
|
"First name field was nil"
|
92
103
|
)
|
@@ -104,6 +115,8 @@ class FormsMechTest < Test::Unit::TestCase
|
|
104
115
|
"couldn't find cool person checkbox")
|
105
116
|
assert_not_nil(get_form.checkboxes.find { |f| f.name == "likes ham" },
|
106
117
|
"couldn't find likes ham checkbox")
|
118
|
+
assert_not_nil(get_form.checkboxes.find { |f| f.name == "green[eggs]" },
|
119
|
+
"couldn't find green[eggs] checkbox")
|
107
120
|
|
108
121
|
# Set up the image button
|
109
122
|
img = get_form.buttons.find { |f| f.name == "button" }
|
@@ -115,14 +128,19 @@ class FormsMechTest < Test::Unit::TestCase
|
|
115
128
|
f.name == "gender" && f.value == "male"
|
116
129
|
}.checked = true
|
117
130
|
get_form.checkboxes.find { |f| f.name == "likes ham" }.checked = true
|
131
|
+
get_form.checkboxes.find { |f| f.name == "green[eggs]" }.checked = true
|
118
132
|
page = agent.submit(get_form, get_form.buttons.first)
|
119
133
|
|
120
134
|
# Check that the submitted fields exist
|
121
|
-
assert_equal(
|
135
|
+
assert_equal(7, page.links.size, "Not enough links")
|
122
136
|
assert_not_nil(
|
123
137
|
page.links.find { |l| l.text == "likes ham:on" },
|
124
138
|
"likes ham check box missing"
|
125
139
|
)
|
140
|
+
assert_not_nil(
|
141
|
+
page.links.find { |l| l.text == "green[eggs]:on" },
|
142
|
+
"green[eggs] check box missing"
|
143
|
+
)
|
126
144
|
assert_not_nil(
|
127
145
|
page.links.find { |l| l.text == "first_name:Aaron" },
|
128
146
|
"first_name field missing"
|
data/test/tc_upload.rb
CHANGED
@@ -30,5 +30,24 @@ class UploadMechTest < Test::Unit::TestCase
|
|
30
30
|
)
|
31
31
|
assert_match('Content-Type: text/plain', page.body)
|
32
32
|
assert_match('Hello World', page.body)
|
33
|
+
assert_match('foo[aaron]', page.body)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_form_multipart
|
37
|
+
agent = WWW::Mechanize.new { |a| a.log = Logger.new(nil) }
|
38
|
+
page = agent.get("http://localhost:#{@port}/file_upload.html")
|
39
|
+
assert_equal('multipart/form-data', page.forms[1].enctype)
|
40
|
+
|
41
|
+
form = page.forms[1]
|
42
|
+
form.file_uploads.first.file_name = "README"
|
43
|
+
form.file_uploads.first.mime_type = "text/plain"
|
44
|
+
form.file_uploads.first.file_data = "Hello World\n\n"
|
45
|
+
|
46
|
+
page = agent.submit(form)
|
47
|
+
|
48
|
+
assert_match(
|
49
|
+
"Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"README\"",
|
50
|
+
page.body
|
51
|
+
)
|
33
52
|
end
|
34
53
|
end
|
data/test/ts_mech.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "test")
|
2
3
|
|
3
4
|
Thread.new {
|
4
5
|
require 'server'
|
@@ -14,4 +15,5 @@ require 'tc_upload'
|
|
14
15
|
require 'tc_forms'
|
15
16
|
require 'tc_watches'
|
16
17
|
require 'tc_parsing'
|
18
|
+
require 'tc_authenticate'
|
17
19
|
|
metadata
CHANGED
@@ -3,99 +3,104 @@ 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-
|
6
|
+
version: 0.4.4
|
7
|
+
date: 2006-05-11 00:00:00 -07:00
|
8
8
|
summary: Mechanize provides automated web-browsing
|
9
9
|
require_paths:
|
10
|
-
|
10
|
+
- lib
|
11
11
|
email: aaronp@rubyforge.org
|
12
12
|
homepage: mechanize.rubyforge.org
|
13
13
|
rubyforge_project: mechanize
|
14
14
|
description:
|
15
|
-
autorequire:
|
15
|
+
autorequire:
|
16
16
|
default_executable:
|
17
17
|
bindir: bin
|
18
18
|
has_rdoc: true
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
version: 0.0.0
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
25
24
|
version:
|
26
25
|
platform: ruby
|
27
26
|
signing_key:
|
28
27
|
cert_chain:
|
29
28
|
authors:
|
30
|
-
|
29
|
+
- Aaron Patterson
|
31
30
|
files:
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
31
|
+
- test/tc_watches.rb
|
32
|
+
- test/servlets.rb
|
33
|
+
- test/tc_upload.rb
|
34
|
+
- test/htdocs
|
35
|
+
- test/tc_response_code.rb
|
36
|
+
- test/tc_links.rb
|
37
|
+
- test/tc_forms.rb
|
38
|
+
- test/server.rb
|
39
|
+
- test/test_mech.rb
|
40
|
+
- test/tc_frames.rb
|
41
|
+
- test/test_includes.rb
|
42
|
+
- test/tc_cookies.rb
|
43
|
+
- test/tc_authenticate.rb
|
44
|
+
- test/tc_mech.rb
|
45
|
+
- test/README
|
46
|
+
- test/data
|
47
|
+
- test/tc_parsing.rb
|
48
|
+
- test/ts_mech.rb
|
49
|
+
- test/htdocs/find_link.html
|
50
|
+
- test/htdocs/frame_test.html
|
51
|
+
- test/htdocs/iframe_test.html
|
52
|
+
- test/htdocs/google.html
|
53
|
+
- test/htdocs/form_test.html
|
54
|
+
- test/htdocs/index.html
|
55
|
+
- test/htdocs/button.jpg
|
56
|
+
- test/htdocs/file_upload.html
|
57
|
+
- test/data/htpasswd
|
58
|
+
- lib/mechanize
|
59
|
+
- lib/mechanize.rb
|
60
|
+
- lib/mechanize/cookie.rb
|
61
|
+
- lib/mechanize/page.rb
|
62
|
+
- lib/mechanize/form.rb
|
63
|
+
- lib/mechanize/parsing.rb
|
64
|
+
- lib/mechanize/net-overrides
|
65
|
+
- lib/mechanize/page_elements.rb
|
66
|
+
- lib/mechanize/form_elements.rb
|
67
|
+
- lib/mechanize/mech_version.rb
|
68
|
+
- lib/mechanize/module.rb
|
69
|
+
- lib/mechanize/net-overrides/net
|
70
|
+
- lib/mechanize/net-overrides/net/http.rb
|
71
|
+
- lib/mechanize/net-overrides/net/protocol.rb
|
72
|
+
- lib/mechanize/net-overrides/net/https.rb
|
73
|
+
- README
|
74
|
+
- EXAMPLES
|
75
|
+
- CHANGELOG
|
76
|
+
- LICENSE
|
77
|
+
- NOTES
|
76
78
|
test_files: []
|
79
|
+
|
77
80
|
rdoc_options:
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
81
|
+
- --main
|
82
|
+
- README
|
83
|
+
- --title
|
84
|
+
- "'WWW::Mechanize RDoc'"
|
82
85
|
extra_rdoc_files:
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
86
|
+
- README
|
87
|
+
- EXAMPLES
|
88
|
+
- CHANGELOG
|
89
|
+
- LICENSE
|
90
|
+
- NOTES
|
88
91
|
executables: []
|
92
|
+
|
89
93
|
extensions: []
|
94
|
+
|
90
95
|
requirements: []
|
96
|
+
|
91
97
|
dependencies:
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
version:
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: ruby-web
|
100
|
+
version_requirement:
|
101
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: 1.1.0
|
106
|
+
version:
|