mechanize 2.14.0 → 2.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -1
- data/README.md +7 -0
- data/SECURITY.md +11 -0
- data/lib/mechanize/directory_saver.rb +2 -1
- data/lib/mechanize/file_saver.rb +2 -0
- data/lib/mechanize/http/agent.rb +83 -29
- data/lib/mechanize/parser.rb +33 -3
- data/lib/mechanize/test_case.rb +2 -9
- data/lib/mechanize/version.rb +1 -1
- data/lib/mechanize.rb +12 -2
- data/test/htdocs/frame_test.html +8 -6
- data/test/htdocs/relative/tc_relative_links.html +1 -1
- metadata +7 -174
- data/.autotest +0 -6
- data/.github/dependabot.yml +0 -11
- data/.github/workflows/ci.yml +0 -43
- data/.github/workflows/upstream.yml +0 -51
- data/.gitignore +0 -15
- data/.yardopts +0 -8
- data/Gemfile +0 -12
- data/Rakefile +0 -56
- data/examples/flickr_upload.rb +0 -22
- data/examples/latest_user_agents.rb +0 -100
- data/examples/mech-dump.rb +0 -5
- data/examples/proxy_req.rb +0 -7
- data/examples/rubygems.rb +0 -23
- data/examples/spider.rb +0 -22
- data/examples/wikipedia_links_to_philosophy.rb +0 -158
- data/mechanize.gemspec +0 -74
- data/test/data/htpasswd +0 -1
- data/test/data/server.crt +0 -16
- data/test/data/server.csr +0 -12
- data/test/data/server.key +0 -15
- data/test/data/server.pem +0 -15
- data/test/test_mechanize.rb +0 -1382
- data/test/test_mechanize_cookie.rb +0 -559
- data/test/test_mechanize_cookie_jar.rb +0 -615
- data/test/test_mechanize_directory_saver.rb +0 -60
- data/test/test_mechanize_download.rb +0 -102
- data/test/test_mechanize_element_not_found_error.rb +0 -16
- data/test/test_mechanize_file.rb +0 -118
- data/test/test_mechanize_file_connection.rb +0 -40
- data/test/test_mechanize_file_request.rb +0 -26
- data/test/test_mechanize_file_response.rb +0 -48
- data/test/test_mechanize_file_saver.rb +0 -22
- data/test/test_mechanize_form.rb +0 -1025
- data/test/test_mechanize_form_check_box.rb +0 -49
- data/test/test_mechanize_form_encoding.rb +0 -110
- data/test/test_mechanize_form_field.rb +0 -78
- data/test/test_mechanize_form_file_upload.rb +0 -21
- data/test/test_mechanize_form_image_button.rb +0 -13
- data/test/test_mechanize_form_keygen.rb +0 -34
- data/test/test_mechanize_form_multi_select_list.rb +0 -98
- data/test/test_mechanize_form_option.rb +0 -60
- data/test/test_mechanize_form_radio_button.rb +0 -96
- data/test/test_mechanize_form_select_list.rb +0 -81
- data/test/test_mechanize_form_textarea.rb +0 -53
- data/test/test_mechanize_headers.rb +0 -36
- data/test/test_mechanize_history.rb +0 -104
- data/test/test_mechanize_http_agent.rb +0 -1915
- data/test/test_mechanize_http_auth_challenge.rb +0 -64
- data/test/test_mechanize_http_auth_realm.rb +0 -56
- data/test/test_mechanize_http_auth_store.rb +0 -233
- data/test/test_mechanize_http_content_disposition_parser.rb +0 -167
- data/test/test_mechanize_http_www_authenticate_parser.rb +0 -204
- data/test/test_mechanize_image.rb +0 -9
- data/test/test_mechanize_link.rb +0 -171
- data/test/test_mechanize_page.rb +0 -295
- data/test/test_mechanize_page_encoding.rb +0 -215
- data/test/test_mechanize_page_frame.rb +0 -17
- data/test/test_mechanize_page_image.rb +0 -191
- data/test/test_mechanize_page_link.rb +0 -377
- data/test/test_mechanize_page_meta_refresh.rb +0 -151
- data/test/test_mechanize_parser.rb +0 -316
- data/test/test_mechanize_pluggable_parser.rb +0 -68
- data/test/test_mechanize_redirect_limit_reached_error.rb +0 -25
- data/test/test_mechanize_redirect_not_get_or_head_error.rb +0 -15
- data/test/test_mechanize_response_read_error.rb +0 -29
- data/test/test_mechanize_subclass.rb +0 -23
- data/test/test_mechanize_util.rb +0 -144
- data/test/test_mechanize_xml_file.rb +0 -30
- data/test/test_multi_select.rb +0 -120
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
require 'mechanize/test_case'
|
|
3
|
-
|
|
4
|
-
class TestMechanizeHttpWwwAuthenticateParser < Mechanize::TestCase
|
|
5
|
-
|
|
6
|
-
def setup
|
|
7
|
-
super
|
|
8
|
-
|
|
9
|
-
@parser = Mechanize::HTTP::WWWAuthenticateParser.new
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def test_auth_param
|
|
13
|
-
@parser.scanner = StringScanner.new 'realm=here'
|
|
14
|
-
|
|
15
|
-
param = @parser.auth_param
|
|
16
|
-
|
|
17
|
-
assert_equal %w[realm here], param
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def test_auth_param_bad_no_value
|
|
21
|
-
@parser.scanner = StringScanner.new 'realm='
|
|
22
|
-
|
|
23
|
-
assert_nil @parser.auth_param
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def test_auth_param_bad_token
|
|
27
|
-
@parser.scanner = StringScanner.new 'realm'
|
|
28
|
-
|
|
29
|
-
assert_nil @parser.auth_param
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def test_auth_param_bad_value
|
|
33
|
-
@parser.scanner = StringScanner.new 'realm="this '
|
|
34
|
-
|
|
35
|
-
assert_nil @parser.auth_param
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def test_auth_param_quoted
|
|
39
|
-
@parser.scanner = StringScanner.new 'realm="this site"'
|
|
40
|
-
|
|
41
|
-
param = @parser.auth_param
|
|
42
|
-
|
|
43
|
-
assert_equal ['realm', 'this site'], param
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def test_parse
|
|
47
|
-
expected = [
|
|
48
|
-
challenge('Basic', { 'realm' => 'foo', 'qop' => 'auth,auth-int' }, 'Basic realm=foo, qop="auth,auth-int"'),
|
|
49
|
-
]
|
|
50
|
-
|
|
51
|
-
assert_equal expected, @parser.parse('Basic realm=foo, qop="auth,auth-int"')
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def test_parse_without_comma_delimiter
|
|
55
|
-
expected = [
|
|
56
|
-
challenge('Basic', { 'realm' => 'foo', 'qop' => 'auth,auth-int' }, 'Basic realm=foo qop="auth,auth-int"'),
|
|
57
|
-
]
|
|
58
|
-
|
|
59
|
-
assert_equal expected, @parser.parse('Basic realm=foo qop="auth,auth-int"')
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def test_parse_multiple
|
|
63
|
-
expected = [
|
|
64
|
-
challenge('Basic', { 'realm' => 'foo' }, 'Basic realm=foo'),
|
|
65
|
-
challenge('Digest', { 'realm' => 'bar' }, 'Digest realm=bar'),
|
|
66
|
-
]
|
|
67
|
-
|
|
68
|
-
assert_equal expected, @parser.parse('Basic realm=foo, Digest realm=bar')
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def test_parse_multiple_without_comma_delimiter
|
|
72
|
-
expected = [
|
|
73
|
-
challenge('Basic', { 'realm' => 'foo' }, 'Basic realm=foo'),
|
|
74
|
-
challenge('Digest', { 'realm' => 'bar' }, 'Digest realm=bar'),
|
|
75
|
-
]
|
|
76
|
-
|
|
77
|
-
assert_equal expected, @parser.parse('Basic realm=foo Digest realm=bar')
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def test_parse_multiple_blank
|
|
81
|
-
expected = [
|
|
82
|
-
challenge('Basic', { 'realm' => 'foo' }, 'Basic realm=foo'),
|
|
83
|
-
challenge('Digest', { 'realm' => 'bar' }, 'Digest realm=bar'),
|
|
84
|
-
]
|
|
85
|
-
|
|
86
|
-
assert_equal expected, @parser.parse('Basic realm=foo,, Digest realm=bar')
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def test_parse_ntlm_init
|
|
90
|
-
expected = [
|
|
91
|
-
challenge('NTLM', nil, 'NTLM'),
|
|
92
|
-
]
|
|
93
|
-
|
|
94
|
-
assert_equal expected, @parser.parse('NTLM')
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def test_parse_ntlm_type_2_3
|
|
98
|
-
expected = [
|
|
99
|
-
challenge('NTLM', 'foo=', 'NTLM foo='),
|
|
100
|
-
]
|
|
101
|
-
|
|
102
|
-
assert_equal expected, @parser.parse('NTLM foo=')
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def test_parse_realm_uppercase
|
|
106
|
-
expected = [
|
|
107
|
-
challenge('Basic', { 'realm' => 'foo' }, 'Basic ReAlM=foo'),
|
|
108
|
-
]
|
|
109
|
-
|
|
110
|
-
assert_equal expected, @parser.parse('Basic ReAlM=foo')
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def test_parse_realm_value_case
|
|
114
|
-
expected = [
|
|
115
|
-
challenge('Basic', { 'realm' => 'Foo' }, 'Basic realm=Foo'),
|
|
116
|
-
]
|
|
117
|
-
|
|
118
|
-
assert_equal expected, @parser.parse('Basic realm=Foo')
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def test_parse_scheme_uppercase
|
|
122
|
-
expected = [
|
|
123
|
-
challenge('Basic', { 'realm' => 'foo' }, 'BaSiC realm=foo'),
|
|
124
|
-
]
|
|
125
|
-
|
|
126
|
-
assert_equal expected, @parser.parse('BaSiC realm=foo')
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def test_parse_bad_whitespace_around_auth_param
|
|
130
|
-
expected = [
|
|
131
|
-
challenge('Basic', { 'realm' => 'foo' }, 'Basic realm = "foo"'),
|
|
132
|
-
]
|
|
133
|
-
|
|
134
|
-
assert_equal expected, @parser.parse('Basic realm = "foo"')
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def test_parse_bad_single_quote
|
|
138
|
-
expected = [
|
|
139
|
-
challenge('Basic', { 'realm' => "'foo" }, "Basic realm='foo"),
|
|
140
|
-
]
|
|
141
|
-
|
|
142
|
-
assert_equal expected, @parser.parse("Basic realm='foo bar', qop='baz'")
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
def test_quoted_string
|
|
146
|
-
@parser.scanner = StringScanner.new '"text"'
|
|
147
|
-
|
|
148
|
-
string = @parser.quoted_string
|
|
149
|
-
|
|
150
|
-
assert_equal 'text', string
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
def test_quoted_string_bad
|
|
154
|
-
@parser.scanner = StringScanner.new '"text'
|
|
155
|
-
|
|
156
|
-
assert_nil @parser.quoted_string
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def test_quoted_string_quote
|
|
160
|
-
@parser.scanner = StringScanner.new '"escaped \\" here"'
|
|
161
|
-
|
|
162
|
-
string = @parser.quoted_string
|
|
163
|
-
|
|
164
|
-
assert_equal 'escaped \\" here', string
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def test_quoted_string_quote_end
|
|
168
|
-
@parser.scanner = StringScanner.new '"end \""'
|
|
169
|
-
|
|
170
|
-
string = @parser.quoted_string
|
|
171
|
-
|
|
172
|
-
assert_equal 'end \"', string
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def test_token
|
|
176
|
-
@parser.scanner = StringScanner.new 'text'
|
|
177
|
-
|
|
178
|
-
string = @parser.token
|
|
179
|
-
|
|
180
|
-
assert_equal 'text', string
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
def test_token_space
|
|
184
|
-
@parser.scanner = StringScanner.new 't ext'
|
|
185
|
-
|
|
186
|
-
string = @parser.token
|
|
187
|
-
|
|
188
|
-
assert_equal 't', string
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
def test_token_special
|
|
192
|
-
@parser.scanner = StringScanner.new "t\text"
|
|
193
|
-
|
|
194
|
-
string = @parser.token
|
|
195
|
-
|
|
196
|
-
assert_equal 't', string
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
def challenge scheme, params, raw
|
|
200
|
-
Mechanize::HTTP::AuthChallenge.new scheme, params, raw
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
end
|
|
204
|
-
|
data/test/test_mechanize_link.rb
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
require 'mechanize/test_case'
|
|
3
|
-
|
|
4
|
-
class TestMechanizeLink < Mechanize::TestCase
|
|
5
|
-
|
|
6
|
-
def test_search
|
|
7
|
-
page = @mech.get("http://localhost/find_link.html")
|
|
8
|
-
link = page.link_with(text: "Form Test")
|
|
9
|
-
|
|
10
|
-
assert_equal('Form Test', link.text)
|
|
11
|
-
|
|
12
|
-
link_with_search = page.link_with(search: "//*[text()='Form Test']")
|
|
13
|
-
assert_equal(link, link_with_search)
|
|
14
|
-
|
|
15
|
-
link_with_xpath = page.link_with(xpath: "//*[text()='Form Test']")
|
|
16
|
-
assert_equal(link, link_with_xpath)
|
|
17
|
-
|
|
18
|
-
link_with_css = page.link_with(css: ".formtest")
|
|
19
|
-
assert_equal(link, link_with_css)
|
|
20
|
-
|
|
21
|
-
link_with_class = page.link_with(class: "formtest")
|
|
22
|
-
assert_equal(link, link_with_class)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def test_click
|
|
26
|
-
page = @mech.get("http://localhost/frame_test.html")
|
|
27
|
-
link = page.link_with(:text => "Form Test")
|
|
28
|
-
|
|
29
|
-
assert_equal('Form Test', link.text)
|
|
30
|
-
page = link.click
|
|
31
|
-
assert_equal("http://localhost/form_test.html",
|
|
32
|
-
@mech.history.last.uri.to_s)
|
|
33
|
-
end unless RUBY_ENGINE == 'jruby' # NekoHTML does not parse body of NOFRAMES
|
|
34
|
-
|
|
35
|
-
def test_click_bang
|
|
36
|
-
page = @mech.get("http://localhost/frame_test.html")
|
|
37
|
-
link = page.link_with!(:text => "Form Test")
|
|
38
|
-
|
|
39
|
-
assert_equal('Form Test', link.text)
|
|
40
|
-
page = link.click
|
|
41
|
-
assert_equal("http://localhost/form_test.html",
|
|
42
|
-
@mech.history.last.uri.to_s)
|
|
43
|
-
end unless RUBY_ENGINE == 'jruby' # NekoHTML does not parse body of NOFRAMES
|
|
44
|
-
|
|
45
|
-
def test_click_base
|
|
46
|
-
page = @mech.get("http://google.com/tc_base_link.html")
|
|
47
|
-
page = page.links.first.click
|
|
48
|
-
assert @mech.visited?("http://localhost/index.html")
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def test_click_unsupported_scheme
|
|
52
|
-
page = @mech.get("http://google.com/tc_links.html")
|
|
53
|
-
link = page.link_with(:text => 'javascript link')
|
|
54
|
-
assert_raises Mechanize::UnsupportedSchemeError do
|
|
55
|
-
begin
|
|
56
|
-
link.click
|
|
57
|
-
rescue Mechanize::UnsupportedSchemeError => error
|
|
58
|
-
assert_equal 'javascript', error.scheme
|
|
59
|
-
assert_equal "javascript:new_page('1')", error.uri.to_s
|
|
60
|
-
raise
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
@mech.scheme_handlers['javascript'] = lambda { |my_link, my_page|
|
|
65
|
-
URI.parse('http://localhost/tc_links.html')
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
link.click
|
|
69
|
-
|
|
70
|
-
# HACK no assertion
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def test_click_unexiting_link
|
|
74
|
-
page = @mech.get("http://google.com/tc_links.html")
|
|
75
|
-
assert_raises NoMethodError do
|
|
76
|
-
page.link_with(:text => 'no link').click
|
|
77
|
-
end
|
|
78
|
-
begin
|
|
79
|
-
page.link_with!(:text => 'no link').click
|
|
80
|
-
rescue => e
|
|
81
|
-
assert_instance_of Mechanize::ElementNotFoundError, e
|
|
82
|
-
assert_kind_of Mechanize::Page, e.source
|
|
83
|
-
assert_equal :link, e.element
|
|
84
|
-
assert_kind_of Hash, e.conditions
|
|
85
|
-
assert_equal 'no link', e.conditions[:text]
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def test_click_empty_href
|
|
90
|
-
page = @mech.get("http://google.com/tc_links.html?q=test#anchor")
|
|
91
|
-
link = page.link_with(:text => 'empty href')
|
|
92
|
-
|
|
93
|
-
new_page = link.click
|
|
94
|
-
assert_equal "http://google.com/tc_links.html?q=test", new_page.uri.to_s
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def test_text_alt_text
|
|
98
|
-
page = @mech.get("http://localhost/alt_text.html")
|
|
99
|
-
assert_equal(5, page.links.length)
|
|
100
|
-
assert_equal(1, page.meta_refresh.length)
|
|
101
|
-
|
|
102
|
-
assert_equal '', page.meta_refresh.first.text
|
|
103
|
-
assert_equal 'alt text', page.link_with(:href => 'alt_text.html').text
|
|
104
|
-
assert_equal '', page.link_with(:href => 'no_alt_text.html').text
|
|
105
|
-
assert_equal 'no image', page.link_with(:href => 'no_image.html').text
|
|
106
|
-
assert_equal '', page.link_with(:href => 'no_text.html').text
|
|
107
|
-
assert_equal '', page.link_with(:href => 'nil_alt_text.html').text
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def test_uri_escaped
|
|
111
|
-
doc = Nokogiri::HTML::Document.new
|
|
112
|
-
|
|
113
|
-
node = Nokogiri::XML::Node.new('foo', doc)
|
|
114
|
-
node['href'] = 'http://foo.bar/%20baz'
|
|
115
|
-
|
|
116
|
-
link = Mechanize::Page::Link.new(node, nil, nil)
|
|
117
|
-
|
|
118
|
-
assert_equal 'http://foo.bar/%20baz', link.uri.to_s
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def test_uri_no_path
|
|
122
|
-
page = @mech.get("http://localhost/relative/tc_relative_links.html")
|
|
123
|
-
page = page.link_with(:text => 'just the query string').click
|
|
124
|
-
assert_equal('http://localhost/relative/tc_relative_links.html?a=b',
|
|
125
|
-
page.uri.to_s)
|
|
126
|
-
end unless RUBY_ENGINE == 'jruby' # NekoHTML does not parse IFRAME
|
|
127
|
-
|
|
128
|
-
def test_uri_weird
|
|
129
|
-
doc = Nokogiri::HTML::Document.new
|
|
130
|
-
|
|
131
|
-
node = Nokogiri::XML::Node.new('foo', doc)
|
|
132
|
-
node['href'] = 'http://foo.bar/ baz'
|
|
133
|
-
|
|
134
|
-
link = Mechanize::Page::Link.new(node, nil, nil)
|
|
135
|
-
|
|
136
|
-
assert_equal 'http://foo.bar/%20baz', link.uri.to_s
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def test_uri_weird_with_fragment
|
|
140
|
-
doc = Nokogiri::HTML::Document.new
|
|
141
|
-
|
|
142
|
-
node = Nokogiri::XML::Node.new('foo', doc)
|
|
143
|
-
node['href'] = 'http://foo.bar/ baz#уважение'
|
|
144
|
-
|
|
145
|
-
link = Mechanize::Page::Link.new(node, nil, nil)
|
|
146
|
-
|
|
147
|
-
assert_equal '%D1%83%D0%B2%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5', link.uri.fragment
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def test_bad_uri_raise_compatible_exception
|
|
151
|
-
doc = Nokogiri::HTML::Document.new
|
|
152
|
-
|
|
153
|
-
node = Nokogiri::XML::Node.new('foo', doc)
|
|
154
|
-
node['href'] = 'http://http:foo.bar/ baz'
|
|
155
|
-
|
|
156
|
-
link = Mechanize::Page::Link.new(node, nil, nil)
|
|
157
|
-
|
|
158
|
-
assert_raises URI::InvalidURIError do
|
|
159
|
-
link.uri
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def test_resolving_full_uri
|
|
164
|
-
page = @mech.get("http://localhost/frame_test.html")
|
|
165
|
-
link = page.link_with(:text => "Form Test")
|
|
166
|
-
|
|
167
|
-
assert_equal "/form_test.html", link.uri.to_s
|
|
168
|
-
assert_equal "http://localhost/form_test.html", link.resolved_uri.to_s
|
|
169
|
-
end unless RUBY_ENGINE == 'jruby' # NekoHTML does not parse body of NOFRAMES
|
|
170
|
-
end
|
|
171
|
-
|
data/test/test_mechanize_page.rb
DELETED
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
require 'mechanize/test_case'
|
|
3
|
-
|
|
4
|
-
class TestMechanizePage < Mechanize::TestCase
|
|
5
|
-
|
|
6
|
-
def setup
|
|
7
|
-
super
|
|
8
|
-
|
|
9
|
-
@uri = URI 'http://example/'
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def test_selector_methods
|
|
13
|
-
page = html_page <<-BODY
|
|
14
|
-
<html>
|
|
15
|
-
<meta>
|
|
16
|
-
<head><title></title>
|
|
17
|
-
<body>
|
|
18
|
-
<span class="name" id="out">Eamonn</span>
|
|
19
|
-
<span>/</span>
|
|
20
|
-
<span class="name" id="bloody">Esther</span>
|
|
21
|
-
<span>/</span>
|
|
22
|
-
<span class="name" id="rageous">Fletcher</span>
|
|
23
|
-
</body>
|
|
24
|
-
</html>
|
|
25
|
-
BODY
|
|
26
|
-
|
|
27
|
-
# at(css_selector), % css_selector
|
|
28
|
-
assert_equal('Eamonn', page.at('#out').text)
|
|
29
|
-
assert_equal('Eamonn', (page % '#out').text)
|
|
30
|
-
|
|
31
|
-
# at(xpath_selector), % xpath_selector
|
|
32
|
-
assert_equal('Esther', page.at('//span[@id="bloody"]').text)
|
|
33
|
-
assert_equal('Esther', (page % '//span[@id="bloody"]').text)
|
|
34
|
-
|
|
35
|
-
# at_css()
|
|
36
|
-
assert_equal('Eamonn', page.at_css('#out').text)
|
|
37
|
-
|
|
38
|
-
# css()
|
|
39
|
-
assert_equal('Fletcher', page.css('.name')[2].text)
|
|
40
|
-
|
|
41
|
-
# at_xpath()
|
|
42
|
-
assert_equal('Esther', page.at_xpath('//span[@id="bloody"]').text)
|
|
43
|
-
|
|
44
|
-
# xpath()
|
|
45
|
-
assert_equal('Fletcher', page.xpath('//*[@class="name"]')[2].text)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def test_initialize_good_content_type
|
|
49
|
-
page = Mechanize::Page.new
|
|
50
|
-
assert_equal('text/html', page.content_type)
|
|
51
|
-
|
|
52
|
-
[
|
|
53
|
-
'text/html',
|
|
54
|
-
'Text/HTML',
|
|
55
|
-
'text/html; charset=UTF-8',
|
|
56
|
-
'text/html ; charset=US-ASCII',
|
|
57
|
-
'application/xhtml+xml',
|
|
58
|
-
'Application/XHTML+XML',
|
|
59
|
-
'application/xhtml+xml; charset=UTF-8',
|
|
60
|
-
'application/xhtml+xml ; charset=US-ASCII',
|
|
61
|
-
].each { |content_type|
|
|
62
|
-
page = Mechanize::Page.new(URI('http://example/'),
|
|
63
|
-
{ 'content-type' => content_type }, 'hello', '200')
|
|
64
|
-
|
|
65
|
-
assert_equal(content_type, page.content_type, content_type)
|
|
66
|
-
}
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def test_initialize_bad_content_type
|
|
70
|
-
[
|
|
71
|
-
'text/xml',
|
|
72
|
-
'text/xhtml',
|
|
73
|
-
'text/htmlfu',
|
|
74
|
-
'footext/html',
|
|
75
|
-
'application/xhtml+xmlfu',
|
|
76
|
-
'fooapplication/xhtml+xml',
|
|
77
|
-
].each { |content_type|
|
|
78
|
-
page = Mechanize::Page.new(URI('http://example/'),
|
|
79
|
-
{ 'content-type' => content_type }, 'hello', '200')
|
|
80
|
-
|
|
81
|
-
assert_equal(content_type, page.content_type, content_type)
|
|
82
|
-
}
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def test_frames
|
|
86
|
-
page = html_page <<-BODY
|
|
87
|
-
<TITLE>A simple frameset document</TITLE>
|
|
88
|
-
<FRAMESET cols="20%, 80%">
|
|
89
|
-
<FRAMESET rows="100, 200">
|
|
90
|
-
<FRAME name="frame1" src="/google.html">
|
|
91
|
-
<FRAME name="frame2" src="/form_test.html">
|
|
92
|
-
</FRAMESET>
|
|
93
|
-
<FRAMESET rows="100, 200">
|
|
94
|
-
<FRAME name="frame3" src="/file_upload.html">
|
|
95
|
-
<IFRAME src="http://google.com/" name="frame4"></IFRAME>
|
|
96
|
-
</FRAMESET>
|
|
97
|
-
</FRAMESET>
|
|
98
|
-
BODY
|
|
99
|
-
|
|
100
|
-
assert_equal 3, page.frames.size
|
|
101
|
-
assert_equal "frame1", page.frames[0].name
|
|
102
|
-
assert_equal "/google.html", page.frames[0].src
|
|
103
|
-
assert_equal "Google", page.frames[0].content.title
|
|
104
|
-
|
|
105
|
-
assert_equal "frame2", page.frames[1].name
|
|
106
|
-
assert_equal "/form_test.html", page.frames[1].src
|
|
107
|
-
assert_equal "Page Title", page.frames[1].content.title
|
|
108
|
-
|
|
109
|
-
assert_equal "frame3", page.frames[2].name
|
|
110
|
-
assert_equal "/file_upload.html", page.frames[2].src
|
|
111
|
-
assert_equal "File Upload Form", page.frames[2].content.title
|
|
112
|
-
|
|
113
|
-
assert_equal %w[/google.html /file_upload.html], page.frames_with(search: '*[name=frame1], *[name=frame3]').map(&:src)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def test_iframes
|
|
117
|
-
page = html_page <<-BODY
|
|
118
|
-
<TITLE>A simple frameset document</TITLE>
|
|
119
|
-
<FRAME name="frame1" src="/google.html">
|
|
120
|
-
<IFRAME src="/file_upload.html" name="frame4">
|
|
121
|
-
</IFRAME>
|
|
122
|
-
BODY
|
|
123
|
-
|
|
124
|
-
assert_equal 1, page.iframes.size
|
|
125
|
-
|
|
126
|
-
assert_equal "frame4", page.iframes.first.name
|
|
127
|
-
assert_equal "/file_upload.html", page.iframes.first.src
|
|
128
|
-
assert_equal "File Upload Form", page.iframes.first.content.title
|
|
129
|
-
end unless RUBY_ENGINE == 'jruby' # NekoHTML does not parse IFRAME
|
|
130
|
-
|
|
131
|
-
def test_image_with
|
|
132
|
-
page = html_page <<-BODY
|
|
133
|
-
<img src="a.jpg">
|
|
134
|
-
<img src="b.jpg">
|
|
135
|
-
<img src="c.png">
|
|
136
|
-
BODY
|
|
137
|
-
|
|
138
|
-
assert_equal "http://example/b.jpg",
|
|
139
|
-
page.image_with(:src => 'b.jpg').url.to_s
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def test_images_with
|
|
143
|
-
page = html_page <<-BODY
|
|
144
|
-
<img src="a.jpg">
|
|
145
|
-
<img src="b.jpg">
|
|
146
|
-
<img src="c.png">
|
|
147
|
-
BODY
|
|
148
|
-
|
|
149
|
-
images = page.images_with(:src => /jpg\Z/).map { |img| img.url.to_s }
|
|
150
|
-
assert_equal %w[http://example/a.jpg http://example/b.jpg], images
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
def test_links
|
|
154
|
-
page = html_page <<-BODY
|
|
155
|
-
<a href="foo.html">
|
|
156
|
-
BODY
|
|
157
|
-
|
|
158
|
-
assert_equal page.links.first.href, "foo.html"
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def test_parser_no_attributes
|
|
162
|
-
page = html_page <<-BODY
|
|
163
|
-
<html>
|
|
164
|
-
<meta>
|
|
165
|
-
<head><title></title>
|
|
166
|
-
<body>
|
|
167
|
-
<a>Hello</a>
|
|
168
|
-
<a><img /></a>
|
|
169
|
-
<form>
|
|
170
|
-
<input />
|
|
171
|
-
<select>
|
|
172
|
-
<option />
|
|
173
|
-
</select>
|
|
174
|
-
<textarea></textarea>
|
|
175
|
-
</form>
|
|
176
|
-
<frame></frame>
|
|
177
|
-
</body>
|
|
178
|
-
</html>
|
|
179
|
-
BODY
|
|
180
|
-
|
|
181
|
-
# HACK weak assertion
|
|
182
|
-
assert_kind_of Nokogiri::HTML::Document, page.root
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
def test_search_links
|
|
186
|
-
page = html_page <<-BODY
|
|
187
|
-
<html>
|
|
188
|
-
<meta>
|
|
189
|
-
<head><title></title>
|
|
190
|
-
<body>
|
|
191
|
-
<span id="spany">
|
|
192
|
-
<a href="b.html">b</a>
|
|
193
|
-
<a href="a.html">a</a>
|
|
194
|
-
</span>
|
|
195
|
-
<a href="6.html">6</a>
|
|
196
|
-
</body>
|
|
197
|
-
</html>
|
|
198
|
-
BODY
|
|
199
|
-
|
|
200
|
-
links = page.links_with(:search => "#spany a")
|
|
201
|
-
|
|
202
|
-
assert_equal 2, links.size
|
|
203
|
-
assert_equal "b.html", links[0].href
|
|
204
|
-
assert_equal "b", links[0].text
|
|
205
|
-
|
|
206
|
-
assert_equal "a.html", links[1].href
|
|
207
|
-
assert_equal "a", links[1].text
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
def test_search_images
|
|
211
|
-
page = html_page <<-BODY
|
|
212
|
-
<html>
|
|
213
|
-
<meta>
|
|
214
|
-
<head><title></title>
|
|
215
|
-
<body>
|
|
216
|
-
<img src="1.jpg" class="unpretty">
|
|
217
|
-
<img src="a.jpg" class="pretty">
|
|
218
|
-
<img src="b.jpg">
|
|
219
|
-
<img src="c.png" class="pretty">
|
|
220
|
-
</body>
|
|
221
|
-
</html>
|
|
222
|
-
BODY
|
|
223
|
-
|
|
224
|
-
{
|
|
225
|
-
:search => "//img[@class='pretty']",
|
|
226
|
-
:xpath => "//img[@class='pretty']",
|
|
227
|
-
:css => "img.pretty",
|
|
228
|
-
:class => "pretty",
|
|
229
|
-
:dom_class => "pretty",
|
|
230
|
-
}.each { |key, expr|
|
|
231
|
-
images = page.images_with(key => expr)
|
|
232
|
-
|
|
233
|
-
message = "selecting with #{key.inspect}"
|
|
234
|
-
|
|
235
|
-
assert_equal 2, images.size
|
|
236
|
-
assert_equal "pretty", images[0].dom_class, message
|
|
237
|
-
assert_equal "a.jpg", images[0].src, message
|
|
238
|
-
|
|
239
|
-
assert_equal "pretty", images[1].dom_class, message
|
|
240
|
-
assert_equal "c.png", images[1].src, message
|
|
241
|
-
}
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
def test_search_bad_selectors
|
|
245
|
-
page = html_page <<-BODY
|
|
246
|
-
<a href="foo.html">foo</a>
|
|
247
|
-
<img src="foo.jpg" />
|
|
248
|
-
BODY
|
|
249
|
-
|
|
250
|
-
assert_empty page.images_with(:search => '//a')
|
|
251
|
-
assert_empty page.links_with(:search => '//img')
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
def test_multiple_titles
|
|
255
|
-
page = html_page <<-BODY
|
|
256
|
-
<!doctype html>
|
|
257
|
-
<html>
|
|
258
|
-
<head>
|
|
259
|
-
<title>HTML>TITLE</title>
|
|
260
|
-
</head>
|
|
261
|
-
<body>
|
|
262
|
-
<svg>
|
|
263
|
-
<title>SVGTITLE</title>
|
|
264
|
-
<metadata id="metadata5">
|
|
265
|
-
<rdf:RDF>
|
|
266
|
-
<cc:Work>
|
|
267
|
-
<dc:title>RDFDCTITLE</dc:title>
|
|
268
|
-
</cc:Work>
|
|
269
|
-
</rdf:RDF>
|
|
270
|
-
</metadata>
|
|
271
|
-
<g></g>
|
|
272
|
-
</svg>
|
|
273
|
-
</body>
|
|
274
|
-
</html>
|
|
275
|
-
BODY
|
|
276
|
-
|
|
277
|
-
assert_equal page.title, "HTML>TITLE"
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
def test_frozen_string_body
|
|
281
|
-
html = (<<~HTML).freeze
|
|
282
|
-
<html>
|
|
283
|
-
<head>
|
|
284
|
-
<title>Page Title</title>
|
|
285
|
-
</head>
|
|
286
|
-
<body>
|
|
287
|
-
<p>Hello World</p>
|
|
288
|
-
</body>
|
|
289
|
-
</html>
|
|
290
|
-
HTML
|
|
291
|
-
|
|
292
|
-
html_page(html) # refute_raises
|
|
293
|
-
end
|
|
294
|
-
end
|
|
295
|
-
|