dbrady-webrat 0.4.4

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 (70) hide show
  1. data/History.txt +325 -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.rb +34 -0
  7. data/lib/webrat/core.rb +14 -0
  8. data/lib/webrat/core/configuration.rb +98 -0
  9. data/lib/webrat/core/elements/area.rb +31 -0
  10. data/lib/webrat/core/elements/element.rb +33 -0
  11. data/lib/webrat/core/elements/field.rb +403 -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 +92 -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 +56 -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 +73 -0
  31. data/lib/webrat/core/matchers/have_selector.rb +74 -0
  32. data/lib/webrat/core/matchers/have_tag.rb +21 -0
  33. data/lib/webrat/core/matchers/have_xpath.rb +147 -0
  34. data/lib/webrat/core/methods.rb +61 -0
  35. data/lib/webrat/core/mime.rb +29 -0
  36. data/lib/webrat/core/save_and_open_page.rb +50 -0
  37. data/lib/webrat/core/scope.rb +350 -0
  38. data/lib/webrat/core/session.rb +281 -0
  39. data/lib/webrat/core/xml.rb +115 -0
  40. data/lib/webrat/core/xml/hpricot.rb +19 -0
  41. data/lib/webrat/core/xml/nokogiri.rb +76 -0
  42. data/lib/webrat/core/xml/rexml.rb +24 -0
  43. data/lib/webrat/core_extensions/blank.rb +58 -0
  44. data/lib/webrat/core_extensions/deprecate.rb +8 -0
  45. data/lib/webrat/core_extensions/detect_mapped.rb +12 -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 +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.rb +80 -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.rb +4 -0
  62. data/lib/webrat/selenium/matchers/have_content.rb +66 -0
  63. data/lib/webrat/selenium/matchers/have_selector.rb +49 -0
  64. data/lib/webrat/selenium/matchers/have_tag.rb +72 -0
  65. data/lib/webrat/selenium/matchers/have_xpath.rb +45 -0
  66. data/lib/webrat/selenium/selenium_extensions.js +6 -0
  67. data/lib/webrat/selenium/selenium_session.rb +241 -0
  68. data/lib/webrat/sinatra.rb +53 -0
  69. data/vendor/selenium-server.jar +0 -0
  70. metadata +141 -0
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ puts IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
data/lib/webrat.rb ADDED
@@ -0,0 +1,34 @@
1
+ require "rubygems"
2
+
3
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
4
+
5
+ module Webrat
6
+ # The common base class for all exceptions raised by Webrat.
7
+ class WebratError < StandardError
8
+ end
9
+
10
+ VERSION = '0.4.4'
11
+
12
+ def self.require_xml
13
+ gem "nokogiri", ">= 1.0.6"
14
+
15
+ if on_java?
16
+ # We need Nokogiri's CSS to XPath support, even if using REXML and Hpricot for parsing and searching
17
+ require "nokogiri/css"
18
+ require "hpricot"
19
+ require "rexml/document"
20
+ else
21
+ require "nokogiri"
22
+ require "webrat/core/xml/nokogiri"
23
+ end
24
+ end
25
+
26
+ def self.on_java?
27
+ RUBY_PLATFORM =~ /java/
28
+ end
29
+
30
+ end
31
+
32
+ Webrat.require_xml
33
+
34
+ require "webrat/core"
@@ -0,0 +1,14 @@
1
+ require "webrat/core/configuration"
2
+ require "webrat/core/xml"
3
+ require "webrat/core/xml/nokogiri"
4
+ require "webrat/core/logging"
5
+ require "webrat/core/elements/form"
6
+ require "webrat/core/scope"
7
+ require "webrat/core/elements/link"
8
+ require "webrat/core/elements/area"
9
+ require "webrat/core/elements/label"
10
+ require "webrat/core/elements/select_option"
11
+ require "webrat/core/session"
12
+ require "webrat/core/methods"
13
+ require "webrat/core/matchers"
14
+ require "webrat/core/save_and_open_page"
@@ -0,0 +1,98 @@
1
+ require "webrat/core_extensions/deprecate"
2
+
3
+ module Webrat
4
+
5
+ # Configures Webrat. If this is not done, Webrat will be created
6
+ # with all of the default settings.
7
+ def self.configure(configuration = Webrat.configuration)
8
+ yield configuration if block_given?
9
+ @@configuration = configuration
10
+ end
11
+
12
+ def self.configuration # :nodoc:
13
+ @@configuration ||= Webrat::Configuration.new
14
+ end
15
+
16
+ # Webrat can be configured using the Webrat.configure method. For example:
17
+ #
18
+ # Webrat.configure do |config|
19
+ # config.parse_with_nokogiri = false
20
+ # end
21
+ class Configuration
22
+
23
+ # Should XHTML be parsed with Nokogiri? Defaults to true, except on JRuby. When false, Hpricot and REXML are used
24
+ attr_writer :parse_with_nokogiri
25
+
26
+ # Webrat's mode, set automatically when requiring webrat/rails, webrat/merb, etc.
27
+ attr_reader :mode # :nodoc:
28
+
29
+ # Save and open pages with error status codes (500-599) in a browser? Defualts to true.
30
+ attr_writer :open_error_files
31
+
32
+ # Which rails environment should the selenium tests be run in? Defaults to selenium.
33
+ attr_accessor :application_environment
34
+ webrat_deprecate :selenium_environment, :application_environment
35
+ webrat_deprecate :selenium_environment=, :application_environment=
36
+
37
+ # Which port is the application running on for selenium testing? Defaults to 3001.
38
+ attr_accessor :application_port
39
+ webrat_deprecate :selenium_port, :application_port
40
+ webrat_deprecate :selenium_port=, :application_port=
41
+
42
+ # Which underlying app framework we're testing with selenium
43
+ attr_accessor :application_framework
44
+
45
+ # Which server the application is running on for selenium testing? Defaults to localhost
46
+ attr_accessor :application_address
47
+
48
+ # Which server Selenium server is running on. Defaults to nil(server starts in webrat process and runs locally)
49
+ attr_accessor :selenium_server_address
50
+
51
+ # Which server Selenium port is running on. Defaults to 4444
52
+ attr_accessor :selenium_server_port
53
+
54
+ # Set the key that Selenium uses to determine the browser running. Default *firefox
55
+ attr_accessor :selenium_browser_key
56
+
57
+ # How many redirects to the same URL should be halted as an infinite redirect
58
+ # loop? Defaults to 10
59
+ attr_accessor :infinite_redirect_limit
60
+
61
+ def initialize # :nodoc:
62
+ self.open_error_files = true
63
+ self.parse_with_nokogiri = !Webrat.on_java?
64
+ self.application_environment = :test
65
+ self.application_port = 3001
66
+ self.application_address = 'localhost'
67
+ self.application_framework = :rails
68
+ self.selenium_server_port = 4444
69
+ self.infinite_redirect_limit = 10
70
+ self.selenium_browser_key = '*firefox'
71
+ end
72
+
73
+ def parse_with_nokogiri? #:nodoc:
74
+ @parse_with_nokogiri ? true : false
75
+ end
76
+
77
+ def open_error_files? #:nodoc:
78
+ @open_error_files ? true : false
79
+ end
80
+
81
+ # Allows setting of webrat's mode, valid modes are:
82
+ # :rails, :selenium, :rack, :sinatra, :mechanize, :merb
83
+ def mode=(mode)
84
+ @mode = mode.to_sym
85
+
86
+ # This is a temporary hack to support backwards compatibility
87
+ # with Merb 1.0.8 until it's updated to use the new Webrat.configure
88
+ # syntax
89
+ if @mode == :merb
90
+ require("webrat/merb_session")
91
+ else
92
+ require("webrat/#{mode}")
93
+ end
94
+ end
95
+
96
+ end
97
+
98
+ end
@@ -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