rcarvalho-capybara 0.4.1.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 (100) hide show
  1. data/History.txt +202 -0
  2. data/README.rdoc +540 -0
  3. data/lib/capybara.rb +231 -0
  4. data/lib/capybara/cucumber.rb +32 -0
  5. data/lib/capybara/driver/base.rb +60 -0
  6. data/lib/capybara/driver/celerity_driver.rb +164 -0
  7. data/lib/capybara/driver/culerity_driver.rb +26 -0
  8. data/lib/capybara/driver/node.rb +78 -0
  9. data/lib/capybara/driver/rack_test_driver.rb +303 -0
  10. data/lib/capybara/driver/selenium_driver.rb +165 -0
  11. data/lib/capybara/dsl.rb +109 -0
  12. data/lib/capybara/node/actions.rb +160 -0
  13. data/lib/capybara/node/base.rb +47 -0
  14. data/lib/capybara/node/document.rb +17 -0
  15. data/lib/capybara/node/element.rb +182 -0
  16. data/lib/capybara/node/finders.rb +201 -0
  17. data/lib/capybara/node/matchers.rb +391 -0
  18. data/lib/capybara/node/simple.rb +116 -0
  19. data/lib/capybara/rails.rb +17 -0
  20. data/lib/capybara/rspec.rb +18 -0
  21. data/lib/capybara/selector.rb +70 -0
  22. data/lib/capybara/server.rb +90 -0
  23. data/lib/capybara/session.rb +281 -0
  24. data/lib/capybara/spec/driver.rb +243 -0
  25. data/lib/capybara/spec/fixtures/capybara.jpg +0 -0
  26. data/lib/capybara/spec/fixtures/test_file.txt +1 -0
  27. data/lib/capybara/spec/public/jquery-ui.js +35 -0
  28. data/lib/capybara/spec/public/jquery.js +19 -0
  29. data/lib/capybara/spec/public/test.js +33 -0
  30. data/lib/capybara/spec/session.rb +110 -0
  31. data/lib/capybara/spec/session/all_spec.rb +78 -0
  32. data/lib/capybara/spec/session/attach_file_spec.rb +70 -0
  33. data/lib/capybara/spec/session/check_spec.rb +65 -0
  34. data/lib/capybara/spec/session/choose_spec.rb +26 -0
  35. data/lib/capybara/spec/session/click_button_spec.rb +252 -0
  36. data/lib/capybara/spec/session/click_link_or_button_spec.rb +36 -0
  37. data/lib/capybara/spec/session/click_link_spec.rb +113 -0
  38. data/lib/capybara/spec/session/current_url_spec.rb +15 -0
  39. data/lib/capybara/spec/session/fill_in_spec.rb +119 -0
  40. data/lib/capybara/spec/session/find_button_spec.rb +18 -0
  41. data/lib/capybara/spec/session/find_by_id_spec.rb +18 -0
  42. data/lib/capybara/spec/session/find_field_spec.rb +26 -0
  43. data/lib/capybara/spec/session/find_link_spec.rb +19 -0
  44. data/lib/capybara/spec/session/find_spec.rb +121 -0
  45. data/lib/capybara/spec/session/first_spec.rb +72 -0
  46. data/lib/capybara/spec/session/has_button_spec.rb +32 -0
  47. data/lib/capybara/spec/session/has_content_spec.rb +106 -0
  48. data/lib/capybara/spec/session/has_css_spec.rb +213 -0
  49. data/lib/capybara/spec/session/has_field_spec.rb +156 -0
  50. data/lib/capybara/spec/session/has_link_spec.rb +37 -0
  51. data/lib/capybara/spec/session/has_select_spec.rb +129 -0
  52. data/lib/capybara/spec/session/has_selector_spec.rb +129 -0
  53. data/lib/capybara/spec/session/has_table_spec.rb +96 -0
  54. data/lib/capybara/spec/session/has_xpath_spec.rb +123 -0
  55. data/lib/capybara/spec/session/headers.rb +19 -0
  56. data/lib/capybara/spec/session/javascript.rb +223 -0
  57. data/lib/capybara/spec/session/response_code.rb +19 -0
  58. data/lib/capybara/spec/session/select_spec.rb +105 -0
  59. data/lib/capybara/spec/session/uncheck_spec.rb +21 -0
  60. data/lib/capybara/spec/session/unselect_spec.rb +61 -0
  61. data/lib/capybara/spec/session/within_spec.rb +160 -0
  62. data/lib/capybara/spec/test_app.rb +117 -0
  63. data/lib/capybara/spec/views/buttons.erb +4 -0
  64. data/lib/capybara/spec/views/fieldsets.erb +29 -0
  65. data/lib/capybara/spec/views/form.erb +348 -0
  66. data/lib/capybara/spec/views/frame_one.erb +8 -0
  67. data/lib/capybara/spec/views/frame_two.erb +8 -0
  68. data/lib/capybara/spec/views/popup_one.erb +8 -0
  69. data/lib/capybara/spec/views/popup_two.erb +8 -0
  70. data/lib/capybara/spec/views/postback.erb +13 -0
  71. data/lib/capybara/spec/views/tables.erb +122 -0
  72. data/lib/capybara/spec/views/with_html.erb +69 -0
  73. data/lib/capybara/spec/views/with_js.erb +39 -0
  74. data/lib/capybara/spec/views/with_scope.erb +36 -0
  75. data/lib/capybara/spec/views/with_simple_html.erb +1 -0
  76. data/lib/capybara/spec/views/within_frames.erb +10 -0
  77. data/lib/capybara/spec/views/within_popups.erb +25 -0
  78. data/lib/capybara/util/save_and_open_page.rb +40 -0
  79. data/lib/capybara/util/timeout.rb +27 -0
  80. data/lib/capybara/version.rb +3 -0
  81. data/spec/basic_node_spec.rb +77 -0
  82. data/spec/capybara_spec.rb +46 -0
  83. data/spec/driver/celerity_driver_spec.rb +13 -0
  84. data/spec/driver/culerity_driver_spec.rb +14 -0
  85. data/spec/driver/rack_test_driver_spec.rb +84 -0
  86. data/spec/driver/remote_culerity_driver_spec.rb +22 -0
  87. data/spec/driver/remote_selenium_driver_spec.rb +16 -0
  88. data/spec/driver/selenium_driver_spec.rb +14 -0
  89. data/spec/dsl_spec.rb +157 -0
  90. data/spec/rspec_spec.rb +47 -0
  91. data/spec/save_and_open_page_spec.rb +159 -0
  92. data/spec/server_spec.rb +85 -0
  93. data/spec/session/celerity_session_spec.rb +24 -0
  94. data/spec/session/culerity_session_spec.rb +26 -0
  95. data/spec/session/rack_test_session_spec.rb +44 -0
  96. data/spec/session/selenium_session_spec.rb +26 -0
  97. data/spec/spec_helper.rb +40 -0
  98. data/spec/string_spec.rb +77 -0
  99. data/spec/timeout_spec.rb +28 -0
  100. metadata +343 -0
@@ -0,0 +1,231 @@
1
+ require 'timeout'
2
+ require 'nokogiri'
3
+ require 'xpath'
4
+ module Capybara
5
+ class CapybaraError < StandardError; end
6
+ class DriverNotFoundError < CapybaraError; end
7
+ class ElementNotFound < CapybaraError; end
8
+ class UnselectNotAllowed < CapybaraError; end
9
+ class NotSupportedByDriverError < CapybaraError; end
10
+ class TimeoutError < CapybaraError; end
11
+ class LocateHiddenElementError < CapybaraError; end
12
+ class InfiniteRedirectError < TimeoutError; end
13
+
14
+ class << self
15
+ attr_accessor :asset_root, :app_host, :run_server, :default_host
16
+ attr_accessor :server_port, :server_boot_timeout
17
+ attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements
18
+ attr_accessor :save_and_open_page_path
19
+
20
+ ##
21
+ #
22
+ # Configure Capybara to suit your needs.
23
+ #
24
+ # Capybara.configure do |config|
25
+ # config.run_server = false
26
+ # config.app_host = 'http://www.google.com'
27
+ # end
28
+ #
29
+ # === Configurable options
30
+ #
31
+ # [asset_root = String] Where static assets are located, used by save_and_open_page
32
+ # [app_host = String] The default host to use when giving a relative URL to visit
33
+ # [run_server = Boolean] Whether to start a Rack server for the given Rack app (Default: true)
34
+ # [default_selector = :css/:xpath] Methods which take a selector use the given type by default (Default: CSS)
35
+ # [default_wait_time = Integer] The number of seconds to wait for asynchronous processes to finish (Default: 2)
36
+ # [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: false)
37
+ #
38
+ # === DSL Options
39
+ #
40
+ # when using capybara/dsl, the following options are also available:
41
+ #
42
+ # [default_driver = Symbol] The name of the driver to use by default. (Default: :rack_test)
43
+ # [javascript_driver = Symbol] The name of a driver to use for JavaScript enabled tests. (Default: :selenium)
44
+ #
45
+ def configure
46
+ yield self
47
+ end
48
+
49
+ ##
50
+ #
51
+ # Register a new driver for Capybara.
52
+ #
53
+ # Capybara.register_driver :rack_test do |app|
54
+ # Capybara::Driver::RackTest.new(app)
55
+ # end
56
+ #
57
+ # @param [Symbol] name The name of the new driver
58
+ # @yield [app] This block takes a rack app and returns a Capybara driver
59
+ # @yieldparam [<Rack>] app The rack application that this driver runs agains. May be nil.
60
+ # @yieldreturn [Capybara::Driver::Base] A Capybara driver instance
61
+ #
62
+ def register_driver(name, &block)
63
+ drivers[name] = block
64
+ end
65
+
66
+ ##
67
+ #
68
+ # Add a new selector to Capybara. Selectors can be used by various methods in Capybara
69
+ # to find certain elements on the page in a more convenient way. For example adding a
70
+ # selector to find certain table rows might look like this:
71
+ #
72
+ # Capybara.add_selector(:row) do
73
+ # xpath { |num| ".//tbody/tr[#{num}]" }
74
+ # end
75
+ #
76
+ # This makes it possible to use this selector in a variety of ways:
77
+ #
78
+ # find(:row, 3)
79
+ # page.find('table#myTable').find(:row, 3).text
80
+ # page.find('table#myTable').has_selector?(:row, 3)
81
+ # within(:row, 3) { page.should have_content('$100.000') }
82
+ #
83
+ # It might be convenient to specify that the selector is automatically chosen for certain
84
+ # values. This way you don't have to explicitely specify that you are looking for a row, or
85
+ # an id. Let's say we want Capybara to treat any Symbols sent into methods like find to be
86
+ # treated as though they were element ids. We could achieve this like so:
87
+ #
88
+ # Capybara.add_selector(:id) do
89
+ # xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
90
+ # match { |value| value.is_a?(Symbol) }
91
+ # end
92
+ #
93
+ # Now we can retrieve elements by id like this:
94
+ #
95
+ # find(:post_123)
96
+ #
97
+ # Note that this particular selector already ships with Capybara.
98
+ #
99
+ # @param [Symbol] name The name of the selector to add
100
+ # @yield A block executed in the context of the new {Capybara::Selector}
101
+ #
102
+ def add_selector(name, &block)
103
+ Capybara::Selector.add(name, &block)
104
+ end
105
+
106
+ def drivers
107
+ @drivers ||= {}
108
+ end
109
+
110
+ ##
111
+ #
112
+ # Register a proc that Capybara will call to run the Rack application.
113
+ #
114
+ # Capybara.server do |app, port|
115
+ # require 'rack/handler/mongrel'
116
+ # Rack::Handler::Mongrel.run(app, :Port => port)
117
+ # end
118
+ #
119
+ # By default, Capybara will try to run thin, falling back to webrick.
120
+ #
121
+ # @yield [app, port] This block recieves a rack app and port and should run a Rack handler
122
+ #
123
+ def server(&block)
124
+ if block_given?
125
+ @server = block
126
+ else
127
+ @server
128
+ end
129
+ end
130
+
131
+ ##
132
+ #
133
+ # Wraps the given string, which should contain an HTML document or fragment
134
+ # in a {Capybara::Node::Simple} which exposes all {Capybara::Node::Matchers} and
135
+ # {Capybara::Node::Finders}. This allows you to query any string containing
136
+ # HTML in the exact same way you would query the current document in a Capybara
137
+ # session. For example:
138
+ #
139
+ # node = Capybara.string <<-HTML
140
+ # <ul>
141
+ # <li id="home">Home</li>
142
+ # <li id="projects">Projects</li>
143
+ # </ul>
144
+ # HTML
145
+ #
146
+ # node.find('#projects').text # => 'Projects'
147
+ # node.has_selector?('li#home', :text => 'Home')
148
+ # node.has_selector?(:projects)
149
+ # node.find('ul').find('li').text # => 'Home'
150
+ #
151
+ # @param [String] html An html fragment or document
152
+ # @return [Capybara::Node::Simple] A node which has Capybara's finders and matchers
153
+ #
154
+ def string(html)
155
+ Capybara::Node::Simple.new(html)
156
+ end
157
+
158
+ ##
159
+ #
160
+ # Runs Capybara's default server for the given application and port
161
+ # under most circumstances you should not have to call this method
162
+ # manually.
163
+ #
164
+ # @param [Rack Application] app The rack application to run
165
+ # @param [Fixnum] port The port to run the application on
166
+ #
167
+ def run_default_server(app, port)
168
+ begin
169
+ require 'rack/handler/thin'
170
+ Thin::Logging.silent = true
171
+ Rack::Handler::Thin.run(app, :Port => port)
172
+ rescue LoadError
173
+ require 'rack/handler/webrick'
174
+ Rack::Handler::WEBrick.run(app, :Port => port, :AccessLog => [], :Logger => WEBrick::Log::new(nil, 0))
175
+ end
176
+ end
177
+
178
+ def deprecate(method, alternate_method)
179
+ warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead"
180
+ end
181
+ end
182
+
183
+ autoload :Server, 'capybara/server'
184
+ autoload :Session, 'capybara/session'
185
+ autoload :Selector, 'capybara/selector'
186
+ autoload :VERSION, 'capybara/version'
187
+
188
+ module Node
189
+ autoload :Base, 'capybara/node/base'
190
+ autoload :Simple, 'capybara/node/simple'
191
+ autoload :Element, 'capybara/node/element'
192
+ autoload :Document, 'capybara/node/document'
193
+ autoload :Finders, 'capybara/node/finders'
194
+ autoload :Matchers, 'capybara/node/matchers'
195
+ autoload :Actions, 'capybara/node/actions'
196
+ end
197
+
198
+ module Driver
199
+ autoload :Base, 'capybara/driver/base'
200
+ autoload :Node, 'capybara/driver/node'
201
+ autoload :RackTest, 'capybara/driver/rack_test_driver'
202
+ autoload :Celerity, 'capybara/driver/celerity_driver'
203
+ autoload :Culerity, 'capybara/driver/culerity_driver'
204
+ autoload :Selenium, 'capybara/driver/selenium_driver'
205
+ end
206
+ end
207
+
208
+ Capybara.configure do |config|
209
+ config.run_server = true
210
+ config.server {|app, port| Capybara.run_default_server(app, port)}
211
+ config.server_boot_timeout = 10
212
+ config.default_selector = :css
213
+ config.default_wait_time = 2
214
+ config.ignore_hidden_elements = false
215
+ end
216
+
217
+ Capybara.register_driver :rack_test do |app|
218
+ Capybara::Driver::RackTest.new(app)
219
+ end
220
+
221
+ Capybara.register_driver :celerity do |app|
222
+ Capybara::Driver::Celerity.new(app)
223
+ end
224
+
225
+ Capybara.register_driver :culerity do |app|
226
+ Capybara::Driver::Culerity.new(app)
227
+ end
228
+
229
+ Capybara.register_driver :selenium do |app|
230
+ Capybara::Driver::Selenium.new(app)
231
+ end
@@ -0,0 +1,32 @@
1
+ require 'capybara'
2
+ require 'capybara/dsl'
3
+
4
+ World(Capybara)
5
+
6
+ After do
7
+ Capybara.reset_sessions!
8
+ end
9
+
10
+ Before('@javascript') do
11
+ Capybara.current_driver = Capybara.javascript_driver
12
+ end
13
+
14
+ Before('@selenium') do
15
+ Capybara.current_driver = :selenium
16
+ end
17
+
18
+ Before('@celerity') do
19
+ Capybara.current_driver = :celerity
20
+ end
21
+
22
+ Before('@culerity') do
23
+ Capybara.current_driver = :culerity
24
+ end
25
+
26
+ Before('@rack_test') do
27
+ Capybara.current_driver = :rack_test
28
+ end
29
+
30
+ After do
31
+ Capybara.use_default_driver
32
+ end
@@ -0,0 +1,60 @@
1
+ class Capybara::Driver::Base
2
+ def current_url
3
+ raise NotImplementedError
4
+ end
5
+
6
+ def visit(path)
7
+ raise NotImplementedError
8
+ end
9
+
10
+ def find(query)
11
+ raise NotImplementedError
12
+ end
13
+
14
+ def source
15
+ raise NotImplementedError
16
+ end
17
+
18
+ def body
19
+ raise NotImplementedError
20
+ end
21
+
22
+ def execute_script(script)
23
+ raise Capybara::NotSupportedByDriverError
24
+ end
25
+
26
+ def evaluate_script(script)
27
+ raise Capybara::NotSupportedByDriverError
28
+ end
29
+
30
+ def response_headers
31
+ raise Capybara::NotSupportedByDriverError
32
+ end
33
+
34
+ def status_code
35
+ raise Capybara::NotSupportedByDriverError
36
+ end
37
+
38
+ def within_frame(frame_id)
39
+ raise Capybara::NotSupportedByDriverError
40
+ end
41
+
42
+ def within_window(handle)
43
+ raise Capybara::NotSupportedByDriverError
44
+ end
45
+
46
+ def wait?
47
+ false
48
+ end
49
+
50
+ def wait_until(*args)
51
+ end
52
+
53
+ def reset!
54
+ end
55
+
56
+ def has_shortcircuit_timeout?
57
+ false
58
+ end
59
+
60
+ end
@@ -0,0 +1,164 @@
1
+ class Capybara::Driver::Celerity < Capybara::Driver::Base
2
+ class Node < Capybara::Driver::Node
3
+ def text
4
+ native.text
5
+ end
6
+
7
+ def [](name)
8
+ value = native.attribute_value(name.to_sym)
9
+ return value if value and not value.to_s.empty?
10
+ end
11
+
12
+ def value
13
+ if tag_name == "select" and native.multiple?
14
+ find(".//option[@selected]").map { |n| if n.has_value? then n.value else n.text end }
15
+ else
16
+ native.value
17
+ end
18
+ end
19
+
20
+ def set(value)
21
+ native.set(value)
22
+ end
23
+
24
+ def select_option
25
+ native.click
26
+ end
27
+
28
+ def unselect_option
29
+ unless select_node.native.multiple?
30
+ raise Capybara::UnselectNotAllowed, "Cannot unselect option from single select box."
31
+ end
32
+
33
+ # FIXME: couldn't find a clean way to unselect, so clear and reselect
34
+ selected_nodes = select_node.find('.//option[@selected]')
35
+ select_node.native.clear
36
+ selected_nodes.each { |n| n.click unless n.path == path }
37
+ end
38
+
39
+ def click
40
+ native.click
41
+ end
42
+
43
+ def drag_to(element)
44
+ native.fire_event('mousedown')
45
+ element.native.fire_event('mousemove')
46
+ element.native.fire_event('mouseup')
47
+ end
48
+
49
+ def tag_name
50
+ # FIXME: this might be the dumbest way ever of getting the tag name
51
+ # there has to be something better...
52
+ native.to_xml[/^\s*<([a-z0-9\-\:]+)/, 1]
53
+ end
54
+
55
+ def visible?
56
+ native.visible?
57
+ end
58
+
59
+ def checked?
60
+ native.checked?
61
+ rescue # https://github.com/langalex/culerity/issues/issue/33
62
+ false
63
+ end
64
+
65
+ def selected?
66
+ native.selected?
67
+ rescue # https://github.com/langalex/culerity/issues/issue/33
68
+ false
69
+ end
70
+
71
+ def path
72
+ native.xpath
73
+ end
74
+
75
+ def trigger(event)
76
+ native.fire_event(event.to_s)
77
+ end
78
+
79
+ def find(locator)
80
+ noko_node = Nokogiri::HTML(driver.body).xpath(native.xpath).first
81
+ all_nodes = noko_node.xpath(locator).map { |n| n.path }.join(' | ')
82
+ if all_nodes.empty? then [] else driver.find(all_nodes) end
83
+ end
84
+
85
+ protected
86
+
87
+ # a reference to the select node if this is an option node
88
+ def select_node
89
+ find('./ancestor::select').first
90
+ end
91
+
92
+ def has_value?
93
+ native.object.hasAttribute('value')
94
+ end
95
+ end
96
+
97
+ attr_reader :app, :rack_server, :options
98
+
99
+ def initialize(app, options={})
100
+ @app = app
101
+ @options = options
102
+ @rack_server = Capybara::Server.new(@app)
103
+ @rack_server.boot if Capybara.run_server
104
+ end
105
+
106
+ def visit(path)
107
+ browser.goto(url(path))
108
+ end
109
+
110
+ def current_url
111
+ browser.url
112
+ end
113
+
114
+ def source
115
+ browser.html
116
+ end
117
+
118
+ def body
119
+ browser.document.as_xml
120
+ end
121
+
122
+ def response_headers
123
+ browser.response_headers
124
+ end
125
+
126
+ def status_code
127
+ browser.status_code
128
+ end
129
+
130
+ def find(selector)
131
+ browser.elements_by_xpath(selector).map { |node| Node.new(self, node) }
132
+ end
133
+
134
+ def wait?; true; end
135
+
136
+ def execute_script(script)
137
+ browser.execute_script script
138
+ nil
139
+ end
140
+
141
+ def evaluate_script(script)
142
+ browser.execute_script "#{script}"
143
+ end
144
+
145
+ def browser
146
+ unless @_browser
147
+ require 'celerity'
148
+ @_browser = ::Celerity::Browser.new(options)
149
+ end
150
+
151
+ @_browser
152
+ end
153
+
154
+ def reset!
155
+ browser.clear_cookies
156
+ end
157
+
158
+ private
159
+
160
+ def url(path)
161
+ rack_server.url(path)
162
+ end
163
+
164
+ end