futuresinc-webrat 0.4.4.99

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