raldred-webrat 0.4.4.2

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 (160) hide show
  1. data/History.txt +346 -0
  2. data/MIT-LICENSE.txt +19 -0
  3. data/README.rdoc +85 -0
  4. data/Rakefile +168 -0
  5. data/install.rb +1 -0
  6. data/lib/webrat.rb +31 -0
  7. data/lib/webrat/core.rb +14 -0
  8. data/lib/webrat/core/configuration.rb +102 -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 +405 -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 +75 -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 +24 -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 +63 -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 +289 -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/core_extensions/tcp_socket.rb +27 -0
  49. data/lib/webrat/mechanize.rb +74 -0
  50. data/lib/webrat/merb.rb +9 -0
  51. data/lib/webrat/merb_session.rb +65 -0
  52. data/lib/webrat/rack.rb +24 -0
  53. data/lib/webrat/rack_test.rb +32 -0
  54. data/lib/webrat/rails.rb +105 -0
  55. data/lib/webrat/rspec-rails.rb +13 -0
  56. data/lib/webrat/selenium.rb +81 -0
  57. data/lib/webrat/selenium/application_server.rb +73 -0
  58. data/lib/webrat/selenium/location_strategy_javascript/button.js +19 -0
  59. data/lib/webrat/selenium/location_strategy_javascript/label.js +15 -0
  60. data/lib/webrat/selenium/location_strategy_javascript/webrat.js +5 -0
  61. data/lib/webrat/selenium/location_strategy_javascript/webratlink.js +12 -0
  62. data/lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js +15 -0
  63. data/lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js +5 -0
  64. data/lib/webrat/selenium/matchers.rb +4 -0
  65. data/lib/webrat/selenium/matchers/have_content.rb +66 -0
  66. data/lib/webrat/selenium/matchers/have_selector.rb +49 -0
  67. data/lib/webrat/selenium/matchers/have_tag.rb +72 -0
  68. data/lib/webrat/selenium/matchers/have_xpath.rb +45 -0
  69. data/lib/webrat/selenium/merb_application_server.rb +48 -0
  70. data/lib/webrat/selenium/rails_application_server.rb +42 -0
  71. data/lib/webrat/selenium/selenium_extensions.js +6 -0
  72. data/lib/webrat/selenium/selenium_rc_server.rb +84 -0
  73. data/lib/webrat/selenium/selenium_session.rb +242 -0
  74. data/lib/webrat/selenium/silence_stream.rb +18 -0
  75. data/lib/webrat/selenium/sinatra_application_server.rb +35 -0
  76. data/lib/webrat/sinatra.rb +44 -0
  77. data/spec/fakes/test_session.rb +34 -0
  78. data/spec/integration/merb/app/controllers/application.rb +2 -0
  79. data/spec/integration/merb/app/controllers/exceptions.rb +13 -0
  80. data/spec/integration/merb/app/controllers/testing.rb +18 -0
  81. data/spec/integration/merb/config/environments/development.rb +15 -0
  82. data/spec/integration/merb/config/environments/rake.rb +11 -0
  83. data/spec/integration/merb/config/environments/test.rb +14 -0
  84. data/spec/integration/merb/config/init.rb +25 -0
  85. data/spec/integration/merb/config/rack.rb +11 -0
  86. data/spec/integration/merb/config/router.rb +33 -0
  87. data/spec/integration/merb/spec/spec_helper.rb +24 -0
  88. data/spec/integration/merb/spec/webrat_spec.rb +32 -0
  89. data/spec/integration/merb/tasks/merb.thor/app_script.rb +31 -0
  90. data/spec/integration/merb/tasks/merb.thor/common.rb +64 -0
  91. data/spec/integration/merb/tasks/merb.thor/gem_ext.rb +124 -0
  92. data/spec/integration/merb/tasks/merb.thor/ops.rb +93 -0
  93. data/spec/integration/merb/tasks/merb.thor/utils.rb +40 -0
  94. data/spec/integration/rack/rack_app.rb +16 -0
  95. data/spec/integration/rack/test/test_helper.rb +20 -0
  96. data/spec/integration/rack/test/webrat_rack_test.rb +67 -0
  97. data/spec/integration/rails/app/controllers/application.rb +15 -0
  98. data/spec/integration/rails/app/controllers/buttons_controller.rb +7 -0
  99. data/spec/integration/rails/app/controllers/fields_controller.rb +4 -0
  100. data/spec/integration/rails/app/controllers/links_controller.rb +7 -0
  101. data/spec/integration/rails/app/controllers/webrat_controller.rb +39 -0
  102. data/spec/integration/rails/app/helpers/buttons_helper.rb +2 -0
  103. data/spec/integration/rails/app/helpers/fields_helper.rb +2 -0
  104. data/spec/integration/rails/app/helpers/links_helper.rb +2 -0
  105. data/spec/integration/rails/config/boot.rb +109 -0
  106. data/spec/integration/rails/config/environment.rb +12 -0
  107. data/spec/integration/rails/config/environments/development.rb +17 -0
  108. data/spec/integration/rails/config/environments/selenium.rb +22 -0
  109. data/spec/integration/rails/config/environments/test.rb +22 -0
  110. data/spec/integration/rails/config/initializers/inflections.rb +10 -0
  111. data/spec/integration/rails/config/initializers/mime_types.rb +5 -0
  112. data/spec/integration/rails/config/initializers/new_rails_defaults.rb +17 -0
  113. data/spec/integration/rails/config/routes.rb +17 -0
  114. data/spec/integration/rails/test/integration/button_click_test.rb +80 -0
  115. data/spec/integration/rails/test/integration/fill_in_test.rb +24 -0
  116. data/spec/integration/rails/test/integration/link_click_test.rb +21 -0
  117. data/spec/integration/rails/test/integration/webrat_test.rb +75 -0
  118. data/spec/integration/rails/test/test_helper.rb +25 -0
  119. data/spec/integration/sinatra/classic_app.rb +64 -0
  120. data/spec/integration/sinatra/modular_app.rb +16 -0
  121. data/spec/integration/sinatra/test/classic_app_test.rb +37 -0
  122. data/spec/integration/sinatra/test/modular_app_test.rb +18 -0
  123. data/spec/integration/sinatra/test/test_helper.rb +16 -0
  124. data/spec/private/core/configuration_spec.rb +106 -0
  125. data/spec/private/core/field_spec.rb +85 -0
  126. data/spec/private/core/link_spec.rb +24 -0
  127. data/spec/private/core/logging_spec.rb +10 -0
  128. data/spec/private/core/session_spec.rb +198 -0
  129. data/spec/private/mechanize/mechanize_session_spec.rb +81 -0
  130. data/spec/private/merb/merb_session_spec.rb +42 -0
  131. data/spec/private/nokogiri_spec.rb +77 -0
  132. data/spec/private/rails/attaches_file_spec.rb +81 -0
  133. data/spec/private/rails/rails_session_spec.rb +110 -0
  134. data/spec/public/basic_auth_spec.rb +24 -0
  135. data/spec/public/check_spec.rb +191 -0
  136. data/spec/public/choose_spec.rb +118 -0
  137. data/spec/public/click_area_spec.rb +106 -0
  138. data/spec/public/click_button_spec.rb +496 -0
  139. data/spec/public/click_link_spec.rb +541 -0
  140. data/spec/public/fill_in_spec.rb +209 -0
  141. data/spec/public/locators/field_by_xpath_spec.rb +19 -0
  142. data/spec/public/locators/field_labeled_spec.rb +172 -0
  143. data/spec/public/locators/field_with_id_spec.rb +16 -0
  144. data/spec/public/matchers/contain_spec.rb +114 -0
  145. data/spec/public/matchers/have_selector_spec.rb +142 -0
  146. data/spec/public/matchers/have_tag_spec.rb +39 -0
  147. data/spec/public/matchers/have_xpath_spec.rb +136 -0
  148. data/spec/public/reload_spec.rb +10 -0
  149. data/spec/public/save_and_open_spec.rb +51 -0
  150. data/spec/public/select_date_spec.rb +112 -0
  151. data/spec/public/select_datetime_spec.rb +137 -0
  152. data/spec/public/select_spec.rb +249 -0
  153. data/spec/public/select_time_spec.rb +100 -0
  154. data/spec/public/set_hidden_field_spec.rb +5 -0
  155. data/spec/public/submit_form_spec.rb +5 -0
  156. data/spec/public/visit_spec.rb +58 -0
  157. data/spec/public/within_spec.rb +177 -0
  158. data/spec/spec_helper.rb +50 -0
  159. data/vendor/selenium-server.jar +0 -0
  160. metadata +220 -0
data/Rakefile ADDED
@@ -0,0 +1,168 @@
1
+ # require 'rubygems'
2
+ require "rake/gempackagetask"
3
+ require 'rake/rdoctask'
4
+ require "rake/clean"
5
+ require 'spec'
6
+ require 'spec/rake/spectask'
7
+ require 'spec/rake/verify_rcov'
8
+ require File.expand_path('./lib/webrat.rb')
9
+ require 'jeweler'
10
+
11
+
12
+ ##############################################################################
13
+ # Package && release
14
+ ##############################################################################
15
+ spec = Gem::Specification.new do |s|
16
+ s.name = "webrat"
17
+ s.version = Webrat::VERSION
18
+ s.platform = Gem::Platform::RUBY
19
+ s.author = "Bryan Helmkamp"
20
+ s.email = "bryan" + "@" + "brynary.com"
21
+ s.homepage = "http://github.com/brynary/webrat"
22
+ s.summary = "Webrat. Ruby Acceptance Testing for Web applications"
23
+ s.bindir = "bin"
24
+ s.description = s.summary
25
+ s.require_path = "lib"
26
+ s.files = %w(History.txt install.rb MIT-LICENSE.txt README.rdoc Rakefile) + Dir["lib/**/*"] + Dir["vendor/**/*"]
27
+
28
+ # rdoc
29
+ s.has_rdoc = true
30
+ s.extra_rdoc_files = %w(README.rdoc MIT-LICENSE.txt)
31
+
32
+ # Dependencies
33
+ s.add_dependency "nokogiri", ">= 1.2.0"
34
+
35
+ s.rubyforge_project = "webrat"
36
+ end
37
+
38
+ Rake::GemPackageTask.new(spec) do |package|
39
+ package.gem_spec = spec
40
+ end
41
+
42
+ Jeweler::Tasks.new(spec)
43
+
44
+ desc 'Show information about the gem.'
45
+ task :debug_gem do
46
+ puts spec.to_ruby
47
+ end
48
+
49
+ CLEAN.include ["pkg", "*.gem", "doc", "ri", "coverage"]
50
+
51
+ desc "Upload rdoc to brynary.com"
52
+ task :publish_rdoc => :docs do
53
+ sh "scp -r doc/ brynary.com:/apps/uploads/webrat"
54
+ end
55
+
56
+ desc "Run API and Core specs"
57
+ Spec::Rake::SpecTask.new do |t|
58
+ t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
59
+ t.spec_files = FileList['spec/public/**/*_spec.rb'] + FileList['spec/private/**/*_spec.rb']
60
+ end
61
+
62
+ desc "Run all specs in spec directory with RCov"
63
+ Spec::Rake::SpecTask.new(:rcov) do |t|
64
+ t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
65
+ t.spec_files = FileList['spec/public/**/*_spec.rb'] + FileList['spec/private/**/*_spec.rb']
66
+ t.rcov = true
67
+ t.rcov_opts = lambda do
68
+ IO.readlines(File.dirname(__FILE__) + "/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
69
+ end
70
+ end
71
+
72
+ RCov::VerifyTask.new(:verify_rcov => :rcov) do |t|
73
+ t.threshold = 96.2 # Make sure you have rcov 0.7 or higher!
74
+ end
75
+
76
+ desc 'Install the package as a gem.'
77
+ task :install_gem => [:clean, :package] do
78
+ gem_filename = Dir['pkg/*.gem'].first
79
+ sh "sudo gem install --no-rdoc --no-ri --local #{gem_filename}"
80
+ end
81
+
82
+ desc "Delete generated RDoc"
83
+ task :clobber_docs do
84
+ FileUtils.rm_rf("doc")
85
+ end
86
+
87
+ desc "Generate RDoc"
88
+ task :docs => :clobber_docs do
89
+ system "hanna --title 'Webrat #{Webrat::VERSION} API Documentation'"
90
+ end
91
+
92
+ desc "Run specs using jruby"
93
+ task "spec:jruby" do
94
+ result = system "jruby -S rake spec"
95
+ raise "JRuby tests failed" unless result
96
+ end
97
+
98
+ desc "Run each spec in isolation to test for dependency issues"
99
+ task :spec_deps do
100
+ Dir["spec/**/*_spec.rb"].each do |test|
101
+ if !system("spec #{test} &> /dev/null")
102
+ puts "Dependency Issues: #{test}"
103
+ end
104
+ end
105
+ end
106
+
107
+ task :prepare do
108
+ system "ln -s ../../../../.. ./spec/integration/rails/vendor/plugins/webrat"
109
+ end
110
+
111
+ namespace :spec do
112
+ desc "Run the integration specs"
113
+ task :integration => ["integration:rails", "integration:merb", "integration:sinatra", "integration:rack"]
114
+
115
+ namespace :integration do
116
+ desc "Run the Rails integration specs"
117
+ task :rails => ['rails:webrat'] #,'rails:selenium'] currently not running selenium as it doesn't pass.
118
+
119
+ namespace :rails do
120
+ task :selenium do
121
+ Dir.chdir "spec/integration/rails" do
122
+ result = system "rake test_unit:selenium"
123
+ raise "Rails integration tests failed" unless result
124
+ end
125
+ end
126
+
127
+ task :webrat do
128
+ Dir.chdir "spec/integration/rails" do
129
+ result = system "rake test_unit:rails"
130
+ raise "Rails integration tests failed" unless result
131
+ end
132
+ end
133
+ end
134
+
135
+ desc "Run the Merb integration specs"
136
+ task :merb do
137
+ Dir.chdir "spec/integration/merb" do
138
+ result = system "rake spec"
139
+ raise "Merb integration tests failed" unless result
140
+ end
141
+ end
142
+
143
+ desc "Run the Sinatra integration specs"
144
+ task :sinatra do
145
+ Dir.chdir "spec/integration/sinatra" do
146
+ result = system "rake test"
147
+ raise "Sinatra integration tests failed" unless result
148
+ end
149
+ end
150
+
151
+ desc "Run the Sinatra integration specs"
152
+ task :rack do
153
+ Dir.chdir "spec/integration/rack" do
154
+ result = system "rake test"
155
+ raise "Rack integration tests failed" unless result
156
+ end
157
+ end
158
+ end
159
+ end
160
+
161
+ task :default => :spec
162
+
163
+ task :precommit => ["spec", "spec:jruby", "spec:integration"]
164
+
165
+ desc 'Removes trailing whitespace'
166
+ task :whitespace do
167
+ sh %{find . -name '*.rb' -exec sed -i '' 's/ *$//g' {} \\;}
168
+ end
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,31 @@
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
+ if on_java?
14
+ gem "nokogiri", ">= 1.2.4"
15
+ else
16
+ gem "nokogiri", ">= 1.0.6"
17
+ end
18
+
19
+ require "nokogiri"
20
+ require "webrat/core/xml/nokogiri"
21
+ end
22
+
23
+ def self.on_java?
24
+ RUBY_PLATFORM =~ /java/
25
+ end
26
+
27
+ end
28
+
29
+ Webrat.require_xml
30
+
31
+ 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,102 @@
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
+ # Set the timeout for waiting for the browser process to start
58
+ attr_accessor :selenium_browser_startup_timeout
59
+
60
+ # How many redirects to the same URL should be halted as an infinite redirect
61
+ # loop? Defaults to 10
62
+ attr_accessor :infinite_redirect_limit
63
+
64
+ def initialize # :nodoc:
65
+ self.open_error_files = true
66
+ self.parse_with_nokogiri = true
67
+ self.application_environment = :test
68
+ self.application_port = 3001
69
+ self.application_address = 'localhost'
70
+ self.application_framework = :rails
71
+ self.selenium_server_port = 4444
72
+ self.infinite_redirect_limit = 10
73
+ self.selenium_browser_key = '*firefox'
74
+ self.selenium_browser_startup_timeout = 5
75
+ end
76
+
77
+ def parse_with_nokogiri? #:nodoc:
78
+ @parse_with_nokogiri ? true : false
79
+ end
80
+
81
+ def open_error_files? #:nodoc:
82
+ @open_error_files ? true : false
83
+ end
84
+
85
+ # Allows setting of webrat's mode, valid modes are:
86
+ # :rails, :selenium, :rack, :sinatra, :mechanize, :merb
87
+ def mode=(mode)
88
+ @mode = mode.to_sym
89
+
90
+ # This is a temporary hack to support backwards compatibility
91
+ # with Merb 1.0.8 until it's updated to use the new Webrat.configure
92
+ # syntax
93
+ if @mode == :merb
94
+ require("webrat/merb_session")
95
+ else
96
+ require("webrat/#{mode}")
97
+ end
98
+ end
99
+
100
+ end
101
+
102
+ 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,405 @@
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
+ when :mechanize
91
+ { name => value }
92
+ else
93
+ { name => escaped_value }
94
+ end
95
+ end
96
+
97
+ def set(value)
98
+ @value = value
99
+ end
100
+
101
+ def unset
102
+ @value = default_value
103
+ end
104
+
105
+ protected
106
+
107
+ def parse_rails_request_params(params)
108
+ if defined?(ActionController::AbstractRequest)
109
+ ActionController::AbstractRequest.parse_query_parameters(params)
110
+ elsif defined?(ActionController::UrlEncodedPairParser)
111
+ # For Rails > 2.2
112
+ ActionController::UrlEncodedPairParser.parse_query_parameters(params)
113
+ else
114
+ # For Rails > 2.3
115
+ Rack::Utils.parse_nested_query(params)
116
+ end
117
+ end
118
+
119
+ def form
120
+ Form.load(@session, form_element)
121
+ end
122
+
123
+ def form_element
124
+ parent = @element.parent
125
+
126
+ while parent.respond_to?(:parent)
127
+ return parent if parent.name == 'form'
128
+ parent = parent.parent
129
+ end
130
+ end
131
+
132
+ def name
133
+ Webrat::XML.attribute(@element, "name")
134
+ end
135
+
136
+ def escaped_value
137
+ CGI.escape(@value.to_s)
138
+ end
139
+
140
+ def labels
141
+ @labels ||= label_elements.map do |element|
142
+ Label.load(@session, element)
143
+ end
144
+ end
145
+
146
+ def label_elements
147
+ return @label_elements unless @label_elements.nil?
148
+ @label_elements = []
149
+
150
+ parent = @element.parent
151
+ while parent.respond_to?(:parent)
152
+ if parent.name == 'label'
153
+ @label_elements.push parent
154
+ break
155
+ end
156
+ parent = parent.parent
157
+ end
158
+
159
+ unless id.blank?
160
+ @label_elements += Webrat::XML.xpath_search(form.element, ".//label[@for = '#{id}']")
161
+ end
162
+
163
+ @label_elements
164
+ end
165
+
166
+ def default_value
167
+ Webrat::XML.attribute(@element, "value")
168
+ end
169
+
170
+ def replace_param_value(params, oval, nval)
171
+ output = Hash.new
172
+ params.each do |key, value|
173
+ case value
174
+ when Hash
175
+ value = replace_param_value(value, oval, nval)
176
+ when Array
177
+ value = value.map { |o| o == oval ? nval : oval }
178
+ when oval
179
+ value = nval
180
+ end
181
+ output[key] = value
182
+ end
183
+ output
184
+ end
185
+ end
186
+
187
+ class ButtonField < Field #:nodoc:
188
+
189
+ def self.xpath_search
190
+ [".//button", ".//input[@type = 'submit']", ".//input[@type = 'button']", ".//input[@type = 'image']"]
191
+ end
192
+
193
+ def to_param
194
+ return nil if @value.nil?
195
+ super
196
+ end
197
+
198
+ def default_value
199
+ nil
200
+ end
201
+
202
+ def click
203
+ raise_error_if_disabled
204
+ set(Webrat::XML.attribute(@element, "value")) unless Webrat::XML.attribute(@element, "name").blank?
205
+ form.submit
206
+ end
207
+
208
+ end
209
+
210
+ class HiddenField < Field #:nodoc:
211
+
212
+ def self.xpath_search
213
+ ".//input[@type = 'hidden']"
214
+ end
215
+
216
+ def to_param
217
+ if collection_name?
218
+ super
219
+ else
220
+ checkbox_with_same_name = form.field_named(name, CheckboxField)
221
+
222
+ if checkbox_with_same_name.to_param.blank?
223
+ super
224
+ else
225
+ nil
226
+ end
227
+ end
228
+ end
229
+
230
+ protected
231
+
232
+ def collection_name?
233
+ name =~ /\[\]/
234
+ end
235
+
236
+ end
237
+
238
+ class CheckboxField < Field #:nodoc:
239
+
240
+ def self.xpath_search
241
+ ".//input[@type = 'checkbox']"
242
+ end
243
+
244
+ def to_param
245
+ return nil if @value.nil?
246
+ super
247
+ end
248
+
249
+ def check
250
+ raise_error_if_disabled
251
+ set(Webrat::XML.attribute(@element, "value") || "on")
252
+ end
253
+
254
+ def checked?
255
+ Webrat::XML.attribute(@element, "checked") == "checked"
256
+ end
257
+
258
+ def uncheck
259
+ raise_error_if_disabled
260
+ set(nil)
261
+ end
262
+
263
+ protected
264
+
265
+ def default_value
266
+ if Webrat::XML.attribute(@element, "checked") == "checked"
267
+ Webrat::XML.attribute(@element, "value") || "on"
268
+ else
269
+ nil
270
+ end
271
+ end
272
+
273
+ end
274
+
275
+ class PasswordField < Field #:nodoc:
276
+
277
+ def self.xpath_search
278
+ ".//input[@type = 'password']"
279
+ end
280
+
281
+ end
282
+
283
+ class RadioField < Field #:nodoc:
284
+
285
+ def self.xpath_search
286
+ ".//input[@type = 'radio']"
287
+ end
288
+
289
+ def to_param
290
+ return nil if @value.nil?
291
+ super
292
+ end
293
+
294
+ def choose
295
+ raise_error_if_disabled
296
+ other_options.each do |option|
297
+ option.set(nil)
298
+ end
299
+
300
+ set(Webrat::XML.attribute(@element, "value") || "on")
301
+ end
302
+
303
+ def checked?
304
+ Webrat::XML.attribute(@element, "checked") == "checked"
305
+ end
306
+
307
+ protected
308
+
309
+ def other_options
310
+ form.fields.select { |f| f.name == name }
311
+ end
312
+
313
+ def default_value
314
+ if Webrat::XML.attribute(@element, "checked") == "checked"
315
+ Webrat::XML.attribute(@element, "value") || "on"
316
+ else
317
+ nil
318
+ end
319
+ end
320
+
321
+ end
322
+
323
+ class TextareaField < Field #:nodoc:
324
+
325
+ def self.xpath_search
326
+ ".//textarea"
327
+ end
328
+
329
+ protected
330
+
331
+ def default_value
332
+ Webrat::XML.inner_html(@element)
333
+ end
334
+
335
+ end
336
+
337
+ class FileField < Field #:nodoc:
338
+
339
+ def self.xpath_search
340
+ ".//input[@type = 'file']"
341
+ end
342
+
343
+ attr_accessor :content_type
344
+
345
+ def set(value, content_type = nil)
346
+ super(value)
347
+ @content_type = content_type
348
+ end
349
+
350
+ def to_param
351
+ if @value.nil?
352
+ super
353
+ else
354
+ replace_param_value(super, @value, test_uploaded_file)
355
+ end
356
+ end
357
+
358
+ protected
359
+
360
+ def test_uploaded_file
361
+ if content_type
362
+ ActionController::TestUploadedFile.new(@value, content_type)
363
+ else
364
+ ActionController::TestUploadedFile.new(@value)
365
+ end
366
+ end
367
+
368
+ end
369
+
370
+ class TextField < Field #:nodoc:
371
+ def self.xpath_search
372
+ [".//input[@type = 'text']", ".//input[not(@type)]"]
373
+ end
374
+ end
375
+
376
+ class ResetField < Field #:nodoc:
377
+ def self.xpath_search
378
+ ".//input[@type = 'reset']"
379
+ end
380
+ end
381
+
382
+ class SelectField < Field #:nodoc:
383
+
384
+ def self.xpath_search
385
+ ".//select"
386
+ end
387
+
388
+ def options
389
+ @options ||= SelectOption.load_all(@session, @element)
390
+ end
391
+
392
+ protected
393
+
394
+ def default_value
395
+ selected_options = Webrat::XML.xpath_search(@element, ".//option[@selected = 'selected']")
396
+ selected_options = Webrat::XML.xpath_search(@element, ".//option[position() = 1]") if selected_options.empty?
397
+
398
+ selected_options.map do |option|
399
+ return "" if option.nil?
400
+ Webrat::XML.attribute(option, "value") || Webrat::XML.inner_html(option)
401
+ end.uniq
402
+ end
403
+
404
+ end
405
+ end