webrat 0.5.3 → 0.6.0

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 (87) hide show
  1. data/.gitignore +4 -1
  2. data/Gemfile +19 -0
  3. data/History.txt +29 -0
  4. data/Rakefile +27 -63
  5. data/Thorfile +117 -0
  6. data/lib/webrat.rb +11 -3
  7. data/lib/webrat/{mechanize.rb → adapters/mechanize.rb} +0 -0
  8. data/lib/webrat/adapters/merb.rb +11 -0
  9. data/lib/webrat/{rack.rb → adapters/rack.rb} +0 -0
  10. data/lib/webrat/{rails.rb → adapters/rails.rb} +2 -23
  11. data/lib/webrat/{sinatra.rb → adapters/sinatra.rb} +0 -2
  12. data/lib/webrat/core.rb +0 -1
  13. data/lib/webrat/core/configuration.rb +6 -16
  14. data/lib/webrat/core/elements/area.rb +2 -2
  15. data/lib/webrat/core/elements/element.rb +3 -3
  16. data/lib/webrat/core/elements/field.rb +106 -30
  17. data/lib/webrat/core/elements/form.rb +4 -4
  18. data/lib/webrat/core/elements/label.rb +4 -4
  19. data/lib/webrat/core/elements/link.rb +6 -6
  20. data/lib/webrat/core/elements/select_option.rb +15 -2
  21. data/lib/webrat/core/locators.rb +1 -1
  22. data/lib/webrat/core/locators/area_locator.rb +3 -3
  23. data/lib/webrat/core/locators/button_locator.rb +6 -6
  24. data/lib/webrat/core/locators/field_by_id_locator.rb +3 -3
  25. data/lib/webrat/core/locators/field_labeled_locator.rb +2 -2
  26. data/lib/webrat/core/locators/field_named_locator.rb +3 -3
  27. data/lib/webrat/core/locators/form_locator.rb +1 -1
  28. data/lib/webrat/core/locators/label_locator.rb +2 -2
  29. data/lib/webrat/core/locators/link_locator.rb +7 -7
  30. data/lib/webrat/core/locators/select_option_locator.rb +5 -5
  31. data/lib/webrat/core/logging.rb +4 -5
  32. data/lib/webrat/core/matchers/have_content.rb +2 -7
  33. data/lib/webrat/core/matchers/have_xpath.rb +3 -28
  34. data/lib/webrat/core/methods.rb +1 -0
  35. data/lib/webrat/core/scope.rb +17 -2
  36. data/lib/webrat/core/session.rb +2 -1
  37. data/lib/webrat/core/xml.rb +41 -84
  38. data/lib/webrat/integrations/merb.rb +10 -0
  39. data/lib/webrat/integrations/rails.rb +25 -0
  40. data/lib/webrat/integrations/rspec-rails.rb +11 -0
  41. data/lib/webrat/integrations/selenium.rb +11 -0
  42. data/lib/webrat/rspec-rails.rb +2 -10
  43. data/lib/webrat/selenium.rb +0 -10
  44. data/lib/webrat/selenium/application_servers.rb +1 -1
  45. data/lib/webrat/selenium/application_servers/external.rb +1 -1
  46. data/lib/webrat/selenium/location_strategy_javascript/label.js +29 -3
  47. data/lib/webrat/selenium/location_strategy_javascript/webrat.js +1 -0
  48. data/lib/webrat/selenium/location_strategy_javascript/webratlink.js +24 -4
  49. data/lib/webrat/selenium/selenium_rc_server.rb +2 -2
  50. data/lib/webrat/selenium/selenium_session.rb +21 -2
  51. data/lib/webrat/selenium/silence_stream.rb +1 -1
  52. data/spec/integration/mechanize/spec/spec_helper.rb +3 -1
  53. data/spec/integration/rails/app/controllers/{application.rb → application_controller.rb} +0 -0
  54. data/spec/integration/rails/app/controllers/webrat_controller.rb +3 -0
  55. data/spec/integration/rails/app/views/buttons/show.html.erb +0 -2
  56. data/spec/integration/rails/app/views/webrat/buttons.html.erb +0 -2
  57. data/spec/integration/rails/app/views/webrat/within.html.erb +3 -0
  58. data/spec/integration/rails/config/environment.rb +1 -1
  59. data/spec/integration/rails/config/routes.rb +1 -0
  60. data/spec/integration/rails/test/integration/button_click_test.rb +12 -26
  61. data/spec/integration/rails/test/integration/fill_in_test.rb +1 -1
  62. data/spec/integration/rails/test/integration/link_click_test.rb +1 -1
  63. data/spec/integration/rails/test/integration/webrat_test.rb +35 -9
  64. data/spec/integration/rails/test/test_helper.rb +1 -0
  65. data/spec/private/core/configuration_spec.rb +2 -31
  66. data/spec/private/core/field_spec.rb +14 -16
  67. data/spec/private/mechanize/mechanize_adapter_spec.rb +0 -2
  68. data/spec/private/nokogiri_spec.rb +2 -2
  69. data/spec/private/rails/rails_adapter_spec.rb +0 -27
  70. data/spec/public/basic_auth_spec.rb +13 -2
  71. data/spec/public/click_button_spec.rb +10 -12
  72. data/spec/public/click_link_spec.rb +21 -0
  73. data/spec/public/fill_in_spec.rb +15 -0
  74. data/spec/public/matchers/have_selector_spec.rb +4 -0
  75. data/spec/public/select_spec.rb +232 -26
  76. data/spec/spec_helper.rb +2 -0
  77. data/webrat.gemspec +305 -313
  78. metadata +21 -25
  79. data/VERSION +0 -1
  80. data/lib/webrat/core/xml/hpricot.rb +0 -19
  81. data/lib/webrat/core/xml/nokogiri.rb +0 -76
  82. data/lib/webrat/core/xml/rexml.rb +0 -24
  83. data/lib/webrat/merb_adapter.rb +0 -82
  84. data/lib/webrat/merb_multipart_support.rb +0 -27
  85. data/spec/private/core/logging_spec.rb +0 -10
  86. data/spec/private/merb/attaches_file_spec.rb +0 -93
  87. data/spec/private/merb/merb_adapter_spec.rb +0 -61
@@ -3,14 +3,14 @@ module Webrat
3
3
  class Element # :nodoc:
4
4
 
5
5
  def self.load_all(session, dom)
6
- Webrat::XML.xpath_search(dom, xpath_search).map do |element|
6
+ dom.xpath(*xpath_search).map do |element|
7
7
  load(session, element)
8
8
  end
9
9
  end
10
10
 
11
11
  def self.load(session, element)
12
12
  return nil if element.nil?
13
- session.elements[Webrat::XML.xpath_to(element)] ||= self.new(session, element)
13
+ session.elements[element.path] ||= self.new(session, element)
14
14
  end
15
15
 
16
16
  attr_reader :element
@@ -21,7 +21,7 @@ module Webrat
21
21
  end
22
22
 
23
23
  def path
24
- Webrat::XML.xpath_to(@element)
24
+ @element.path
25
25
  end
26
26
 
27
27
  def inspect
@@ -32,16 +32,21 @@ module Webrat
32
32
 
33
33
  def self.load(session, element)
34
34
  return nil if element.nil?
35
- session.elements[Webrat::XML.xpath_to(element)] ||= field_class(element).new(session, element)
35
+ session.elements[element.path] ||= field_class(element).new(session, element)
36
36
  end
37
37
 
38
38
  def self.field_class(element)
39
39
  case element.name
40
40
  when "button" then ButtonField
41
- when "select" then SelectField
41
+ when "select"
42
+ if element.attributes["multiple"].nil?
43
+ SelectField
44
+ else
45
+ MultipleSelectField
46
+ end
42
47
  when "textarea" then TextareaField
43
48
  else
44
- case Webrat::XML.attribute(element, "type")
49
+ case element["type"]
45
50
  when "checkbox" then CheckboxField
46
51
  when "hidden" then HiddenField
47
52
  when "radio" then RadioField
@@ -67,11 +72,11 @@ module Webrat
67
72
  end
68
73
 
69
74
  def id
70
- Webrat::XML.attribute(@element, "id")
75
+ @element["id"]
71
76
  end
72
77
 
73
78
  def disabled?
74
- @element.attributes.has_key?("disabled") && Webrat::XML.attribute(@element, "disabled") != 'false'
79
+ @element.attributes.has_key?("disabled") && @element["disabled"] != 'false'
75
80
  end
76
81
 
77
82
  def raise_error_if_disabled
@@ -82,14 +87,16 @@ module Webrat
82
87
  def to_param
83
88
  return nil if disabled?
84
89
 
85
- case Webrat.configuration.mode
90
+ params = case Webrat.configuration.mode
86
91
  when :rails
87
92
  parse_rails_request_params("#{name}=#{escaped_value}")
88
93
  when :merb
89
94
  ::Merb::Parse.query("#{name}=#{escaped_value}")
90
95
  else
91
- { name => value }
96
+ { name => [*@value].first.to_s }
92
97
  end
98
+
99
+ unescape_params(params)
93
100
  end
94
101
 
95
102
  def set(value)
@@ -128,11 +135,26 @@ module Webrat
128
135
  end
129
136
 
130
137
  def name
131
- Webrat::XML.attribute(@element, "name")
138
+ @element["name"]
132
139
  end
133
140
 
134
141
  def escaped_value
135
- CGI.escape([*@value].first.to_s)
142
+ CGI.escape(@value.to_s)
143
+ end
144
+
145
+ # Because we have to escape it before sending it to the above case statement,
146
+ # we have to make sure we unescape each value when it gets back so assertions
147
+ # involving characters like <, >, and & work as expected
148
+ def unescape_params(params)
149
+ case params.class.name
150
+ when 'Hash', 'Mash'
151
+ params.each { |key,value| params[key] = unescape_params(value) }
152
+ params
153
+ when 'Array'
154
+ params.collect { |value| unescape_params(value) }
155
+ else
156
+ CGI.unescapeHTML(params)
157
+ end
136
158
  end
137
159
 
138
160
  def labels
@@ -155,14 +177,14 @@ module Webrat
155
177
  end
156
178
 
157
179
  unless id.blank?
158
- @label_elements += Webrat::XML.xpath_search(form.element, ".//label[@for = '#{id}']")
180
+ @label_elements += form.element.xpath(".//label[@for = '#{id}']")
159
181
  end
160
182
 
161
183
  @label_elements
162
184
  end
163
185
 
164
186
  def default_value
165
- Webrat::XML.attribute(@element, "value")
187
+ @element["value"]
166
188
  end
167
189
 
168
190
  def replace_param_value(params, oval, nval)
@@ -199,7 +221,7 @@ module Webrat
199
221
 
200
222
  def click
201
223
  raise_error_if_disabled
202
- set(Webrat::XML.attribute(@element, "value")) unless Webrat::XML.attribute(@element, "name").blank?
224
+ set(@element["value"]) unless @element["name"].blank?
203
225
  form.submit
204
226
  end
205
227
 
@@ -246,11 +268,11 @@ module Webrat
246
268
 
247
269
  def check
248
270
  raise_error_if_disabled
249
- set(Webrat::XML.attribute(@element, "value") || "on")
271
+ set(@element["value"] || "on")
250
272
  end
251
273
 
252
274
  def checked?
253
- Webrat::XML.attribute(@element, "checked") == "checked"
275
+ @element["checked"] == "checked"
254
276
  end
255
277
 
256
278
  def uncheck
@@ -261,8 +283,8 @@ module Webrat
261
283
  protected
262
284
 
263
285
  def default_value
264
- if Webrat::XML.attribute(@element, "checked") == "checked"
265
- Webrat::XML.attribute(@element, "value") || "on"
286
+ if @element["checked"] == "checked"
287
+ @element["value"] || "on"
266
288
  else
267
289
  nil
268
290
  end
@@ -295,11 +317,11 @@ module Webrat
295
317
  option.set(nil)
296
318
  end
297
319
 
298
- set(Webrat::XML.attribute(@element, "value") || "on")
320
+ set(@element["value"] || "on")
299
321
  end
300
322
 
301
323
  def checked?
302
- Webrat::XML.attribute(@element, "checked") == "checked"
324
+ @element["checked"] == "checked"
303
325
  end
304
326
 
305
327
  protected
@@ -309,8 +331,8 @@ module Webrat
309
331
  end
310
332
 
311
333
  def default_value
312
- if Webrat::XML.attribute(@element, "checked") == "checked"
313
- Webrat::XML.attribute(@element, "value") || "on"
334
+ if @element["checked"] == "checked"
335
+ @element["value"] || "on"
314
336
  else
315
337
  nil
316
338
  end
@@ -327,7 +349,7 @@ module Webrat
327
349
  protected
328
350
 
329
351
  def default_value
330
- Webrat::XML.inner_html(@element)
352
+ @element.inner_html
331
353
  end
332
354
 
333
355
  end
@@ -363,10 +385,7 @@ module Webrat
363
385
  else
364
386
  ActionController::TestUploadedFile.new(@value)
365
387
  end
366
- when :merb
367
- # TODO: support content_type
368
- File.new(@value)
369
- when :rack
388
+ when :rack, :merb
370
389
  Rack::Test::UploadedFile.new(@value, content_type)
371
390
  end
372
391
  end
@@ -381,31 +400,88 @@ module Webrat
381
400
 
382
401
  class ResetField < Field #:nodoc:
383
402
  def self.xpath_search
384
- ".//input[@type = 'reset']"
403
+ [".//input[@type = 'reset']"]
385
404
  end
386
405
  end
387
406
 
388
407
  class SelectField < Field #:nodoc:
389
408
 
390
409
  def self.xpath_search
391
- ".//select"
410
+ [".//select[not(@multiple)]"]
392
411
  end
393
412
 
394
413
  def options
395
414
  @options ||= SelectOption.load_all(@session, @element)
396
415
  end
397
416
 
417
+ def unset(value)
418
+ @value = nil
419
+ end
420
+
398
421
  protected
399
422
 
400
423
  def default_value
401
- selected_options = Webrat::XML.xpath_search(@element, ".//option[@selected = 'selected']")
402
- selected_options = Webrat::XML.xpath_search(@element, ".//option[position() = 1]") if selected_options.empty?
424
+ selected_options = @element.xpath(".//option[@selected = 'selected']")
425
+ selected_options = @element.xpath(".//option[position() = 1]") if selected_options.empty?
403
426
 
404
427
  selected_options.map do |option|
405
428
  return "" if option.nil?
406
- Webrat::XML.attribute(option, "value") || Webrat::XML.inner_html(option)
429
+ option["value"] || option.inner_html
430
+ end.uniq.first
431
+ end
432
+
433
+ end
434
+
435
+ class MultipleSelectField < Field #:nodoc:
436
+
437
+ def self.xpath_search
438
+ [".//select[@multiple='multiple']"]
439
+ end
440
+
441
+ def options
442
+ @options ||= SelectOption.load_all(@session, @element)
443
+ end
444
+
445
+ def set(value)
446
+ @value << value
447
+ end
448
+
449
+ def unset(value)
450
+ @value.delete(value)
451
+ end
452
+
453
+ # We have to overide how the uri string is formed when dealing with multiples
454
+ # Where normally a select field might produce name=value with a multiple,
455
+ # we need to form something like name[]=value1&name[]=value2
456
+ def to_param
457
+ return nil if disabled?
458
+
459
+ uri_string = @value.collect {|value| "#{name}=#{CGI.escape(value)}"}.join("&")
460
+ params = case Webrat.configuration.mode
461
+ when :rails
462
+ parse_rails_request_params(uri_string)
463
+ when :merb
464
+ ::Merb::Parse.query(uri_string)
465
+ else
466
+ { name => @value }
467
+ end
468
+
469
+ unescape_params(params)
470
+ end
471
+
472
+ protected
473
+
474
+ # Overwrite SelectField definition because we don't want to select the first option
475
+ # (mutliples don't select the first option unlike their non multiple versions)
476
+ def default_value
477
+ selected_options = @element.xpath(".//option[@selected = 'selected']")
478
+
479
+ selected_options.map do |option|
480
+ return "" if option.nil?
481
+ option["value"] || option.inner_html
407
482
  end.uniq
408
483
  end
409
484
 
410
485
  end
486
+
411
487
  end
@@ -9,7 +9,7 @@ module Webrat
9
9
  attr_reader :element
10
10
 
11
11
  def self.xpath_search
12
- ".//form"
12
+ [".//form"]
13
13
  end
14
14
 
15
15
  def fields
@@ -27,7 +27,7 @@ module Webrat
27
27
  protected
28
28
 
29
29
  def dom
30
- Webrat::XML.xpath_at(@session.dom, path)
30
+ @session.dom.xpath(path).first
31
31
  end
32
32
 
33
33
  def fields_by_type(field_types)
@@ -50,11 +50,11 @@ module Webrat
50
50
  end
51
51
 
52
52
  def form_method
53
- Webrat::XML.attribute(@element, "method").blank? ? :get : Webrat::XML.attribute(@element, "method").downcase
53
+ @element["method"].blank? ? :get : @element["method"].downcase
54
54
  end
55
55
 
56
56
  def form_action
57
- Webrat::XML.attribute(@element, "action").blank? ? @session.current_url : Webrat::XML.attribute(@element, "action")
57
+ @element["action"].blank? ? @session.current_url : @element["action"]
58
58
  end
59
59
 
60
60
  def merge(all_params, new_param)
@@ -6,11 +6,11 @@ module Webrat
6
6
  attr_reader :element
7
7
 
8
8
  def self.xpath_search
9
- ".//label"
9
+ [".//label"]
10
10
  end
11
11
 
12
12
  def for_id
13
- Webrat::XML.attribute(@element, "for")
13
+ @element["for"]
14
14
  end
15
15
 
16
16
  def field
@@ -21,9 +21,9 @@ module Webrat
21
21
 
22
22
  def field_element
23
23
  if for_id.blank?
24
- Webrat::XML.xpath_at(@element, *Field.xpath_search_excluding_hidden)
24
+ @element.xpath(*Field.xpath_search_excluding_hidden).first
25
25
  else
26
- Webrat::XML.css_search(@session.current_dom, "#" + for_id).first
26
+ @session.current_dom.css("#" + for_id).first
27
27
  end
28
28
  end
29
29
 
@@ -7,7 +7,7 @@ module Webrat
7
7
  class Link < Element #:nodoc:
8
8
 
9
9
  def self.xpath_search
10
- ".//a[@href]"
10
+ [".//a[@href]"]
11
11
  end
12
12
 
13
13
  def click(options = {})
@@ -26,7 +26,7 @@ module Webrat
26
26
  protected
27
27
 
28
28
  def id
29
- Webrat::XML.attribute(@element, "id")
29
+ @element["id"]
30
30
  end
31
31
 
32
32
  def data
@@ -34,11 +34,11 @@ module Webrat
34
34
  end
35
35
 
36
36
  def title
37
- Webrat::XML.attribute(@element, "title")
37
+ @element["title"]
38
38
  end
39
39
 
40
40
  def href
41
- Webrat::XML.attribute(@element, "href")
41
+ @element["href"]
42
42
  end
43
43
 
44
44
  def absolute_href
@@ -53,12 +53,12 @@ module Webrat
53
53
 
54
54
  def authenticity_token
55
55
  return unless onclick && onclick.include?("s.setAttribute('name', 'authenticity_token');") &&
56
- onclick =~ /s\.setAttribute\('value', '([a-f0-9]{40})'\);/
56
+ ( onclick =~ /s\.setAttribute\('value', '([a-f0-9]{40})'\);/ || onclick =~ /s\.setAttribute\('value', '(.{44})'\);/ )
57
57
  $LAST_MATCH_INFO.captures.first
58
58
  end
59
59
 
60
60
  def onclick
61
- Webrat::XML.attribute(@element, "onclick")
61
+ @element["onclick"]
62
62
  end
63
63
 
64
64
  def http_method
@@ -4,7 +4,7 @@ module Webrat
4
4
  class SelectOption < Element #:nodoc:
5
5
 
6
6
  def self.xpath_search
7
- ".//option"
7
+ [".//option"]
8
8
  end
9
9
 
10
10
  def choose
@@ -12,6 +12,15 @@ module Webrat
12
12
  select.set(value)
13
13
  end
14
14
 
15
+ def unchoose
16
+ select.raise_error_if_disabled
17
+ select.unset(value)
18
+ end
19
+
20
+ def inner_text
21
+ @element.inner_text
22
+ end
23
+
15
24
  protected
16
25
 
17
26
  def select
@@ -28,7 +37,11 @@ module Webrat
28
37
  end
29
38
 
30
39
  def value
31
- Webrat::XML.attribute(@element, "value") || Webrat::XML.inner_html(@element)
40
+ @element["value"] || @element.inner_html
41
+ end
42
+
43
+ def label
44
+ @element.inner_html
32
45
  end
33
46
 
34
47
  end
@@ -13,7 +13,7 @@ module Webrat
13
13
  module Locators
14
14
 
15
15
  def field_by_xpath(xpath)
16
- Field.load(@session, Webrat::XML.xpath_at(dom, xpath))
16
+ Field.load(@session, dom.xpath(xpath).first)
17
17
  end
18
18
 
19
19
  end
@@ -11,8 +11,8 @@ module Webrat
11
11
 
12
12
  def area_element
13
13
  area_elements.detect do |area_element|
14
- Webrat::XML.attribute(area_element, "title") =~ matcher ||
15
- Webrat::XML.attribute(area_element, "id") =~ matcher
14
+ area_element["title"] =~ matcher ||
15
+ area_element["id"] =~ matcher
16
16
  end
17
17
  end
18
18
 
@@ -21,7 +21,7 @@ module Webrat
21
21
  end
22
22
 
23
23
  def area_elements
24
- Webrat::XML.xpath_search(@dom, Area.xpath_search)
24
+ @dom.xpath(*Area.xpath_search)
25
25
  end
26
26
 
27
27
  def error_message