mechanize 2.7.3 → 2.8.0

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.

Files changed (137) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci-test.yml +45 -0
  3. data/.gitignore +15 -0
  4. data/.yardopts +8 -0
  5. data/{CHANGELOG.rdoc → CHANGELOG.md} +149 -62
  6. data/EXAMPLES.rdoc +2 -25
  7. data/Gemfile +3 -0
  8. data/{LICENSE.rdoc → LICENSE.txt} +4 -0
  9. data/README.md +79 -0
  10. data/Rakefile +36 -37
  11. data/examples/{rubyforge.rb → rubygems.rb} +7 -6
  12. data/lib/mechanize.rb +75 -33
  13. data/lib/mechanize/chunked_termination_error.rb +1 -0
  14. data/lib/mechanize/content_type_error.rb +1 -0
  15. data/lib/mechanize/cookie.rb +1 -13
  16. data/lib/mechanize/cookie_jar.rb +4 -12
  17. data/lib/mechanize/directory_saver.rb +15 -2
  18. data/lib/mechanize/download.rb +2 -1
  19. data/lib/mechanize/element_matcher.rb +29 -14
  20. data/lib/mechanize/element_not_found_error.rb +1 -0
  21. data/lib/mechanize/file.rb +2 -1
  22. data/lib/mechanize/file_connection.rb +5 -3
  23. data/lib/mechanize/file_request.rb +1 -0
  24. data/lib/mechanize/file_response.rb +5 -4
  25. data/lib/mechanize/file_saver.rb +1 -0
  26. data/lib/mechanize/form.rb +119 -46
  27. data/lib/mechanize/form/button.rb +1 -0
  28. data/lib/mechanize/form/check_box.rb +1 -0
  29. data/lib/mechanize/form/field.rb +47 -0
  30. data/lib/mechanize/form/file_upload.rb +1 -0
  31. data/lib/mechanize/form/hidden.rb +1 -0
  32. data/lib/mechanize/form/image_button.rb +1 -0
  33. data/lib/mechanize/form/keygen.rb +1 -0
  34. data/lib/mechanize/form/multi_select_list.rb +8 -14
  35. data/lib/mechanize/form/option.rb +3 -1
  36. data/lib/mechanize/form/radio_button.rb +1 -0
  37. data/lib/mechanize/form/reset.rb +1 -0
  38. data/lib/mechanize/form/select_list.rb +1 -0
  39. data/lib/mechanize/form/submit.rb +1 -0
  40. data/lib/mechanize/form/text.rb +1 -0
  41. data/lib/mechanize/form/textarea.rb +1 -0
  42. data/lib/mechanize/headers.rb +1 -0
  43. data/lib/mechanize/history.rb +2 -1
  44. data/lib/mechanize/http.rb +1 -0
  45. data/lib/mechanize/http/agent.rb +115 -64
  46. data/lib/mechanize/http/auth_challenge.rb +1 -0
  47. data/lib/mechanize/http/auth_realm.rb +2 -1
  48. data/lib/mechanize/http/auth_store.rb +3 -0
  49. data/lib/mechanize/http/content_disposition_parser.rb +18 -3
  50. data/lib/mechanize/http/www_authenticate_parser.rb +5 -5
  51. data/lib/mechanize/image.rb +1 -0
  52. data/lib/mechanize/page.rb +166 -55
  53. data/lib/mechanize/page/base.rb +1 -0
  54. data/lib/mechanize/page/frame.rb +4 -1
  55. data/lib/mechanize/page/image.rb +3 -0
  56. data/lib/mechanize/page/label.rb +1 -0
  57. data/lib/mechanize/page/link.rb +13 -1
  58. data/lib/mechanize/page/meta_refresh.rb +1 -0
  59. data/lib/mechanize/parser.rb +4 -3
  60. data/lib/mechanize/pluggable_parsers.rb +14 -1
  61. data/lib/mechanize/prependable.rb +1 -0
  62. data/lib/mechanize/redirect_limit_reached_error.rb +1 -0
  63. data/lib/mechanize/redirect_not_get_or_head_error.rb +1 -0
  64. data/lib/mechanize/response_code_error.rb +2 -1
  65. data/lib/mechanize/response_read_error.rb +1 -0
  66. data/lib/mechanize/robots_disallowed_error.rb +1 -0
  67. data/lib/mechanize/test_case.rb +39 -29
  68. data/lib/mechanize/test_case/bad_chunking_servlet.rb +1 -0
  69. data/lib/mechanize/test_case/basic_auth_servlet.rb +1 -0
  70. data/lib/mechanize/test_case/content_type_servlet.rb +1 -0
  71. data/lib/mechanize/test_case/digest_auth_servlet.rb +1 -0
  72. data/lib/mechanize/test_case/file_upload_servlet.rb +1 -0
  73. data/lib/mechanize/test_case/form_servlet.rb +1 -0
  74. data/lib/mechanize/test_case/gzip_servlet.rb +4 -3
  75. data/lib/mechanize/test_case/header_servlet.rb +1 -0
  76. data/lib/mechanize/test_case/http_refresh_servlet.rb +2 -2
  77. data/lib/mechanize/test_case/infinite_redirect_servlet.rb +1 -0
  78. data/lib/mechanize/test_case/infinite_refresh_servlet.rb +2 -2
  79. data/lib/mechanize/test_case/many_cookies_as_string_servlet.rb +1 -0
  80. data/lib/mechanize/test_case/many_cookies_servlet.rb +1 -0
  81. data/lib/mechanize/test_case/modified_since_servlet.rb +1 -0
  82. data/lib/mechanize/test_case/ntlm_servlet.rb +1 -0
  83. data/lib/mechanize/test_case/one_cookie_no_spaces_servlet.rb +1 -0
  84. data/lib/mechanize/test_case/one_cookie_servlet.rb +1 -0
  85. data/lib/mechanize/test_case/quoted_value_cookie_servlet.rb +1 -0
  86. data/lib/mechanize/test_case/redirect_servlet.rb +1 -0
  87. data/lib/mechanize/test_case/referer_servlet.rb +1 -0
  88. data/lib/mechanize/test_case/refresh_with_empty_url.rb +1 -0
  89. data/lib/mechanize/test_case/refresh_without_url.rb +1 -0
  90. data/lib/mechanize/test_case/response_code_servlet.rb +1 -0
  91. data/lib/mechanize/test_case/robots_txt_servlet.rb +15 -0
  92. data/lib/mechanize/test_case/send_cookies_servlet.rb +1 -0
  93. data/lib/mechanize/test_case/server.rb +1 -0
  94. data/lib/mechanize/test_case/servlets.rb +4 -0
  95. data/lib/mechanize/test_case/verb_servlet.rb +5 -6
  96. data/lib/mechanize/unauthorized_error.rb +2 -1
  97. data/lib/mechanize/unsupported_scheme_error.rb +5 -2
  98. data/lib/mechanize/util.rb +90 -43
  99. data/lib/mechanize/version.rb +4 -0
  100. data/lib/mechanize/xml_file.rb +1 -0
  101. data/mechanize.gemspec +69 -0
  102. data/test/htdocs/dir with spaces/foo.html +1 -0
  103. data/test/htdocs/find_link.html +1 -4
  104. data/test/htdocs/tc_links.html +1 -1
  105. data/test/test_mechanize.rb +111 -55
  106. data/test/test_mechanize_cookie.rb +75 -60
  107. data/test/test_mechanize_cookie_jar.rb +112 -59
  108. data/test/test_mechanize_download.rb +13 -1
  109. data/test/test_mechanize_file.rb +10 -0
  110. data/test/test_mechanize_file_connection.rb +21 -3
  111. data/test/test_mechanize_file_response.rb +26 -2
  112. data/test/test_mechanize_form.rb +46 -11
  113. data/test/test_mechanize_form_check_box.rb +10 -0
  114. data/test/test_mechanize_form_encoding.rb +3 -8
  115. data/test/test_mechanize_form_keygen.rb +1 -0
  116. data/test/test_mechanize_form_multi_select_list.rb +5 -1
  117. data/test/test_mechanize_http_agent.rb +175 -18
  118. data/test/test_mechanize_http_auth_challenge.rb +14 -0
  119. data/test/test_mechanize_http_auth_realm.rb +7 -1
  120. data/test/test_mechanize_http_auth_store.rb +37 -0
  121. data/test/test_mechanize_http_content_disposition_parser.rb +35 -1
  122. data/test/test_mechanize_http_www_authenticate_parser.rb +24 -0
  123. data/test/test_mechanize_link.rb +60 -4
  124. data/test/test_mechanize_page.rb +82 -7
  125. data/test/test_mechanize_page_encoding.rb +2 -3
  126. data/test/test_mechanize_page_image.rb +1 -1
  127. data/test/test_mechanize_page_link.rb +20 -5
  128. data/test/test_mechanize_page_meta_refresh.rb +1 -1
  129. data/test/test_mechanize_parser.rb +12 -2
  130. data/test/test_mechanize_util.rb +46 -11
  131. metadata +198 -99
  132. data/.gemtest +0 -0
  133. data/.travis.yml +0 -26
  134. data/Manifest.txt +0 -205
  135. data/README.rdoc +0 -83
  136. data/lib/mechanize/monkey_patch.rb +0 -17
  137. data/test/htdocs/robots.txt +0 -2
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::HTTP
2
3
 
3
4
  AuthChallenge = Struct.new :scheme, :params, :raw
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class Mechanize::HTTP::AuthRealm
2
3
 
3
4
  attr_reader :scheme
@@ -7,7 +8,7 @@ class Mechanize::HTTP::AuthRealm
7
8
  def initialize scheme, uri, realm
8
9
  @scheme = scheme
9
10
  @uri = uri
10
- @realm = realm.downcase if realm
11
+ @realm = realm if realm
11
12
  end
12
13
 
13
14
  def == other
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # A credential store for HTTP authentication.
3
4
  #
@@ -93,6 +94,8 @@ only to a particular server you specify.
93
94
  uri = URI uri unless URI === uri
94
95
 
95
96
  uri += '/'
97
+ uri.user = nil
98
+ uri.password = nil
96
99
 
97
100
  realms = @auth_accounts[uri]
98
101
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # coding: BINARY
2
3
 
3
4
  require 'strscan'
@@ -16,6 +17,7 @@ end
16
17
  # * Missing disposition-type
17
18
  # * Multiple semicolons
18
19
  # * Whitespace around semicolons
20
+ # * Dates in ISO 8601 format
19
21
 
20
22
  class Mechanize::HTTP::ContentDispositionParser
21
23
 
@@ -93,7 +95,17 @@ class Mechanize::HTTP::ContentDispositionParser
93
95
  when /^filename$/ then
94
96
  rfc_2045_value
95
97
  when /^(creation|modification|read)-date$/ then
96
- Time.rfc822 rfc_2045_quoted_string
98
+ date = rfc_2045_quoted_string
99
+
100
+ begin
101
+ Time.rfc822 date
102
+ rescue ArgumentError
103
+ begin
104
+ Time.iso8601 date
105
+ rescue ArgumentError
106
+ nil
107
+ end
108
+ end
97
109
  when /^size$/ then
98
110
  rfc_2045_value.to_i(10)
99
111
  else
@@ -125,7 +137,7 @@ class Mechanize::HTTP::ContentDispositionParser
125
137
  def rfc_2045_quoted_string
126
138
  return nil unless @scanner.scan(/"/)
127
139
 
128
- text = ''
140
+ text = String.new
129
141
 
130
142
  while true do
131
143
  chunk = @scanner.scan(/[\000-\014\016-\041\043-\133\135-\177]+/) # not \r "
@@ -141,7 +153,10 @@ class Mechanize::HTTP::ContentDispositionParser
141
153
  text << " "
142
154
  end
143
155
  else
144
- if '"' == @scanner.peek(1) then
156
+ if '\\"' == @scanner.peek(2) then
157
+ @scanner.skip(/\\/)
158
+ text << @scanner.get_byte
159
+ elsif '"' == @scanner.peek(1) then
145
160
  @scanner.get_byte
146
161
  break
147
162
  else
@@ -1,4 +1,4 @@
1
- # coding: BINARY
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'strscan'
4
4
 
@@ -34,7 +34,7 @@ class Mechanize::HTTP::WWWAuthenticateParser
34
34
  scan_comma_spaces
35
35
  end
36
36
 
37
- next unless scheme
37
+ break unless scheme
38
38
  challenge.scheme = scheme
39
39
 
40
40
  space = spaces
@@ -128,7 +128,7 @@ class Mechanize::HTTP::WWWAuthenticateParser
128
128
 
129
129
  def auth_param
130
130
  return nil unless name = token
131
- return nil unless @scanner.scan(/=/)
131
+ return nil unless @scanner.scan(/ *= */)
132
132
 
133
133
  value = if @scanner.peek(1) == '"' then
134
134
  quoted_string
@@ -151,10 +151,10 @@ class Mechanize::HTTP::WWWAuthenticateParser
151
151
  def quoted_string
152
152
  return nil unless @scanner.scan(/"/)
153
153
 
154
- text = ''
154
+ text = String.new
155
155
 
156
156
  while true do
157
- chunk = @scanner.scan(/[\r\n \t\041\043-\176\200-\377]+/) # not "
157
+ chunk = @scanner.scan(/[\r\n \t\x21\x23-\x7e\u0080-\u00ff]+/) # not " which is \x22
158
158
 
159
159
  if chunk then
160
160
  text << chunk
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # An Image holds downloaded data for an image/* response.
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  ##
2
3
  # This class encapsulates an HTML page. If Mechanize finds a content
3
4
  # type of 'text/html', this class will be instantiated and returned.
@@ -42,7 +43,7 @@ class Mechanize::Page < Mechanize::File
42
43
  if body
43
44
  # Force the encoding to be 8BIT so we can perform regular expressions.
44
45
  # We'll set it to the detected encoding later
45
- body.force_encoding 'ASCII-8BIT' if body.respond_to? :force_encoding
46
+ body.force_encoding(Encoding::ASCII_8BIT)
46
47
 
47
48
  @encodings.concat self.class.meta_charset body
48
49
 
@@ -58,7 +59,7 @@ class Mechanize::Page < Mechanize::File
58
59
  def title
59
60
  @title ||=
60
61
  if doc = parser
61
- title = doc.search('title').inner_text
62
+ title = doc.xpath('string(((/html/head | /html | /head | /)/title)[1])').to_s
62
63
  title.empty? ? nil : title
63
64
  end
64
65
  end
@@ -92,7 +93,9 @@ class Mechanize::Page < Mechanize::File
92
93
  end
93
94
 
94
95
  def encoding
95
- parser.respond_to?(:encoding) ? parser.encoding : nil
96
+ parser.encoding
97
+ rescue NoMethodError
98
+ nil
96
99
  end
97
100
 
98
101
  # Return whether parser result has errors related to encoding or not.
@@ -109,15 +112,17 @@ class Mechanize::Page < Mechanize::File
109
112
 
110
113
  def parser
111
114
  return @parser if @parser
112
- return nil unless @body
115
+ return unless @body
116
+
117
+ url = @uri && @uri.to_s
113
118
 
114
- if @encoding then
115
- @parser = @mech.html_parser.parse html_body, nil, @encoding
116
- elsif mech.force_default_encoding then
117
- @parser = @mech.html_parser.parse html_body, nil, @mech.default_encoding
119
+ if @encoding
120
+ @parser = mech.html_parser.parse html_body, url, @encoding
121
+ elsif mech.force_default_encoding
122
+ @parser = mech.html_parser.parse html_body, url, @mech.default_encoding
118
123
  else
119
124
  @encodings.reverse_each do |encoding|
120
- @parser = @mech.html_parser.parse html_body, nil, encoding
125
+ @parser = mech.html_parser.parse html_body, url, encoding
121
126
 
122
127
  break unless encoding_error? @parser
123
128
  end
@@ -192,39 +197,71 @@ class Mechanize::Page < Mechanize::File
192
197
  ##
193
198
  # :method: search
194
199
  #
195
- # Search for +paths+ in the page using Nokogiri's #search. The +paths+ can
196
- # be XPath or CSS and an optional Hash of namespaces may be appended.
200
+ # Shorthand for +parser.search+.
197
201
  #
198
- # See Nokogiri::XML::Node#search for further details.
202
+ # See Nokogiri::XML::Node#search for details.
199
203
 
200
- def_delegator :parser, :search, :search
204
+ ##
205
+ # :method: css
206
+ #
207
+ # Shorthand for +parser.css+.
208
+ #
209
+ # See also Nokogiri::XML::Node#css for details.
201
210
 
202
- alias / search
211
+ ##
212
+ # :method: xpath
213
+ #
214
+ # Shorthand for +parser.xpath+.
215
+ #
216
+ # See also Nokogiri::XML::Node#xpath for details.
203
217
 
204
218
  ##
205
219
  # :method: at
206
220
  #
207
- # Search through the page for +path+ under +namespace+ using Nokogiri's #at.
208
- # The +path+ may be either a CSS or XPath expression.
221
+ # Shorthand for +parser.at+.
222
+ #
223
+ # See also Nokogiri::XML::Node#at for details.
224
+
225
+ ##
226
+ # :method: at_css
227
+ #
228
+ # Shorthand for +parser.at_css+.
229
+ #
230
+ # See also Nokogiri::XML::Node#at_css for details.
231
+
232
+ ##
233
+ # :method: at_xpath
209
234
  #
210
- # See also Nokogiri::XML::Node#at
235
+ # Shorthand for +parser.at_xpath+.
236
+ #
237
+ # See also Nokogiri::XML::Node#at_xpath for details.
211
238
 
212
- def_delegator :parser, :at, :at
239
+ def_delegators :parser, :search, :css, :xpath, :at, :at_css, :at_xpath
240
+
241
+ alias / search
242
+ alias % at
213
243
 
214
244
  ##
215
245
  # :method: form_with
216
246
  #
217
247
  # :call-seq:
218
248
  # form_with(criteria)
249
+ # form_with(criteria) { |form| ... }
219
250
  #
220
- # Find a single form matching +criteria+.
221
- # Example:
222
- # page.form_with(:action => '/post/login.php') do |f|
251
+ # Find a single form matching +criteria+. See +forms_with+ for
252
+ # details of +criteria+.
253
+ #
254
+ # Examples:
255
+ # page.form_with(action: '/post/login.php') do |f|
223
256
  # ...
224
257
  # end
225
258
 
226
259
  ##
227
- # :mehtod: form_with!(criteria)
260
+ # :method: form_with!(criteria)
261
+ #
262
+ # :call-seq:
263
+ # form_with!(criteria)
264
+ # form_with!(criteria) { |form| ... }
228
265
  #
229
266
  # Same as +form_with+ but raises an ElementNotFoundError if no button matches
230
267
  # +criteria+
@@ -232,11 +269,35 @@ class Mechanize::Page < Mechanize::File
232
269
  ##
233
270
  # :method: forms_with
234
271
  #
235
- # :call-seq: forms_with(criteria)
272
+ # :call-seq:
273
+ # forms_with(name)
274
+ # forms_with(name: name_matcher, id: id_matcher, class: class_matcher,
275
+ # search: search_expression, xpath: xpath_expression, css: css_expression,
276
+ # action: action_matcher, ...)
277
+ #
278
+ # Find all forms form matching criteria. If a string is given, it
279
+ # is taken as a name attribute value. If a hash is given, forms
280
+ # are narrowed by the key-value pairs as follows.
281
+ #
282
+ # :id, :dom_id: selects forms with a #dom_id value that matches this
283
+ # value.
284
+ #
285
+ # :class, :dom_class: selects forms with a #dom_class value that
286
+ # matches this value. Note that class attribute values are compared
287
+ # literally as string, so forms_with(class: "a") does not match a
288
+ # form with class="a b". Use forms_with(css: "form.a") instead.
289
+ #
290
+ # :search: only selects forms matching this selector expression.
291
+ #
292
+ # :xpath: only selects forms matching this XPath expression.
293
+ #
294
+ # :css: only selects forms matching this CSS selector expression.
295
+ #
296
+ # :action, :method, etc.: narrows forms by a given attribute value
297
+ # using the === operator.
236
298
  #
237
- # Find all forms form matching +criteria+.
238
299
  # Example:
239
- # page.forms_with(:action => '/post/login.php').each do |f|
300
+ # page.forms_with(css: '#content table.login_box form', method: /\APOST\z/i, ).each do |f|
240
301
  # ...
241
302
  # end
242
303
 
@@ -245,14 +306,22 @@ class Mechanize::Page < Mechanize::File
245
306
  ##
246
307
  # :method: link_with
247
308
  #
248
- # :call-seq: link_with(criteria)
309
+ # :call-seq:
310
+ # link_with(criteria)
311
+ # link_with(criteria) { |link| ... }
312
+ #
313
+ # Find a single link matching +criteria+. See +forms_with+ for
314
+ # details of +criteria+, where for "form(s)" read "link(s)".
249
315
  #
250
- # Find a single link matching +criteria+.
251
316
  # Example:
252
- # page.link_with(:href => /foo/).click
317
+ # page.link_with(href: /foo/).click
253
318
 
254
319
  ##
255
- # :mehtod: link_with!(criteria)
320
+ # :method: link_with!
321
+ #
322
+ # :call-seq:
323
+ # link_with!(criteria)
324
+ # link_with!(criteria) { |link| ... }
256
325
  #
257
326
  # Same as +link_with+ but raises an ElementNotFoundError if no button matches
258
327
  # +criteria+
@@ -263,9 +332,11 @@ class Mechanize::Page < Mechanize::File
263
332
  # :call-seq:
264
333
  # links_with(criteria)
265
334
  #
266
- # Find all links matching +criteria+.
335
+ # Find all links matching +criteria+. See +forms_with+ for details
336
+ # of +criteria+, where for "form(s)" read "link(s)".
337
+ #
267
338
  # Example:
268
- # page.links_with(:href => /foo/).each do |link|
339
+ # page.links_with(href: /foo/).each do |link|
269
340
  # puts link.href
270
341
  # end
271
342
 
@@ -274,14 +345,22 @@ class Mechanize::Page < Mechanize::File
274
345
  ##
275
346
  # :method: base_with
276
347
  #
277
- # :call-seq: base_with(criteria)
348
+ # :call-seq:
349
+ # base_with(criteria)
350
+ # base_with(criteria) { |base| ... }
351
+ #
352
+ # Find a single base tag matching +criteria+. See +forms_with+ for
353
+ # details of +criteria+, where for "form(s)" read "base tag(s)".
278
354
  #
279
- # Find a single base tag matching +criteria+.
280
355
  # Example:
281
- # page.base_with(:href => /foo/).click
356
+ # page.base_with(href: /foo/).click
282
357
 
283
358
  ##
284
- # :mehtod: base_with!(criteria)
359
+ # :method: base_with!(criteria)
360
+ #
361
+ # :call-seq:
362
+ # base_with!(criteria)
363
+ # base_with!(criteria) { |base| ... }
285
364
  #
286
365
  # Same as +base_with+ but raises an ElementNotFoundError if no button matches
287
366
  # +criteria+
@@ -291,9 +370,11 @@ class Mechanize::Page < Mechanize::File
291
370
  #
292
371
  # :call-seq: bases_with(criteria)
293
372
  #
294
- # Find all base tags matching +criteria+.
373
+ # Find all base tags matching +criteria+. See +forms_with+ for
374
+ # details of +criteria+, where for "form(s)" read "base tag(s)".
375
+ #
295
376
  # Example:
296
- # page.bases_with(:href => /foo/).each do |base|
377
+ # page.bases_with(href: /foo/).each do |base|
297
378
  # puts base.href
298
379
  # end
299
380
 
@@ -302,14 +383,22 @@ class Mechanize::Page < Mechanize::File
302
383
  ##
303
384
  # :method: frame_with
304
385
  #
305
- # :call-seq: frame_with(criteria)
386
+ # :call-seq:
387
+ # frame_with(criteria)
388
+ # frame_with(criteria) { |frame| ... }
389
+ #
390
+ # Find a single frame tag matching +criteria+. See +forms_with+ for
391
+ # details of +criteria+, where for "form(s)" read "frame tag(s)".
306
392
  #
307
- # Find a single frame tag matching +criteria+.
308
393
  # Example:
309
- # page.frame_with(:src => /foo/).click
394
+ # page.frame_with(src: /foo/).click
310
395
 
311
396
  ##
312
- # :mehtod: frame_with!(criteria)
397
+ # :method: frame_with!
398
+ #
399
+ # :call-seq:
400
+ # frame_with!(criteria)
401
+ # frame_with!(criteria) { |frame| ... }
313
402
  #
314
403
  # Same as +frame_with+ but raises an ElementNotFoundError if no button matches
315
404
  # +criteria+
@@ -319,9 +408,11 @@ class Mechanize::Page < Mechanize::File
319
408
  #
320
409
  # :call-seq: frames_with(criteria)
321
410
  #
322
- # Find all frame tags matching +criteria+.
411
+ # Find all frame tags matching +criteria+. See +forms_with+ for
412
+ # details of +criteria+, where for "form(s)" read "frame tag(s)".
413
+ #
323
414
  # Example:
324
- # page.frames_with(:src => /foo/).each do |frame|
415
+ # page.frames_with(src: /foo/).each do |frame|
325
416
  # p frame.src
326
417
  # end
327
418
 
@@ -330,14 +421,22 @@ class Mechanize::Page < Mechanize::File
330
421
  ##
331
422
  # :method: iframe_with
332
423
  #
333
- # :call-seq: iframe_with(criteria)
424
+ # :call-seq:
425
+ # iframe_with(criteria)
426
+ # iframe_with(criteria) { |iframe| ... }
427
+ #
428
+ # Find a single iframe tag matching +criteria+. See +forms_with+ for
429
+ # details of +criteria+, where for "form(s)" read "iframe tag(s)".
334
430
  #
335
- # Find a single iframe tag matching +criteria+.
336
431
  # Example:
337
- # page.iframe_with(:src => /foo/).click
432
+ # page.iframe_with(src: /foo/).click
338
433
 
339
434
  ##
340
- # :mehtod: iframe_with!(criteria)
435
+ # :method: iframe_with!
436
+ #
437
+ # :call-seq:
438
+ # iframe_with!(criteria)
439
+ # iframe_with!(criteria) { |iframe| ... }
341
440
  #
342
441
  # Same as +iframe_with+ but raises an ElementNotFoundError if no button
343
442
  # matches +criteria+
@@ -347,9 +446,11 @@ class Mechanize::Page < Mechanize::File
347
446
  #
348
447
  # :call-seq: iframes_with(criteria)
349
448
  #
350
- # Find all iframe tags matching +criteria+.
449
+ # Find all iframe tags matching +criteria+. See +forms_with+ for
450
+ # details of +criteria+, where for "form(s)" read "iframe tag(s)".
451
+ #
351
452
  # Example:
352
- # page.iframes_with(:src => /foo/).each do |iframe|
453
+ # page.iframes_with(src: /foo/).each do |iframe|
353
454
  # p iframe.src
354
455
  # end
355
456
 
@@ -358,14 +459,22 @@ class Mechanize::Page < Mechanize::File
358
459
  ##
359
460
  # :method: image_with
360
461
  #
361
- # :call-seq: image_with(criteria)
462
+ # :call-seq:
463
+ # image_with(criteria)
464
+ # image_with(criteria) { |image| ... }
465
+ #
466
+ # Find a single image matching +criteria+. See +forms_with+ for
467
+ # details of +criteria+, where for "form(s)" read "image(s)".
362
468
  #
363
- # Find a single image matching +criteria+.
364
469
  # Example:
365
- # page.image_with(:alt => /main/).fetch.save
470
+ # page.image_with(alt: /main/).fetch.save
366
471
 
367
472
  ##
368
- # :mehtod: image_with!(criteria)
473
+ # :method: image_with!
474
+ #
475
+ # :call-seq:
476
+ # image_with!(criteria)
477
+ # image_with!(criteria) { |image| ... }
369
478
  #
370
479
  # Same as +image_with+ but raises an ElementNotFoundError if no button matches
371
480
  # +criteria+
@@ -375,9 +484,11 @@ class Mechanize::Page < Mechanize::File
375
484
  #
376
485
  # :call-seq: images_with(criteria)
377
486
  #
378
- # Find all images matching +criteria+.
487
+ # Find all images matching +criteria+. See +forms_with+ for
488
+ # details of +criteria+, where for "form(s)" read "image(s)".
489
+ #
379
490
  # Example:
380
- # page.images_with(:src => /jpg\Z/).each do |img|
491
+ # page.images_with(src: /jpg\Z/).each do |img|
381
492
  # img.fetch.save
382
493
  # end
383
494