rcarvalho-capybara 0.4.1.1

Sign up to get free protection for your applications and to get access to all the features.
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