brynary-webrat 0.3.2.1

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 (65) hide show
  1. data/History.txt +184 -0
  2. data/MIT-LICENSE.txt +19 -0
  3. data/README.rdoc +81 -0
  4. data/Rakefile +104 -0
  5. data/install.rb +1 -0
  6. data/lib/webrat.rb +32 -0
  7. data/lib/webrat/core.rb +13 -0
  8. data/lib/webrat/core/configuration.rb +44 -0
  9. data/lib/webrat/core/elements/area.rb +31 -0
  10. data/lib/webrat/core/elements/element.rb +29 -0
  11. data/lib/webrat/core/elements/field.rb +386 -0
  12. data/lib/webrat/core/elements/form.rb +103 -0
  13. data/lib/webrat/core/elements/label.rb +31 -0
  14. data/lib/webrat/core/elements/link.rb +94 -0
  15. data/lib/webrat/core/elements/select_option.rb +35 -0
  16. data/lib/webrat/core/locators.rb +20 -0
  17. data/lib/webrat/core/locators/area_locator.rb +38 -0
  18. data/lib/webrat/core/locators/button_locator.rb +54 -0
  19. data/lib/webrat/core/locators/field_by_id_locator.rb +37 -0
  20. data/lib/webrat/core/locators/field_labeled_locator.rb +50 -0
  21. data/lib/webrat/core/locators/field_locator.rb +25 -0
  22. data/lib/webrat/core/locators/field_named_locator.rb +41 -0
  23. data/lib/webrat/core/locators/form_locator.rb +19 -0
  24. data/lib/webrat/core/locators/label_locator.rb +34 -0
  25. data/lib/webrat/core/locators/link_locator.rb +66 -0
  26. data/lib/webrat/core/locators/locator.rb +20 -0
  27. data/lib/webrat/core/locators/select_option_locator.rb +59 -0
  28. data/lib/webrat/core/logging.rb +21 -0
  29. data/lib/webrat/core/matchers.rb +4 -0
  30. data/lib/webrat/core/matchers/have_content.rb +55 -0
  31. data/lib/webrat/core/matchers/have_selector.rb +37 -0
  32. data/lib/webrat/core/matchers/have_tag.rb +57 -0
  33. data/lib/webrat/core/matchers/have_xpath.rb +83 -0
  34. data/lib/webrat/core/methods.rb +54 -0
  35. data/lib/webrat/core/mime.rb +29 -0
  36. data/lib/webrat/core/scope.rb +318 -0
  37. data/lib/webrat/core/session.rb +241 -0
  38. data/lib/webrat/core/xml.rb +99 -0
  39. data/lib/webrat/core/xml/hpricot.rb +19 -0
  40. data/lib/webrat/core/xml/nokogiri.rb +44 -0
  41. data/lib/webrat/core/xml/rexml.rb +24 -0
  42. data/lib/webrat/core_extensions/blank.rb +58 -0
  43. data/lib/webrat/core_extensions/deprecate.rb +8 -0
  44. data/lib/webrat/core_extensions/detect_mapped.rb +12 -0
  45. data/lib/webrat/core_extensions/hash_with_indifferent_access.rb +131 -0
  46. data/lib/webrat/core_extensions/meta_class.rb +6 -0
  47. data/lib/webrat/core_extensions/nil_to_param.rb +5 -0
  48. data/lib/webrat/mechanize.rb +43 -0
  49. data/lib/webrat/merb.rb +77 -0
  50. data/lib/webrat/rack.rb +26 -0
  51. data/lib/webrat/rails.rb +88 -0
  52. data/lib/webrat/rails/redirect_actions.rb +18 -0
  53. data/lib/webrat/rspec-rails.rb +13 -0
  54. data/lib/webrat/selenium.rb +59 -0
  55. data/lib/webrat/selenium/location_strategy_javascript/button.js +12 -0
  56. data/lib/webrat/selenium/location_strategy_javascript/label.js +16 -0
  57. data/lib/webrat/selenium/location_strategy_javascript/webrat.js +5 -0
  58. data/lib/webrat/selenium/location_strategy_javascript/webratlink.js +9 -0
  59. data/lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js +15 -0
  60. data/lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js +5 -0
  61. data/lib/webrat/selenium/selenium_extensions.js +6 -0
  62. data/lib/webrat/selenium/selenium_session.rb +186 -0
  63. data/lib/webrat/sinatra.rb +21 -0
  64. data/vendor/selenium-server.jar +0 -0
  65. metadata +135 -0
@@ -0,0 +1,31 @@
1
+ require "webrat/core/elements/element"
2
+
3
+ module Webrat
4
+ class Area < Element #:nodoc:
5
+
6
+ def self.xpath_search
7
+ ".//area"
8
+ end
9
+
10
+ def click(method = nil, options = {})
11
+ @session.request_page(absolute_href, :get, {})
12
+ end
13
+
14
+ protected
15
+
16
+ def href
17
+ Webrat::XML.attribute(@element, "href")
18
+ end
19
+
20
+ def absolute_href
21
+ if href =~ /^\?/
22
+ "#{@session.current_url}#{href}"
23
+ elsif href !~ %r{^https?://[\w|.]+(/.*)} && (href !~ /^\//)
24
+ "#{@session.current_url}/#{href}"
25
+ else
26
+ href
27
+ end
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,29 @@
1
+ module Webrat
2
+
3
+ class Element # :nodoc:
4
+
5
+ def self.load_all(session, dom)
6
+ Webrat::XML.xpath_search(dom, xpath_search).map do |element|
7
+ load(session, element)
8
+ end
9
+ end
10
+
11
+ def self.load(session, element)
12
+ return nil if element.nil?
13
+ session.elements[Webrat::XML.xpath_to(element)] ||= self.new(session, element)
14
+ end
15
+
16
+ attr_reader :element
17
+
18
+ def initialize(session, element)
19
+ @session = session
20
+ @element = element
21
+ end
22
+
23
+ def path
24
+ Webrat::XML.xpath_to(@element)
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,386 @@
1
+ require "cgi"
2
+ require "webrat/core_extensions/blank"
3
+ require "webrat/core_extensions/nil_to_param"
4
+
5
+ require "webrat/core/elements/element"
6
+
7
+ module Webrat
8
+ # Raised when Webrat is asked to manipulate a disabled form field
9
+ class DisabledFieldError < WebratError
10
+ end
11
+
12
+ class Field < Element #:nodoc:
13
+ attr_reader :value
14
+
15
+ def self.xpath_search
16
+ [".//button", ".//input", ".//textarea", ".//select"]
17
+ end
18
+
19
+ def self.field_classes
20
+ @field_classes || []
21
+ end
22
+
23
+ def self.inherited(klass)
24
+ @field_classes ||= []
25
+ @field_classes << klass
26
+ # raise args.inspect
27
+ end
28
+
29
+ def self.load(session, element)
30
+ return nil if element.nil?
31
+ session.elements[Webrat::XML.xpath_to(element)] ||= field_class(element).new(session, element)
32
+ end
33
+
34
+ def self.field_class(element)
35
+ case element.name
36
+ when "button" then ButtonField
37
+ when "select" then SelectField
38
+ when "textarea" then TextareaField
39
+ else
40
+ case Webrat::XML.attribute(element, "type")
41
+ when "checkbox" then CheckboxField
42
+ when "hidden" then HiddenField
43
+ when "radio" then RadioField
44
+ when "password" then PasswordField
45
+ when "file" then FileField
46
+ when "reset" then ResetField
47
+ when "submit" then ButtonField
48
+ when "image" then ButtonField
49
+ else TextField
50
+ end
51
+ end
52
+ end
53
+
54
+ def initialize(*args)
55
+ super
56
+ @value = default_value
57
+ end
58
+
59
+ def label_text
60
+ return nil if labels.empty?
61
+ labels.first.text
62
+ end
63
+
64
+ def id
65
+ Webrat::XML.attribute(@element, "id")
66
+ end
67
+
68
+ def disabled?
69
+ @element.attributes.has_key?("disabled") && Webrat::XML.attribute(@element, "disabled") != 'false'
70
+ end
71
+
72
+ def raise_error_if_disabled
73
+ return unless disabled?
74
+ raise DisabledFieldError.new("Cannot interact with disabled form element (#{self})")
75
+ end
76
+
77
+ def to_param
78
+ return nil if disabled?
79
+
80
+ case Webrat.configuration.mode
81
+ when :rails
82
+ ActionController::AbstractRequest.parse_query_parameters("#{name}=#{escaped_value}")
83
+ when :merb
84
+ ::Merb::Parse.query("#{name}=#{escaped_value}")
85
+ else
86
+ { name => escaped_value }
87
+ end
88
+ end
89
+
90
+ def set(value)
91
+ @value = value
92
+ end
93
+
94
+ def unset
95
+ @value = default_value
96
+ end
97
+
98
+ protected
99
+
100
+ def form
101
+ Form.load(@session, form_element)
102
+ end
103
+
104
+ def form_element
105
+ parent = @element.parent
106
+
107
+ while parent.respond_to?(:parent)
108
+ return parent if parent.name == 'form'
109
+ parent = parent.parent
110
+ end
111
+ end
112
+
113
+ def name
114
+ Webrat::XML.attribute(@element, "name")
115
+ end
116
+
117
+ def escaped_value
118
+ CGI.escape(@value.to_s)
119
+ end
120
+
121
+ def labels
122
+ @labels ||= label_elements.map do |element|
123
+ Label.load(@session, element)
124
+ end
125
+ end
126
+
127
+ def label_elements
128
+ return @label_elements unless @label_elements.nil?
129
+ @label_elements = []
130
+
131
+ parent = @element.parent
132
+ while parent.respond_to?(:parent)
133
+ if parent.name == 'label'
134
+ @label_elements.push parent
135
+ break
136
+ end
137
+ parent = parent.parent
138
+ end
139
+
140
+ unless id.blank?
141
+ @label_elements += Webrat::XML.css_search(form.element, "label[@for='#{id}']")
142
+ end
143
+
144
+ @label_elements
145
+ end
146
+
147
+ def default_value
148
+ Webrat::XML.attribute(@element, "value")
149
+ end
150
+
151
+ def replace_param_value(params, oval, nval)
152
+ output = Hash.new
153
+ params.each do |key, value|
154
+ case value
155
+ when Hash
156
+ value = replace_param_value(value, oval, nval)
157
+ when Array
158
+ value = value.map { |o| o == oval ? nval : oval }
159
+ when oval
160
+ value = nval
161
+ end
162
+ output[key] = value
163
+ end
164
+ output
165
+ end
166
+ end
167
+
168
+ class ButtonField < Field #:nodoc:
169
+
170
+ def self.xpath_search
171
+ [".//button", ".//input[@type = 'submit']", ".//input[@type = 'image']"]
172
+ end
173
+
174
+ def to_param
175
+ return nil if @value.nil?
176
+ super
177
+ end
178
+
179
+ def default_value
180
+ nil
181
+ end
182
+
183
+ def click
184
+ raise_error_if_disabled
185
+ set(Webrat::XML.attribute(@element, "value")) unless Webrat::XML.attribute(@element, "name").blank?
186
+ form.submit
187
+ end
188
+
189
+ end
190
+
191
+ class HiddenField < Field #:nodoc:
192
+
193
+ def self.xpath_search
194
+ ".//input[@type = 'hidden']"
195
+ end
196
+
197
+ def to_param
198
+ if collection_name?
199
+ super
200
+ else
201
+ checkbox_with_same_name = form.field_named(name, CheckboxField)
202
+
203
+ if checkbox_with_same_name.to_param.blank?
204
+ super
205
+ else
206
+ nil
207
+ end
208
+ end
209
+ end
210
+
211
+ protected
212
+
213
+ def collection_name?
214
+ name =~ /\[\]/
215
+ end
216
+
217
+ end
218
+
219
+ class CheckboxField < Field #:nodoc:
220
+
221
+ def self.xpath_search
222
+ ".//input[@type = 'checkbox']"
223
+ end
224
+
225
+ def to_param
226
+ return nil if @value.nil?
227
+ super
228
+ end
229
+
230
+ def check
231
+ raise_error_if_disabled
232
+ set(Webrat::XML.attribute(@element, "value") || "on")
233
+ end
234
+
235
+ def checked?
236
+ Webrat::XML.attribute(@element, "checked") == "checked"
237
+ end
238
+
239
+ def uncheck
240
+ raise_error_if_disabled
241
+ set(nil)
242
+ end
243
+
244
+ protected
245
+
246
+ def default_value
247
+ if Webrat::XML.attribute(@element, "checked") == "checked"
248
+ Webrat::XML.attribute(@element, "value") || "on"
249
+ else
250
+ nil
251
+ end
252
+ end
253
+
254
+ end
255
+
256
+ class PasswordField < Field #:nodoc:
257
+
258
+ def self.xpath_search
259
+ ".//input[@type = 'password']"
260
+ end
261
+
262
+ end
263
+
264
+ class RadioField < Field #:nodoc:
265
+
266
+ def self.xpath_search
267
+ ".//input[@type = 'radio']"
268
+ end
269
+
270
+ def to_param
271
+ return nil if @value.nil?
272
+ super
273
+ end
274
+
275
+ def choose
276
+ raise_error_if_disabled
277
+ other_options.each do |option|
278
+ option.set(nil)
279
+ end
280
+
281
+ set(Webrat::XML.attribute(@element, "value") || "on")
282
+ end
283
+
284
+ def checked?
285
+ Webrat::XML.attribute(@element, "checked") == "checked"
286
+ end
287
+
288
+ protected
289
+
290
+ def other_options
291
+ form.fields.select { |f| f.name == name }
292
+ end
293
+
294
+ def default_value
295
+ if Webrat::XML.attribute(@element, "checked") == "checked"
296
+ Webrat::XML.attribute(@element, "value") || "on"
297
+ else
298
+ nil
299
+ end
300
+ end
301
+
302
+ end
303
+
304
+ class TextareaField < Field #:nodoc:
305
+
306
+ def self.xpath_search
307
+ ".//textarea"
308
+ end
309
+
310
+ protected
311
+
312
+ def default_value
313
+ Webrat::XML.inner_html(@element)
314
+ end
315
+
316
+ end
317
+
318
+ class FileField < Field #:nodoc:
319
+
320
+ def self.xpath_search
321
+ ".//input[@type = 'file']"
322
+ end
323
+
324
+ attr_accessor :content_type
325
+
326
+ def set(value, content_type = nil)
327
+ super(value)
328
+ @content_type = content_type
329
+ end
330
+
331
+ def to_param
332
+ if @value.nil?
333
+ super
334
+ else
335
+ replace_param_value(super, @value, test_uploaded_file)
336
+ end
337
+ end
338
+
339
+ protected
340
+
341
+ def test_uploaded_file
342
+ if content_type
343
+ ActionController::TestUploadedFile.new(@value, content_type)
344
+ else
345
+ ActionController::TestUploadedFile.new(@value)
346
+ end
347
+ end
348
+
349
+ end
350
+
351
+ class TextField < Field #:nodoc:
352
+ def self.xpath_search
353
+ [".//input[@type = 'text']", ".//input[not(@type)]"]
354
+ end
355
+ end
356
+
357
+ class ResetField < Field #:nodoc:
358
+ def self.xpath_search
359
+ ".//input[@type = 'reset']"
360
+ end
361
+ end
362
+
363
+ class SelectField < Field #:nodoc:
364
+
365
+ def self.xpath_search
366
+ ".//select"
367
+ end
368
+
369
+ def options
370
+ @options ||= SelectOption.load_all(@session, @element)
371
+ end
372
+
373
+ protected
374
+
375
+ def default_value
376
+ selected_options = Webrat::XML.css_search(@element, "option[@selected='selected']")
377
+ selected_options = Webrat::XML.css_search(@element, "option:first") if selected_options.empty?
378
+
379
+ selected_options.map do |option|
380
+ return "" if option.nil?
381
+ Webrat::XML.attribute(option, "value") || Webrat::XML.inner_html(option)
382
+ end
383
+ end
384
+
385
+ end
386
+ end
@@ -0,0 +1,103 @@
1
+ require "webrat/core/elements/field"
2
+ require "webrat/core_extensions/blank"
3
+
4
+ require "webrat/core/elements/element"
5
+ require "webrat/core/locators/field_named_locator"
6
+
7
+ module Webrat
8
+ class Form < Element #:nodoc:
9
+ attr_reader :element
10
+
11
+ def self.xpath_search
12
+ ".//form"
13
+ end
14
+
15
+ def fields
16
+ @fields ||= Field.load_all(@session, @element)
17
+ end
18
+
19
+ def submit
20
+ @session.request_page(form_action, form_method, params)
21
+ end
22
+
23
+ def field_named(name, *field_types)
24
+ Webrat::Locators::FieldNamedLocator.new(@session, dom, name, *field_types).locate
25
+ end
26
+
27
+ protected
28
+
29
+ def dom
30
+ Webrat::XML.xpath_at(@session.dom, path)
31
+ end
32
+
33
+ def fields_by_type(field_types)
34
+ if field_types.any?
35
+ fields.select { |f| field_types.include?(f.class) }
36
+ else
37
+ fields
38
+ end
39
+ end
40
+
41
+ def params
42
+ all_params = {}
43
+
44
+ fields.each do |field|
45
+ next if field.to_param.nil?
46
+ merge(all_params, field.to_param)
47
+ end
48
+
49
+ all_params
50
+ end
51
+
52
+ def form_method
53
+ Webrat::XML.attribute(@element, "method").blank? ? :get : Webrat::XML.attribute(@element, "method").downcase
54
+ end
55
+
56
+ def form_action
57
+ Webrat::XML.attribute(@element, "action").blank? ? @session.current_url : Webrat::XML.attribute(@element, "action")
58
+ end
59
+
60
+ def merge(all_params, new_param)
61
+ new_param.each do |key, value|
62
+ case all_params[key]
63
+ when *hash_classes
64
+ merge_hash_values(all_params[key], value)
65
+ when Array
66
+ all_params[key] += value
67
+ else
68
+ all_params[key] = value
69
+ end
70
+ end
71
+ end
72
+
73
+ def merge_hash_values(a, b) # :nodoc:
74
+ a.keys.each do |k|
75
+ if b.has_key?(k)
76
+ case [a[k], b[k]].map{|value| value.class}
77
+ when *hash_classes.zip(hash_classes)
78
+ a[k] = merge_hash_values(a[k], b[k])
79
+ b.delete(k)
80
+ when [Array, Array]
81
+ a[k] += b[k]
82
+ b.delete(k)
83
+ end
84
+ end
85
+ end
86
+ a.merge!(b)
87
+ end
88
+
89
+ def hash_classes
90
+ klasses = [Hash]
91
+
92
+ case Webrat.configuration.mode
93
+ when :rails
94
+ klasses << HashWithIndifferentAccess
95
+ when :merb
96
+ klasses << Mash
97
+ end
98
+
99
+ klasses
100
+ end
101
+
102
+ end
103
+ end