bbc-capybara 1.1.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 (107) hide show
  1. data/History.txt +325 -0
  2. data/License.txt +22 -0
  3. data/README.md +815 -0
  4. data/lib/capybara.rb +368 -0
  5. data/lib/capybara/cucumber.rb +25 -0
  6. data/lib/capybara/driver/base.rb +64 -0
  7. data/lib/capybara/driver/node.rb +74 -0
  8. data/lib/capybara/dsl.rb +50 -0
  9. data/lib/capybara/node/actions.rb +146 -0
  10. data/lib/capybara/node/base.rb +63 -0
  11. data/lib/capybara/node/document.rb +25 -0
  12. data/lib/capybara/node/element.rb +201 -0
  13. data/lib/capybara/node/finders.rb +154 -0
  14. data/lib/capybara/node/matchers.rb +442 -0
  15. data/lib/capybara/node/simple.rb +132 -0
  16. data/lib/capybara/query.rb +63 -0
  17. data/lib/capybara/rack_test/browser.rb +126 -0
  18. data/lib/capybara/rack_test/driver.rb +80 -0
  19. data/lib/capybara/rack_test/form.rb +80 -0
  20. data/lib/capybara/rack_test/node.rb +121 -0
  21. data/lib/capybara/rails.rb +17 -0
  22. data/lib/capybara/rspec.rb +26 -0
  23. data/lib/capybara/rspec/features.rb +22 -0
  24. data/lib/capybara/rspec/matchers.rb +152 -0
  25. data/lib/capybara/selector.rb +156 -0
  26. data/lib/capybara/selenium/driver.rb +169 -0
  27. data/lib/capybara/selenium/node.rb +91 -0
  28. data/lib/capybara/server.rb +87 -0
  29. data/lib/capybara/session.rb +322 -0
  30. data/lib/capybara/spec/driver.rb +329 -0
  31. data/lib/capybara/spec/fixtures/capybara.jpg +3 -0
  32. data/lib/capybara/spec/fixtures/test_file.txt +1 -0
  33. data/lib/capybara/spec/public/jquery-ui.js +791 -0
  34. data/lib/capybara/spec/public/jquery.js +9046 -0
  35. data/lib/capybara/spec/public/test.js +43 -0
  36. data/lib/capybara/spec/session.rb +148 -0
  37. data/lib/capybara/spec/session/all_spec.rb +78 -0
  38. data/lib/capybara/spec/session/attach_file_spec.rb +76 -0
  39. data/lib/capybara/spec/session/check_spec.rb +68 -0
  40. data/lib/capybara/spec/session/choose_spec.rb +29 -0
  41. data/lib/capybara/spec/session/click_button_spec.rb +305 -0
  42. data/lib/capybara/spec/session/click_link_or_button_spec.rb +37 -0
  43. data/lib/capybara/spec/session/click_link_spec.rb +120 -0
  44. data/lib/capybara/spec/session/current_url_spec.rb +83 -0
  45. data/lib/capybara/spec/session/fill_in_spec.rb +127 -0
  46. data/lib/capybara/spec/session/find_button_spec.rb +18 -0
  47. data/lib/capybara/spec/session/find_by_id_spec.rb +18 -0
  48. data/lib/capybara/spec/session/find_field_spec.rb +26 -0
  49. data/lib/capybara/spec/session/find_link_spec.rb +19 -0
  50. data/lib/capybara/spec/session/find_spec.rb +168 -0
  51. data/lib/capybara/spec/session/first_spec.rb +105 -0
  52. data/lib/capybara/spec/session/has_button_spec.rb +32 -0
  53. data/lib/capybara/spec/session/has_css_spec.rb +243 -0
  54. data/lib/capybara/spec/session/has_field_spec.rb +192 -0
  55. data/lib/capybara/spec/session/has_link_spec.rb +37 -0
  56. data/lib/capybara/spec/session/has_select_spec.rb +129 -0
  57. data/lib/capybara/spec/session/has_selector_spec.rb +129 -0
  58. data/lib/capybara/spec/session/has_table_spec.rb +34 -0
  59. data/lib/capybara/spec/session/has_text_spec.rb +138 -0
  60. data/lib/capybara/spec/session/has_xpath_spec.rb +123 -0
  61. data/lib/capybara/spec/session/headers.rb +19 -0
  62. data/lib/capybara/spec/session/javascript.rb +312 -0
  63. data/lib/capybara/spec/session/response_code.rb +19 -0
  64. data/lib/capybara/spec/session/select_spec.rb +119 -0
  65. data/lib/capybara/spec/session/text_spec.rb +24 -0
  66. data/lib/capybara/spec/session/uncheck_spec.rb +21 -0
  67. data/lib/capybara/spec/session/unselect_spec.rb +67 -0
  68. data/lib/capybara/spec/session/within_spec.rb +178 -0
  69. data/lib/capybara/spec/test_app.rb +156 -0
  70. data/lib/capybara/spec/views/buttons.erb +4 -0
  71. data/lib/capybara/spec/views/fieldsets.erb +29 -0
  72. data/lib/capybara/spec/views/form.erb +366 -0
  73. data/lib/capybara/spec/views/frame_one.erb +8 -0
  74. data/lib/capybara/spec/views/frame_two.erb +8 -0
  75. data/lib/capybara/spec/views/header_links.erb +7 -0
  76. data/lib/capybara/spec/views/host_links.erb +12 -0
  77. data/lib/capybara/spec/views/popup_one.erb +8 -0
  78. data/lib/capybara/spec/views/popup_two.erb +8 -0
  79. data/lib/capybara/spec/views/postback.erb +13 -0
  80. data/lib/capybara/spec/views/tables.erb +62 -0
  81. data/lib/capybara/spec/views/with_html.erb +75 -0
  82. data/lib/capybara/spec/views/with_html_entities.erb +1 -0
  83. data/lib/capybara/spec/views/with_js.erb +53 -0
  84. data/lib/capybara/spec/views/with_scope.erb +36 -0
  85. data/lib/capybara/spec/views/with_simple_html.erb +1 -0
  86. data/lib/capybara/spec/views/within_frames.erb +10 -0
  87. data/lib/capybara/spec/views/within_popups.erb +25 -0
  88. data/lib/capybara/util/save_and_open_page.rb +45 -0
  89. data/lib/capybara/util/timeout.rb +27 -0
  90. data/lib/capybara/version.rb +3 -0
  91. data/spec/basic_node_spec.rb +89 -0
  92. data/spec/capybara_spec.rb +46 -0
  93. data/spec/driver/rack_test_driver_spec.rb +90 -0
  94. data/spec/driver/selenium_driver_spec.rb +55 -0
  95. data/spec/dsl_spec.rb +255 -0
  96. data/spec/fixtures/selenium_driver_rspec_failure.rb +8 -0
  97. data/spec/fixtures/selenium_driver_rspec_success.rb +8 -0
  98. data/spec/rspec/features_spec.rb +43 -0
  99. data/spec/rspec/matchers_spec.rb +564 -0
  100. data/spec/rspec_spec.rb +51 -0
  101. data/spec/save_and_open_page_spec.rb +155 -0
  102. data/spec/server_spec.rb +74 -0
  103. data/spec/session/rack_test_session_spec.rb +61 -0
  104. data/spec/session/selenium_session_spec.rb +26 -0
  105. data/spec/spec_helper.rb +31 -0
  106. data/spec/timeout_spec.rb +28 -0
  107. metadata +297 -0
@@ -0,0 +1,368 @@
1
+ require 'timeout'
2
+ require 'nokogiri'
3
+ require 'xpath'
4
+
5
+ module Capybara
6
+ class CapybaraError < StandardError; end
7
+ class DriverNotFoundError < CapybaraError; end
8
+ class FrozenInTime < CapybaraError; end
9
+ class ElementNotFound < CapybaraError; end
10
+ class ExpectationNotMet < ElementNotFound; end
11
+ class FileNotFound < CapybaraError; end
12
+ class UnselectNotAllowed < CapybaraError; end
13
+ class NotSupportedByDriverError < CapybaraError; end
14
+ class TimeoutError < CapybaraError; end
15
+ class LocateHiddenElementError < CapybaraError; end
16
+ class InfiniteRedirectError < TimeoutError; end
17
+
18
+ class << self
19
+ attr_accessor :asset_root, :app_host, :run_server, :default_host
20
+ attr_accessor :server_host, :server_port
21
+ attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements, :prefer_visible_elements
22
+ attr_accessor :save_and_open_page_path, :automatic_reload
23
+ attr_writer :default_driver, :current_driver, :javascript_driver, :session_name
24
+ attr_accessor :app
25
+
26
+ ##
27
+ #
28
+ # Configure Capybara to suit your needs.
29
+ #
30
+ # Capybara.configure do |config|
31
+ # config.run_server = false
32
+ # config.app_host = 'http://www.google.com'
33
+ # end
34
+ #
35
+ # === Configurable options
36
+ #
37
+ # [asset_root = String] Where static assets are located, used by save_and_open_page
38
+ # [app_host = String] The default host to use when giving a relative URL to visit
39
+ # [run_server = Boolean] Whether to start a Rack server for the given Rack app (Default: true)
40
+ # [default_selector = :css/:xpath] Methods which take a selector use the given type by default (Default: CSS)
41
+ # [default_wait_time = Integer] The number of seconds to wait for asynchronous processes to finish (Default: 2)
42
+ # [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: false)
43
+ # [prefer_visible_elements = Boolean] Whether to prefer visible elements over hidden elements (Default: true)
44
+ # [automatic_reload = Boolean] Whether to automatically reload elements as Capybara is waiting (Default: true)
45
+ # [save_and_open_page_path = String] Where to put pages saved through save_and_open_page (Default: Dir.pwd)
46
+ #
47
+ # === DSL Options
48
+ #
49
+ # when using capybara/dsl, the following options are also available:
50
+ #
51
+ # [default_driver = Symbol] The name of the driver to use by default. (Default: :rack_test)
52
+ # [javascript_driver = Symbol] The name of a driver to use for JavaScript enabled tests. (Default: :selenium)
53
+ #
54
+ def configure
55
+ yield self
56
+ end
57
+
58
+ ##
59
+ #
60
+ # Register a new driver for Capybara.
61
+ #
62
+ # Capybara.register_driver :rack_test do |app|
63
+ # Capybara::Driver::RackTest.new(app)
64
+ # end
65
+ #
66
+ # @param [Symbol] name The name of the new driver
67
+ # @yield [app] This block takes a rack app and returns a Capybara driver
68
+ # @yieldparam [<Rack>] app The rack application that this driver runs agains. May be nil.
69
+ # @yieldreturn [Capybara::Driver::Base] A Capybara driver instance
70
+ #
71
+ def register_driver(name, &block)
72
+ drivers[name] = block
73
+ end
74
+
75
+ ##
76
+ #
77
+ # Add a new selector to Capybara. Selectors can be used by various methods in Capybara
78
+ # to find certain elements on the page in a more convenient way. For example adding a
79
+ # selector to find certain table rows might look like this:
80
+ #
81
+ # Capybara.add_selector(:row) do
82
+ # xpath { |num| ".//tbody/tr[#{num}]" }
83
+ # end
84
+ #
85
+ # This makes it possible to use this selector in a variety of ways:
86
+ #
87
+ # find(:row, 3)
88
+ # page.find('table#myTable').find(:row, 3).text
89
+ # page.find('table#myTable').has_selector?(:row, 3)
90
+ # within(:row, 3) { page.should have_content('$100.000') }
91
+ #
92
+ # It might be convenient to specify that the selector is automatically chosen for certain
93
+ # values. This way you don't have to explicitly specify that you are looking for a row, or
94
+ # an id. Let's say we want Capybara to treat any Symbols sent into methods like find to be
95
+ # treated as though they were element ids. We could achieve this like so:
96
+ #
97
+ # Capybara.add_selector(:id) do
98
+ # xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
99
+ # match { |value| value.is_a?(Symbol) }
100
+ # end
101
+ #
102
+ # Now we can retrieve elements by id like this:
103
+ #
104
+ # find(:post_123)
105
+ #
106
+ # Note that this particular selector already ships with Capybara.
107
+ #
108
+ # @param [Symbol] name The name of the selector to add
109
+ # @yield A block executed in the context of the new {Capybara::Selector}
110
+ #
111
+ def add_selector(name, &block)
112
+ Capybara::Selector.add(name, &block)
113
+ end
114
+
115
+ def drivers
116
+ @drivers ||= {}
117
+ end
118
+
119
+ ##
120
+ #
121
+ # Register a proc that Capybara will call to run the Rack application.
122
+ #
123
+ # Capybara.server do |app, port|
124
+ # require 'rack/handler/mongrel'
125
+ # Rack::Handler::Mongrel.run(app, :Port => port)
126
+ # end
127
+ #
128
+ # By default, Capybara will try to run thin, falling back to webrick.
129
+ #
130
+ # @yield [app, port] This block recieves a rack app and port and should run a Rack handler
131
+ #
132
+ def server(&block)
133
+ if block_given?
134
+ @server = block
135
+ else
136
+ @server
137
+ end
138
+ end
139
+
140
+ ##
141
+ #
142
+ # Wraps the given string, which should contain an HTML document or fragment
143
+ # in a {Capybara::Node::Simple} which exposes all {Capybara::Node::Matchers} and
144
+ # {Capybara::Node::Finders}. This allows you to query any string containing
145
+ # HTML in the exact same way you would query the current document in a Capybara
146
+ # session. For example:
147
+ #
148
+ # node = Capybara.string <<-HTML
149
+ # <ul>
150
+ # <li id="home">Home</li>
151
+ # <li id="projects">Projects</li>
152
+ # </ul>
153
+ # HTML
154
+ #
155
+ # node.find('#projects').text # => 'Projects'
156
+ # node.has_selector?('li#home', :text => 'Home')
157
+ # node.has_selector?(:projects)
158
+ # node.find('ul').find('li').text # => 'Home'
159
+ #
160
+ # @param [String] html An html fragment or document
161
+ # @return [Capybara::Node::Simple] A node which has Capybara's finders and matchers
162
+ #
163
+ def string(html)
164
+ Capybara::Node::Simple.new(html)
165
+ end
166
+
167
+ ##
168
+ #
169
+ # Runs Capybara's default server for the given application and port
170
+ # under most circumstances you should not have to call this method
171
+ # manually.
172
+ #
173
+ # @param [Rack Application] app The rack application to run
174
+ # @param [Fixnum] port The port to run the application on
175
+ #
176
+ def run_default_server(app, port)
177
+ begin
178
+ require 'rack/handler/thin'
179
+ Thin::Logging.silent = true
180
+ Rack::Handler::Thin.run(app, :Port => port)
181
+ rescue LoadError
182
+ require 'rack/handler/webrick'
183
+ Rack::Handler::WEBrick.run(app, :Port => port, :AccessLog => [], :Logger => WEBrick::Log::new(nil, 0))
184
+ end
185
+ end
186
+
187
+ ##
188
+ #
189
+ # @return [Symbol] The name of the driver to use by default
190
+ #
191
+ def default_driver
192
+ @default_driver || :rack_test
193
+ end
194
+
195
+ ##
196
+ #
197
+ # @return [Symbol] The name of the driver currently in use
198
+ #
199
+ def current_driver
200
+ @current_driver || default_driver
201
+ end
202
+ alias_method :mode, :current_driver
203
+
204
+ ##
205
+ #
206
+ # @return [Symbol] The name of the driver used when JavaScript is needed
207
+ #
208
+ def javascript_driver
209
+ @javascript_driver || :selenium
210
+ end
211
+
212
+ ##
213
+ #
214
+ # Use the default driver as the current driver
215
+ #
216
+ def use_default_driver
217
+ @current_driver = nil
218
+ end
219
+
220
+ ##
221
+ #
222
+ # Yield a block using a specific driver
223
+ #
224
+ def using_driver(driver)
225
+ previous_driver = Capybara.current_driver
226
+ Capybara.current_driver = driver
227
+ yield
228
+ ensure
229
+ @current_driver = previous_driver
230
+ end
231
+
232
+ ##
233
+ #
234
+ # Yield a block using a specific wait time
235
+ #
236
+ def using_wait_time(seconds)
237
+ previous_wait_time = Capybara.default_wait_time
238
+ Capybara.default_wait_time = seconds
239
+ yield
240
+ ensure
241
+ Capybara.default_wait_time = previous_wait_time
242
+ end
243
+
244
+ ##
245
+ #
246
+ # The current Capybara::Session based on what is set as Capybara.app and Capybara.current_driver
247
+ #
248
+ # @return [Capybara::Session] The currently used session
249
+ #
250
+ def current_session
251
+ session_pool["#{current_driver}:#{session_name}:#{app.object_id}"] ||= Capybara::Session.new(current_driver, app)
252
+ end
253
+
254
+ ##
255
+ #
256
+ # Reset sessions, cleaning out the pool of sessions. This will remove any session information such
257
+ # as cookies.
258
+ #
259
+ def reset_sessions!
260
+ session_pool.each { |mode, session| session.reset! }
261
+ end
262
+ alias_method :reset!, :reset_sessions!
263
+
264
+ ##
265
+ #
266
+ # The current session name.
267
+ #
268
+ # @return [Symbol] The name of the currently used session.
269
+ #
270
+ def session_name
271
+ @session_name ||= :default
272
+ end
273
+
274
+ ##
275
+ #
276
+ # Yield a block using a specific session name.
277
+ #
278
+ def using_session(name)
279
+ self.session_name = name
280
+ yield
281
+ ensure
282
+ self.session_name = :default
283
+ end
284
+
285
+ def included(base)
286
+ base.send(:include, Capybara::DSL)
287
+ warn "`include Capybara` is deprecated. Please use `include Capybara::DSL` instead."
288
+ end
289
+
290
+ def deprecate(method, alternate_method)
291
+ warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead"
292
+ end
293
+
294
+ private
295
+
296
+ def session_pool
297
+ @session_pool ||= {}
298
+ end
299
+ end
300
+
301
+ self.default_driver = nil
302
+ self.current_driver = nil
303
+
304
+ autoload :DSL, 'capybara/dsl'
305
+ autoload :Server, 'capybara/server'
306
+ autoload :Session, 'capybara/session'
307
+ autoload :Selector, 'capybara/selector'
308
+ autoload :Query, 'capybara/query'
309
+ autoload :VERSION, 'capybara/version'
310
+
311
+ module Node
312
+ autoload :Base, 'capybara/node/base'
313
+ autoload :Simple, 'capybara/node/simple'
314
+ autoload :Element, 'capybara/node/element'
315
+ autoload :Document, 'capybara/node/document'
316
+ autoload :Finders, 'capybara/node/finders'
317
+ autoload :Matchers, 'capybara/node/matchers'
318
+ autoload :Actions, 'capybara/node/actions'
319
+ end
320
+
321
+ module Driver
322
+ autoload :Base, 'capybara/driver/base'
323
+ autoload :Node, 'capybara/driver/node'
324
+
325
+ class Selenium
326
+ def initialize(*args)
327
+ raise "Capybara::Driver::Selenium has been renamed to Capybara::Selenium::Driver"
328
+ end
329
+ end
330
+
331
+ class RackTest
332
+ def initialize(*args)
333
+ raise "Capybara::Driver::RackTest has been renamed to Capybara::RackTest::Driver"
334
+ end
335
+ end
336
+ end
337
+
338
+ module RackTest
339
+ autoload :Driver, 'capybara/rack_test/driver'
340
+ autoload :Node, 'capybara/rack_test/node'
341
+ autoload :Form, 'capybara/rack_test/form'
342
+ autoload :Browser, 'capybara/rack_test/browser'
343
+ end
344
+
345
+ module Selenium
346
+ autoload :Node, 'capybara/selenium/node'
347
+ autoload :Driver, 'capybara/selenium/driver'
348
+ end
349
+ end
350
+
351
+ Capybara.configure do |config|
352
+ config.run_server = true
353
+ config.server {|app, port| Capybara.run_default_server(app, port)}
354
+ config.default_selector = :css
355
+ config.default_wait_time = 2
356
+ config.ignore_hidden_elements = false
357
+ config.prefer_visible_elements = true
358
+ config.default_host = "http://www.example.com"
359
+ config.automatic_reload = true
360
+ end
361
+
362
+ Capybara.register_driver :rack_test do |app|
363
+ Capybara::RackTest::Driver.new(app)
364
+ end
365
+
366
+ Capybara.register_driver :selenium do |app|
367
+ Capybara::Selenium::Driver.new(app)
368
+ end
@@ -0,0 +1,25 @@
1
+ require 'capybara'
2
+
3
+ require 'capybara/dsl'
4
+ require 'capybara/rspec/matchers'
5
+
6
+ World(Capybara::DSL)
7
+ World(Capybara::RSpecMatchers)
8
+
9
+ Before do
10
+ Capybara.reset_sessions!
11
+ Capybara.use_default_driver
12
+ end
13
+
14
+ Before '@javascript' do
15
+ Capybara.current_driver = Capybara.javascript_driver
16
+ end
17
+
18
+ Before do |scenario|
19
+ scenario.source_tag_names.each do |tag|
20
+ driver_name = tag.sub(/^@/, '').to_sym
21
+ if Capybara.drivers.has_key?(driver_name)
22
+ Capybara.current_driver = driver_name
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,64 @@
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 invalid_element_errors
47
+ []
48
+ end
49
+
50
+ def wait?
51
+ false
52
+ end
53
+
54
+ def wait_until(*args)
55
+ end
56
+
57
+ def reset!
58
+ end
59
+
60
+ def has_shortcircuit_timeout?
61
+ false
62
+ end
63
+
64
+ end