capybara 2.13.0 → 2.18.0

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 (122) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +218 -18
  3. data/README.md +54 -23
  4. data/lib/capybara/config.rb +132 -0
  5. data/lib/capybara/cucumber.rb +1 -0
  6. data/lib/capybara/driver/base.rb +14 -0
  7. data/lib/capybara/dsl.rb +1 -3
  8. data/lib/capybara/helpers.rb +3 -3
  9. data/lib/capybara/minitest/spec.rb +14 -37
  10. data/lib/capybara/minitest.rb +95 -114
  11. data/lib/capybara/node/actions.rb +10 -10
  12. data/lib/capybara/node/base.rb +7 -2
  13. data/lib/capybara/node/element.rb +9 -3
  14. data/lib/capybara/node/finders.rb +92 -18
  15. data/lib/capybara/node/matchers.rb +21 -9
  16. data/lib/capybara/node/simple.rb +5 -0
  17. data/lib/capybara/queries/ancestor_query.rb +25 -0
  18. data/lib/capybara/queries/base_query.rb +12 -3
  19. data/lib/capybara/queries/current_path_query.rb +13 -9
  20. data/lib/capybara/queries/selector_query.rb +62 -23
  21. data/lib/capybara/queries/sibling_query.rb +25 -0
  22. data/lib/capybara/queries/text_query.rb +10 -5
  23. data/lib/capybara/queries/title_query.rb +1 -0
  24. data/lib/capybara/rack_test/browser.rb +13 -5
  25. data/lib/capybara/rack_test/driver.rb +6 -1
  26. data/lib/capybara/rack_test/form.rb +4 -3
  27. data/lib/capybara/rack_test/node.rb +1 -1
  28. data/lib/capybara/rspec/compound.rb +95 -0
  29. data/lib/capybara/rspec/matcher_proxies.rb +45 -0
  30. data/lib/capybara/rspec/matchers.rb +108 -7
  31. data/lib/capybara/rspec.rb +3 -1
  32. data/lib/capybara/selector/filter.rb +13 -41
  33. data/lib/capybara/selector/filter_set.rb +30 -4
  34. data/lib/capybara/selector/filters/base.rb +33 -0
  35. data/lib/capybara/selector/filters/expression_filter.rb +40 -0
  36. data/lib/capybara/selector/filters/node_filter.rb +27 -0
  37. data/lib/capybara/selector/selector.rb +36 -15
  38. data/lib/capybara/selector.rb +63 -42
  39. data/lib/capybara/selenium/driver.rb +177 -33
  40. data/lib/capybara/selenium/node.rb +106 -55
  41. data/lib/capybara/server.rb +6 -5
  42. data/lib/capybara/session/config.rb +114 -0
  43. data/lib/capybara/session/matchers.rb +15 -4
  44. data/lib/capybara/session.rb +178 -65
  45. data/lib/capybara/spec/fixtures/no_extension +1 -0
  46. data/lib/capybara/spec/public/test.js +18 -3
  47. data/lib/capybara/spec/session/accept_alert_spec.rb +9 -1
  48. data/lib/capybara/spec/session/accept_prompt_spec.rb +29 -1
  49. data/lib/capybara/spec/session/all_spec.rb +13 -1
  50. data/lib/capybara/spec/session/ancestor_spec.rb +85 -0
  51. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +24 -8
  52. data/lib/capybara/spec/session/assert_selector.rb +1 -1
  53. data/lib/capybara/spec/session/assert_text.rb +8 -0
  54. data/lib/capybara/spec/session/assert_title.rb +22 -9
  55. data/lib/capybara/spec/session/attach_file_spec.rb +8 -1
  56. data/lib/capybara/spec/session/check_spec.rb +4 -4
  57. data/lib/capybara/spec/session/choose_spec.rb +2 -2
  58. data/lib/capybara/spec/session/click_button_spec.rb +1 -1
  59. data/lib/capybara/spec/session/click_link_or_button_spec.rb +3 -3
  60. data/lib/capybara/spec/session/click_link_spec.rb +1 -1
  61. data/lib/capybara/spec/session/current_url_spec.rb +3 -3
  62. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
  63. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +1 -1
  64. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +22 -0
  65. data/lib/capybara/spec/session/evaluate_script_spec.rb +1 -1
  66. data/lib/capybara/spec/session/fill_in_spec.rb +8 -2
  67. data/lib/capybara/spec/session/find_field_spec.rb +1 -0
  68. data/lib/capybara/spec/session/find_spec.rb +8 -6
  69. data/lib/capybara/spec/session/first_spec.rb +10 -5
  70. data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
  71. data/lib/capybara/spec/session/has_css_spec.rb +11 -0
  72. data/lib/capybara/spec/session/has_current_path_spec.rb +52 -7
  73. data/lib/capybara/spec/session/has_link_spec.rb +4 -4
  74. data/lib/capybara/spec/session/has_none_selectors_spec.rb +76 -0
  75. data/lib/capybara/spec/session/has_select_spec.rb +64 -6
  76. data/lib/capybara/spec/session/has_selector_spec.rb +1 -3
  77. data/lib/capybara/spec/session/has_text_spec.rb +5 -3
  78. data/lib/capybara/spec/session/has_title_spec.rb +4 -2
  79. data/lib/capybara/spec/session/has_xpath_spec.rb +5 -3
  80. data/lib/capybara/spec/session/node_spec.rb +50 -26
  81. data/lib/capybara/spec/session/refresh_spec.rb +28 -0
  82. data/lib/capybara/spec/session/reset_session_spec.rb +3 -3
  83. data/lib/capybara/spec/session/select_spec.rb +3 -2
  84. data/lib/capybara/spec/session/sibling_spec.rb +52 -0
  85. data/lib/capybara/spec/session/uncheck_spec.rb +2 -2
  86. data/lib/capybara/spec/session/unselect_spec.rb +2 -2
  87. data/lib/capybara/spec/session/visit_spec.rb +56 -1
  88. data/lib/capybara/spec/session/window/become_closed_spec.rb +11 -11
  89. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +11 -9
  90. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +4 -4
  91. data/lib/capybara/spec/session/window/within_window_spec.rb +27 -2
  92. data/lib/capybara/spec/spec_helper.rb +28 -4
  93. data/lib/capybara/spec/test_app.rb +3 -1
  94. data/lib/capybara/spec/views/form.erb +27 -1
  95. data/lib/capybara/spec/views/initial_alert.erb +10 -0
  96. data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
  97. data/lib/capybara/spec/views/with_hover.erb +5 -0
  98. data/lib/capybara/spec/views/with_html.erb +33 -2
  99. data/lib/capybara/spec/views/with_js.erb +12 -0
  100. data/lib/capybara/spec/views/with_windows.erb +4 -0
  101. data/lib/capybara/version.rb +1 -1
  102. data/lib/capybara/window.rb +1 -1
  103. data/lib/capybara.rb +102 -124
  104. data/spec/capybara_spec.rb +43 -21
  105. data/spec/dsl_spec.rb +1 -0
  106. data/spec/filter_set_spec.rb +28 -0
  107. data/spec/minitest_spec.rb +9 -1
  108. data/spec/minitest_spec_spec.rb +19 -5
  109. data/spec/per_session_config_spec.rb +67 -0
  110. data/spec/result_spec.rb +20 -0
  111. data/spec/rspec/shared_spec_matchers.rb +148 -44
  112. data/spec/rspec/views_spec.rb +4 -0
  113. data/spec/rspec_matchers_spec.rb +46 -0
  114. data/spec/rspec_spec.rb +77 -0
  115. data/spec/selector_spec.rb +2 -1
  116. data/spec/selenium_spec_chrome.rb +25 -17
  117. data/spec/selenium_spec_firefox.rb +2 -1
  118. data/spec/selenium_spec_marionette.rb +18 -5
  119. data/spec/session_spec.rb +44 -0
  120. data/spec/shared_selenium_session.rb +72 -8
  121. data/spec/spec_helper.rb +4 -0
  122. metadata +55 -8
@@ -76,6 +76,7 @@
76
76
 
77
77
  <p>
78
78
  <a href="#" id="open-alert">Open alert</a>
79
+ <a href="/with_html" id="alert-page-change">Alert page change</a>
79
80
  </p>
80
81
 
81
82
  <p>
@@ -95,6 +96,10 @@
95
96
  <a href="#" id="open-prompt">Open prompt</a>
96
97
  </p>
97
98
 
99
+ <p>
100
+ <a href="#" id="open-prompt-with-default">Open defaulted prompt</a>
101
+ </p>
102
+
98
103
  <p>
99
104
  <input id="disable-on-click"/>
100
105
  </p>
@@ -116,6 +121,13 @@
116
121
  <input type="file" id="hidden_file" style="opacity:0; display: none;">
117
122
  </p>
118
123
 
124
+ <div id="drag_scroll">
125
+ <p>This is a draggable element.</p>
126
+ </div>
127
+ <div id="drop_scroll">
128
+ <p>It should be dropped here.</p>
129
+ </div>
130
+
119
131
  <script type="text/javascript">
120
132
  // a javascript comment
121
133
  var aVar = 123;
@@ -46,5 +46,9 @@
46
46
  <button id="doesNotOpenWindows">Does not open windows</button>
47
47
 
48
48
  <iframe src="/frame_one" id="frameOne"></iframe>
49
+
50
+ <div id="scope">
51
+ <span>My scoped content</span>
52
+ </div>
49
53
  </body>
50
54
  </html>
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Capybara
3
- VERSION = '2.13.0'
3
+ VERSION = '2.18.0'
4
4
  end
@@ -115,7 +115,7 @@ module Capybara
115
115
 
116
116
  private
117
117
 
118
- def wait_for_stable_size(seconds=Capybara.default_max_wait_time)
118
+ def wait_for_stable_size(seconds=session.config.default_max_wait_time)
119
119
  res = yield if block_given?
120
120
  prev_size = size
121
121
  start_time = Capybara::Helpers.monotonic_time
data/lib/capybara.rb CHANGED
@@ -2,6 +2,8 @@
2
2
  require 'timeout'
3
3
  require 'nokogiri'
4
4
  require 'xpath'
5
+ require 'forwardable'
6
+ require 'capybara/config'
5
7
 
6
8
  module Capybara
7
9
  class CapybaraError < StandardError; end
@@ -19,18 +21,41 @@ module Capybara
19
21
  class WindowError < CapybaraError; end
20
22
  class ReadOnlyElementError < CapybaraError; end
21
23
 
24
+
22
25
  class << self
23
- attr_reader :app_host, :default_host
24
- attr_accessor :asset_host, :run_server, :always_include_port
25
- attr_accessor :server_port, :exact, :match, :exact_options, :visible_text_only, :enable_aria_label
26
- attr_accessor :default_selector, :default_max_wait_time, :ignore_hidden_elements
27
- attr_accessor :save_path, :wait_on_first_by_default, :automatic_label_click, :automatic_reload
28
- attr_reader :reuse_server
29
- attr_accessor :raise_server_errors, :server_errors
30
- attr_writer :default_driver, :current_driver, :javascript_driver, :session_name, :server_host
31
- attr_reader :save_and_open_page_path
32
- attr_accessor :exact_text
33
- attr_accessor :app
26
+ extend Forwardable
27
+
28
+ # DelegateCapybara global configurations
29
+ # @!method app
30
+ # See {Capybara.configure}
31
+ # @!method reuse_server
32
+ # See {Capybara.configure}
33
+ # @!method threadsafe
34
+ # See {Capybara.configure}
35
+ # @!method server
36
+ # See {Capybara.configure}
37
+ # @!method default_driver
38
+ # See {Capybara.configure}
39
+ # @!method javascript_driver
40
+ # See {Capybara.configure}
41
+ Config::OPTIONS.each do |method|
42
+ def_delegators :config, method, "#{method}="
43
+ end
44
+
45
+ # Delegate Capybara global configurations
46
+ # @!method default_selector
47
+ # See {Capybara.configure}
48
+ # @!method default_max_wait_time
49
+ # See {Capybara.configure}
50
+ # @!method app_host
51
+ # See {Capybara.configure}
52
+ # @!method always_include_port
53
+ # See {Capybara.configure}
54
+ # @!method wait_on_first_by_default
55
+ # See {Capybara.configure}
56
+ SessionConfig::OPTIONS.each do |method|
57
+ def_delegators :config, method, "#{method}="
58
+ end
34
59
 
35
60
  ##
36
61
  #
@@ -44,7 +69,7 @@ module Capybara
44
69
  # === Configurable options
45
70
  #
46
71
  # [app_host = String/nil] The default host to use when giving a relative URL to visit, must be a valid URL e.g. http://www.example.com
47
- # [always_include_port = Boolean] Whether the Rack server's port should automatically be inserted into every visited URL (Default: false)
72
+ # [always_include_port = Boolean] Whether the Rack server's port should automatically be inserted into every visited URL unless another port is explicitly specified (Default: false)
48
73
  # [asset_host = String] Where dynamic assets are hosted - will be prepended to relative asset locations if present (Default: nil)
49
74
  # [run_server = Boolean] Whether to start a Rack server for the given Rack app (Default: true)
50
75
  # [raise_server_errors = Boolean] Should errors raised in the server be raised in the tests? (Default: true)
@@ -58,6 +83,9 @@ module Capybara
58
83
  # [automatic_label_click = Boolean] Whether Node#choose, Node#check, Node#uncheck will attempt to click the associated label element if the checkbox/radio button are non-visible (Default: false)
59
84
  # [enable_aria_label = Boolean] Whether fields, links, and buttons will match against aria-label attribute (Default: false)
60
85
  # [reuse_server = Boolean] Reuse the server thread between multiple sessions using the same app object (Default: true)
86
+ # [threadsafe = Boolean] Whether sessions can be configured individually (Default: false)
87
+ # [server = Symbol] The name of the registered server to use when running the app under test (Default: :webrick)
88
+ #
61
89
  # === DSL Options
62
90
  #
63
91
  # when using capybara/dsl, the following options are also available:
@@ -66,7 +94,7 @@ module Capybara
66
94
  # [javascript_driver = Symbol] The name of a driver to use for JavaScript enabled tests. (Default: :selenium)
67
95
  #
68
96
  def configure
69
- yield self
97
+ yield ConfigureDeprecator.new(config)
70
98
  end
71
99
 
72
100
  ##
@@ -141,13 +169,14 @@ module Capybara
141
169
  ##
142
170
  #
143
171
  # Modify a selector previously created by {Capybara.add_selector}.
144
- # For example modifying the :button selector to also find divs styled
145
- # to look like buttons might look like this
172
+ # For example, adding a new filter to the :button selector to filter based on
173
+ # button style (a class) might look like this
146
174
  #
147
175
  # Capybara.modify_selector(:button) do
148
- # xpath { |locator| XPath::HTML.button(locator).or(XPath::css('div.btn')[XPath::string.n.is(locator)]) }
176
+ # filter (:style, valid_values: [:primary, :secondary]) { |node, style| node[:class].split.include? "btn-#{style}" }
149
177
  # end
150
178
  #
179
+ #
151
180
  # @param [Symbol] name The name of the selector to modify
152
181
  # @yield A block executed in the context of the existing {Capybara::Selector}
153
182
  #
@@ -163,45 +192,6 @@ module Capybara
163
192
  @servers ||= {}
164
193
  end
165
194
 
166
- ##
167
- #
168
- # Register a proc that Capybara will call to run the Rack application.
169
- #
170
- # Capybara.server do |app, port, host|
171
- # require 'rack/handler/mongrel'
172
- # Rack::Handler::Mongrel.run(app, :Port => port)
173
- # end
174
- #
175
- # By default, Capybara will try to run webrick.
176
- #
177
- # @yield [app, port, host] This block receives a rack app, port, and host/ip and should run a Rack handler
178
- #
179
- def server(&block)
180
- if block_given?
181
- warn "DEPRECATED: Passing a block to Capybara::server is deprecated, please use Capybara::register_server instead"
182
- @server = block
183
- else
184
- @server
185
- end
186
- end
187
-
188
- ##
189
- #
190
- # Set the server to use.
191
- #
192
- # Capybara.server = :webrick
193
- #
194
- # @param [Symbol] name Name of the server type to use
195
- # @see register_server
196
- #
197
- def server=(name)
198
- @server = if name.respond_to? :call
199
- name
200
- else
201
- servers[name.to_sym]
202
- end
203
- end
204
-
205
195
  ##
206
196
  #
207
197
  # Wraps the given string, which should contain an HTML document or fragment
@@ -251,29 +241,25 @@ module Capybara
251
241
  servers[:webrick].call(app, port, server_host)
252
242
  end
253
243
 
254
- ##
255
- #
256
- # @return [Symbol] The name of the driver to use by default
257
- #
258
- def default_driver
259
- @default_driver || :rack_test
260
- end
261
-
262
244
  ##
263
245
  #
264
246
  # @return [Symbol] The name of the driver currently in use
265
247
  #
266
248
  def current_driver
267
- @current_driver || default_driver
249
+ if threadsafe
250
+ Thread.current['capybara_current_driver']
251
+ else
252
+ @current_driver
253
+ end || default_driver
268
254
  end
269
255
  alias_method :mode, :current_driver
270
256
 
271
- ##
272
- #
273
- # @return [Symbol] The name of the driver used when JavaScript is needed
274
- #
275
- def javascript_driver
276
- @javascript_driver || :selenium
257
+ def current_driver=(name)
258
+ if threadsafe
259
+ Thread.current['capybara_current_driver'] = name
260
+ else
261
+ @current_driver = name
262
+ end
277
263
  end
278
264
 
279
265
  ##
@@ -281,7 +267,7 @@ module Capybara
281
267
  # Use the default driver as the current driver
282
268
  #
283
269
  def use_default_driver
284
- @current_driver = nil
270
+ self.current_driver = nil
285
271
  end
286
272
 
287
273
  ##
@@ -293,15 +279,7 @@ module Capybara
293
279
  Capybara.current_driver = driver
294
280
  yield
295
281
  ensure
296
- @current_driver = previous_driver
297
- end
298
-
299
- ##
300
- #
301
- # @return [String] The IP address bound by default server
302
- #
303
- def server_host
304
- @server_host || '127.0.0.1'
282
+ self.current_driver = previous_driver
305
283
  end
306
284
 
307
285
  ##
@@ -344,7 +322,19 @@ module Capybara
344
322
  # @return [Symbol] The name of the currently used session.
345
323
  #
346
324
  def session_name
347
- @session_name ||= :default
325
+ if threadsafe
326
+ Thread.current['capybara_session_name'] ||= :default
327
+ else
328
+ @session_name ||= :default
329
+ end
330
+ end
331
+
332
+ def session_name=(name)
333
+ if threadsafe
334
+ Thread.current['capybara_session_name'] = name
335
+ else
336
+ @session_name = name
337
+ end
348
338
  end
349
339
 
350
340
  ##
@@ -352,11 +342,19 @@ module Capybara
352
342
  # Yield a block using a specific session name.
353
343
  #
354
344
  def using_session(name)
355
- previous_session_name = self.session_name
345
+ previous_session_info = {
346
+ session_name: session_name,
347
+ current_driver: current_driver,
348
+ app: app
349
+ }
356
350
  self.session_name = name
357
351
  yield
358
352
  ensure
359
- self.session_name = previous_session_name
353
+ self.session_name = previous_session_info[:session_name]
354
+ if threadsafe
355
+ self.current_driver = previous_session_info[:current_driver]
356
+ self.app = previous_session_info[:app]
357
+ end
360
358
  end
361
359
 
362
360
  ##
@@ -374,32 +372,8 @@ module Capybara
374
372
  end
375
373
  end
376
374
 
377
- # @deprecated Use default_max_wait_time instead
378
- def default_wait_time
379
- deprecate('default_wait_time', 'default_max_wait_time', true)
380
- default_max_wait_time
381
- end
382
-
383
- # @deprecated Use default_max_wait_time= instead
384
- def default_wait_time=(t)
385
- deprecate('default_wait_time=', 'default_max_wait_time=')
386
- self.default_max_wait_time = t
387
- end
388
-
389
- def save_and_open_page_path=(path)
390
- warn "DEPRECATED: #save_and_open_page_path is deprecated, please use #save_path instead. \n"\
391
- "Note: Behavior is slightly different with relative paths - see documentation" unless path.nil?
392
- @save_and_open_page_path = path
393
- end
394
-
395
- def app_host=(url)
396
- raise ArgumentError.new("Capybara.app_host should be set to a url (http://www.example.com)") unless url.nil? || (url =~ URI::Parser.new.make_regexp)
397
- @app_host = url
398
- end
399
-
400
- def default_host=(url)
401
- raise ArgumentError.new("Capybara.default_host should be set to a url (http://www.example.com)") unless url.nil? || (url =~ URI::Parser.new.make_regexp)
402
- @default_host = url
375
+ def session_options
376
+ config.session_options
403
377
  end
404
378
 
405
379
  def included(base)
@@ -407,18 +381,10 @@ module Capybara
407
381
  warn "`include Capybara` is deprecated. Please use `include Capybara::DSL` instead."
408
382
  end
409
383
 
410
- def reuse_server=(bool)
411
- warn "Capybara.reuse_server == false is a BETA feature and may change in a future version" unless bool
412
- @reuse_server = bool
413
- end
414
-
415
- def deprecate(method, alternate_method, once=false)
416
- @deprecation_notified ||= {}
417
- warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead" unless once and @deprecation_notified[method]
418
- @deprecation_notified[method]=true
419
- end
420
-
421
384
  private
385
+ def config
386
+ @config ||= Capybara::Config.new
387
+ end
422
388
 
423
389
  def session_pool
424
390
  @session_pool ||= {}
@@ -447,6 +413,8 @@ module Capybara
447
413
  require 'capybara/queries/title_query'
448
414
  require 'capybara/queries/current_path_query'
449
415
  require 'capybara/queries/match_query'
416
+ require 'capybara/queries/ancestor_query'
417
+ require 'capybara/queries/sibling_query'
450
418
  require 'capybara/query'
451
419
 
452
420
  require 'capybara/node/finders'
@@ -475,14 +443,14 @@ Capybara.register_server :default do |app, port, _host|
475
443
  Capybara.run_default_server(app, port)
476
444
  end
477
445
 
478
- Capybara.register_server :webrick do |app, port, host|
446
+ Capybara.register_server :webrick do |app, port, host, options={}|
479
447
  require 'rack/handler/webrick'
480
- Rack::Handler::WEBrick.run(app, Host: host, Port: port, AccessLog: [], Logger: WEBrick::Log::new(nil, 0))
448
+ Rack::Handler::WEBrick.run(app, {Host: host, Port: port, AccessLog: [], Logger: WEBrick::Log::new(nil, 0)}.merge(options))
481
449
  end
482
450
 
483
- Capybara.register_server :puma do |app, port, host|
451
+ Capybara.register_server :puma do |app, port, host, options={}|
484
452
  require 'rack/handler/puma'
485
- Rack::Handler::Puma.run(app, Host: host, Port: port, Threads: "0:4")
453
+ Rack::Handler::Puma.run(app, {Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false}.merge(options))
486
454
  end
487
455
 
488
456
  Capybara.configure do |config|
@@ -514,3 +482,13 @@ Capybara.register_driver :selenium do |app|
514
482
  Capybara::Selenium::Driver.new(app)
515
483
  end
516
484
 
485
+ Capybara.register_driver :selenium_chrome do |app|
486
+ Capybara::Selenium::Driver.new(app, :browser => :chrome)
487
+ end
488
+
489
+ Capybara.register_driver :selenium_chrome_headless do |app|
490
+ browser_options = ::Selenium::WebDriver::Chrome::Options.new()
491
+ browser_options.args << '--headless'
492
+ browser_options.args << '--disable-gpu'
493
+ Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
494
+ end
@@ -14,8 +14,8 @@ RSpec.describe Capybara do
14
14
  end
15
15
 
16
16
  it "should be accesible as the deprecated default_wait_time" do
17
- expect(Capybara).to receive(:warn).ordered.with('DEPRECATED: #default_wait_time= is deprecated, please use #default_max_wait_time= instead')
18
- expect(Capybara).to receive(:warn).ordered.with('DEPRECATED: #default_wait_time is deprecated, please use #default_max_wait_time instead')
17
+ expect(Capybara.send(:config)).to receive(:warn).ordered.with('DEPRECATED: #default_wait_time= is deprecated, please use #default_max_wait_time= instead')
18
+ expect(Capybara.send(:config)).to receive(:warn).ordered.with('DEPRECATED: #default_wait_time is deprecated, please use #default_max_wait_time instead')
19
19
  @previous_default_time = Capybara.default_max_wait_time
20
20
  Capybara.default_wait_time = 5
21
21
  expect(Capybara.default_wait_time).to eq(5)
@@ -35,27 +35,13 @@ RSpec.describe Capybara do
35
35
  end
36
36
 
37
37
  describe '.register_server' do
38
- before do
39
- Capybara.reuse_server = false
40
- @old_server = Capybara.server
41
- end
42
-
43
- after do
44
- Capybara.server(&@old_server)
45
- Capybara.reuse_server = true
46
- end
47
-
48
38
  it "should add a new server" do
49
- skip "JRuby fails this because of path issues to geckodriver I think. Its tested in other runs - not worth figuring out at this time" if RUBY_PLATFORM == 'java'
50
-
51
- require 'rack/handler/webrick'
39
+ handler = double("handler")
52
40
  Capybara.register_server :blob do |app, port, host|
53
- Rack::Handler::WEBrick.run(app, Host: host, Port: port, AccessLog: [], Logger: WEBrick::Log::new(nil, 0))
41
+ handler.run
54
42
  end
55
- Capybara.server = :blob
56
- session = Capybara::Session.new(:selenium, TestApp.new)
57
- session.visit('/')
58
- expect(session.body).to include("Hello world!")
43
+
44
+ expect(Capybara.servers).to have_key(:blob)
59
45
  end
60
46
  end
61
47
 
@@ -79,6 +65,30 @@ RSpec.describe Capybara do
79
65
  Capybara.server(&server)
80
66
  expect(Capybara.server).to eq(server)
81
67
  end
68
+
69
+ it "should have :webrick registered" do
70
+ require 'rack/handler/webrick'
71
+ mock_app = double('app')
72
+ Capybara.server = :webrick
73
+ expect(Rack::Handler::WEBrick).to receive(:run)
74
+ Capybara.server.call(mock_app, 8000)
75
+ end
76
+
77
+ it "should have :puma registered" do
78
+ require 'rack/handler/puma'
79
+ mock_app = double('app')
80
+ Capybara.server = :puma
81
+ expect(Rack::Handler::Puma).to receive(:run).with(mock_app, hash_including(Host: nil, Port: 8000))
82
+ Capybara.server.call(mock_app, 8000)
83
+ end
84
+
85
+ it "should pass options to server" do
86
+ require 'rack/handler/puma'
87
+ mock_app = double('app')
88
+ Capybara.server = :puma, { Silent: true }
89
+ expect(Rack::Handler::Puma).to receive(:run).with(mock_app, hash_including(Host: nil, Port: 9000, Silent: true))
90
+ Capybara.server.call(mock_app, 9000)
91
+ end
82
92
  end
83
93
 
84
94
  describe 'app_host' do
@@ -114,10 +124,22 @@ RSpec.describe Capybara do
114
124
  expect { Capybara.default_host = "http://www.example.com" }.not_to raise_error
115
125
  end
116
126
  end
127
+
128
+ describe "configure" do
129
+ it 'deprecates calling non configuration option methods in configure' do
130
+ expect_any_instance_of(Kernel).to receive(:warn).
131
+ with('Calling register_driver from Capybara.configure is deprecated - please call it on Capybara directly ( Capybara.register_driver(...) )')
132
+ Capybara.configure do |config|
133
+ config.register_driver(:random_name) do
134
+ #just a random block
135
+ end
136
+ end
137
+ end
138
+ end
117
139
  end
118
140
 
119
141
  RSpec.describe Capybara::Session do
120
- context 'with non-existant driver' do
142
+ context 'with nonexistent driver' do
121
143
  it "should raise an error" do
122
144
  expect {
123
145
  Capybara::Session.new(:quox, TestApp).driver
data/spec/dsl_spec.rb CHANGED
@@ -16,6 +16,7 @@ Capybara::SpecHelper.run_specs TestClass.new, "DSL", capybara_skip: [
16
16
  :server,
17
17
  :hover,
18
18
  :about_scheme,
19
+ :psc
19
20
  ]
20
21
 
21
22
  RSpec.describe Capybara::DSL do
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe Capybara::Selector::FilterSet do
5
+ after do
6
+ Capybara::Selector::FilterSet.remove(:test)
7
+ end
8
+
9
+ it "allows node filters" do
10
+ fs = Capybara::Selector::FilterSet.add(:test) do
11
+ filter(:node_test, :boolean) { |node, value| true }
12
+ expression_filter(:expression_test, :boolean) { |expr, value| true }
13
+ end
14
+
15
+ expect(fs.node_filters.keys).to include(:node_test)
16
+ expect(fs.node_filters.keys).not_to include(:expression_test)
17
+ end
18
+
19
+ it "allows expression filters" do
20
+ fs = Capybara::Selector::FilterSet.add(:test) do
21
+ filter(:node_test, :boolean) { |node, value| true }
22
+ expression_filter(:expression_test, :boolean) { |expr, value| true }
23
+ end
24
+
25
+ expect(fs.expression_filters.keys).to include(:expression_test)
26
+ expect(fs.expression_filters.keys).not_to include(:node_test)
27
+ end
28
+ end
@@ -88,6 +88,14 @@ class MinitestTest < Minitest::Test
88
88
  refute_table('not_on_form')
89
89
  end
90
90
 
91
+ def test_assert_all_of_selectors
92
+ assert_all_of_selectors(:css, 'select#form_other_title', 'input#form_last_name')
93
+ end
94
+
95
+ def test_assert_none_of_selectors
96
+ assert_none_of_selectors(:css, 'input#not_on_page', 'input#also_not_on_page')
97
+ end
98
+
91
99
  def test_assert_matches_selector
92
100
  assert_matches_selector(find(:field, 'customer_email'), :field, 'customer_email')
93
101
  assert_not_matches_selector(find(:select, 'form_title'), :field, 'customer_email')
@@ -117,6 +125,6 @@ RSpec.describe 'capybara/minitest' do
117
125
  reporter.start
118
126
  MinitestTest.run reporter, {}
119
127
  reporter.report
120
- expect(output.string).to include("15 runs, 42 assertions, 0 failures, 0 errors, 0 skips")
128
+ expect(output.string).to include("17 runs, 44 assertions, 0 failures, 0 errors, 0 skips")
121
129
  end
122
130
  end
@@ -37,10 +37,10 @@ class MinitestSpecTest < Minitest::Spec
37
37
  page.must_have_xpath('.//input[@id="customer_email"]')
38
38
  page.wont_have_xpath('.//select[@id="not_form_title"]')
39
39
  page.wont_have_xpath('.//input[@id="customer_email"]') { |el| el[:id] == "not_customer_email" }
40
- el = find(:select, 'form_title')
41
- el.must_have_xpath('.//option[@class="title"]')
42
- el.must_have_xpath('.//option', count: 1) { |el| el[:class] != 'title' && !el.disabled?}
43
- el.wont_have_xpath('.//input[@id="customer_email"]')
40
+ select = find(:select, 'form_title')
41
+ select.must_have_xpath('.//option[@class="title"]')
42
+ select.must_have_xpath('.//option', count: 1) { |option| option[:class] != 'title' && !option.disabled?}
43
+ select.wont_have_xpath('.//input[@id="customer_email"]')
44
44
  end
45
45
 
46
46
  it "support css expectations" do
@@ -88,6 +88,14 @@ class MinitestSpecTest < Minitest::Spec
88
88
  page.wont_have_table('not_on_form')
89
89
  end
90
90
 
91
+ it "supports all_of_selectors expectations" do
92
+ page.must_have_all_of_selectors(:css, 'select#form_other_title', 'input#form_last_name')
93
+ end
94
+
95
+ it "supports none_of_selectors expectations" do
96
+ page.must_have_none_of_selectors(:css, 'input#not_on_page', 'input#also_not_on_page')
97
+ end
98
+
91
99
  it "supports match_selector expectations" do
92
100
  find(:field, 'customer_email').must_match_selector(:field, 'customer_email')
93
101
  find(:select, 'form_title').wont_match_selector(:field, 'customer_email')
@@ -102,6 +110,10 @@ class MinitestSpecTest < Minitest::Spec
102
110
  find(:select, 'form_title').must_match_xpath('.//select[@id="form_title"]')
103
111
  find(:select, 'form_title').wont_match_xpath('.//select[@id="not_on_page"]')
104
112
  end
113
+
114
+ it "handles failures" do
115
+ page.must_have_select('non_existing_form_title')
116
+ end
105
117
  end
106
118
 
107
119
  RSpec.describe 'capybara/minitest/spec' do
@@ -116,6 +128,8 @@ RSpec.describe 'capybara/minitest/spec' do
116
128
  reporter.start
117
129
  MinitestSpecTest.run reporter, {}
118
130
  reporter.report
119
- expect(output.string).to include("15 runs, 38 assertions, 0 failures, 0 errors, 0 skips")
131
+ expect(output.string).to include("18 runs, 41 assertions, 1 failures, 0 errors, 0 skips")
132
+ #Make sure error messages are displayed
133
+ expect(output.string).to include('expected to find visible select box "non_existing_form_title" that is not disabled but there were no matches')
120
134
  end
121
135
  end