mechanize 2.14.1 → 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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -1
  3. data/lib/mechanize/directory_saver.rb +2 -1
  4. data/lib/mechanize/file_saver.rb +2 -0
  5. data/lib/mechanize/parser.rb +33 -3
  6. data/lib/mechanize/test_case.rb +2 -9
  7. data/lib/mechanize/version.rb +1 -1
  8. metadata +3 -172
  9. data/.autotest +0 -6
  10. data/.github/dependabot.yml +0 -11
  11. data/.github/workflows/ci.yml +0 -43
  12. data/.github/workflows/upstream.yml +0 -51
  13. data/.gitignore +0 -15
  14. data/.yardopts +0 -8
  15. data/Gemfile +0 -12
  16. data/Rakefile +0 -56
  17. data/examples/flickr_upload.rb +0 -22
  18. data/examples/latest_user_agents.rb +0 -100
  19. data/examples/mech-dump.rb +0 -5
  20. data/examples/proxy_req.rb +0 -7
  21. data/examples/rubygems.rb +0 -23
  22. data/examples/spider.rb +0 -22
  23. data/examples/wikipedia_links_to_philosophy.rb +0 -158
  24. data/mechanize.gemspec +0 -74
  25. data/test/data/htpasswd +0 -1
  26. data/test/data/server.crt +0 -16
  27. data/test/data/server.csr +0 -12
  28. data/test/data/server.key +0 -15
  29. data/test/data/server.pem +0 -15
  30. data/test/test_mechanize.rb +0 -1382
  31. data/test/test_mechanize_cookie.rb +0 -559
  32. data/test/test_mechanize_cookie_jar.rb +0 -615
  33. data/test/test_mechanize_directory_saver.rb +0 -60
  34. data/test/test_mechanize_download.rb +0 -102
  35. data/test/test_mechanize_element_not_found_error.rb +0 -16
  36. data/test/test_mechanize_file.rb +0 -118
  37. data/test/test_mechanize_file_connection.rb +0 -40
  38. data/test/test_mechanize_file_request.rb +0 -26
  39. data/test/test_mechanize_file_response.rb +0 -48
  40. data/test/test_mechanize_file_saver.rb +0 -22
  41. data/test/test_mechanize_form.rb +0 -1025
  42. data/test/test_mechanize_form_check_box.rb +0 -49
  43. data/test/test_mechanize_form_encoding.rb +0 -110
  44. data/test/test_mechanize_form_field.rb +0 -78
  45. data/test/test_mechanize_form_file_upload.rb +0 -21
  46. data/test/test_mechanize_form_image_button.rb +0 -13
  47. data/test/test_mechanize_form_keygen.rb +0 -34
  48. data/test/test_mechanize_form_multi_select_list.rb +0 -98
  49. data/test/test_mechanize_form_option.rb +0 -60
  50. data/test/test_mechanize_form_radio_button.rb +0 -96
  51. data/test/test_mechanize_form_select_list.rb +0 -81
  52. data/test/test_mechanize_form_textarea.rb +0 -53
  53. data/test/test_mechanize_headers.rb +0 -36
  54. data/test/test_mechanize_history.rb +0 -104
  55. data/test/test_mechanize_http_agent.rb +0 -2145
  56. data/test/test_mechanize_http_auth_challenge.rb +0 -64
  57. data/test/test_mechanize_http_auth_realm.rb +0 -56
  58. data/test/test_mechanize_http_auth_store.rb +0 -233
  59. data/test/test_mechanize_http_content_disposition_parser.rb +0 -167
  60. data/test/test_mechanize_http_www_authenticate_parser.rb +0 -204
  61. data/test/test_mechanize_image.rb +0 -9
  62. data/test/test_mechanize_link.rb +0 -171
  63. data/test/test_mechanize_page.rb +0 -295
  64. data/test/test_mechanize_page_encoding.rb +0 -215
  65. data/test/test_mechanize_page_frame.rb +0 -17
  66. data/test/test_mechanize_page_image.rb +0 -191
  67. data/test/test_mechanize_page_link.rb +0 -377
  68. data/test/test_mechanize_page_meta_refresh.rb +0 -151
  69. data/test/test_mechanize_parser.rb +0 -316
  70. data/test/test_mechanize_pluggable_parser.rb +0 -68
  71. data/test/test_mechanize_redirect_limit_reached_error.rb +0 -25
  72. data/test/test_mechanize_redirect_not_get_or_head_error.rb +0 -15
  73. data/test/test_mechanize_response_read_error.rb +0 -29
  74. data/test/test_mechanize_subclass.rb +0 -23
  75. data/test/test_mechanize_util.rb +0 -144
  76. data/test/test_mechanize_xml_file.rb +0 -30
  77. 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
-
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'mechanize/test_case'
3
-
4
- class TestMechanizeImage < Mechanize::TestCase
5
-
6
- # empty subclass, no tests
7
-
8
- end
9
-
@@ -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
-
@@ -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&gt;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
-