capybara 2.5.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 (205) hide show
  1. checksums.yaml +5 -5
  2. data/.yard/templates_custom/default/class/html/selectors.erb +38 -0
  3. data/.yard/templates_custom/default/class/html/setup.rb +17 -0
  4. data/.yard/yard_extensions.rb +78 -0
  5. data/.yardopts +1 -0
  6. data/History.md +413 -10
  7. data/License.txt +1 -1
  8. data/README.md +237 -130
  9. data/lib/capybara/config.rb +132 -0
  10. data/lib/capybara/cucumber.rb +3 -1
  11. data/lib/capybara/driver/base.rb +27 -6
  12. data/lib/capybara/driver/node.rb +14 -5
  13. data/lib/capybara/dsl.rb +2 -3
  14. data/lib/capybara/helpers.rb +13 -65
  15. data/lib/capybara/minitest/spec.rb +177 -0
  16. data/lib/capybara/minitest.rb +278 -0
  17. data/lib/capybara/node/actions.rb +180 -24
  18. data/lib/capybara/node/base.rb +17 -5
  19. data/lib/capybara/node/document.rb +5 -0
  20. data/lib/capybara/node/document_matchers.rb +15 -14
  21. data/lib/capybara/node/element.rb +55 -7
  22. data/lib/capybara/node/finders.rb +179 -67
  23. data/lib/capybara/node/matchers.rb +301 -105
  24. data/lib/capybara/node/simple.rb +15 -4
  25. data/lib/capybara/queries/ancestor_query.rb +25 -0
  26. data/lib/capybara/queries/base_query.rb +69 -3
  27. data/lib/capybara/queries/current_path_query.rb +17 -8
  28. data/lib/capybara/queries/match_query.rb +19 -0
  29. data/lib/capybara/queries/selector_query.rb +251 -0
  30. data/lib/capybara/queries/sibling_query.rb +25 -0
  31. data/lib/capybara/queries/text_query.rb +67 -16
  32. data/lib/capybara/queries/title_query.rb +4 -2
  33. data/lib/capybara/query.rb +3 -131
  34. data/lib/capybara/rack_test/browser.rb +14 -5
  35. data/lib/capybara/rack_test/css_handlers.rb +1 -0
  36. data/lib/capybara/rack_test/driver.rb +15 -8
  37. data/lib/capybara/rack_test/form.rb +34 -12
  38. data/lib/capybara/rack_test/node.rb +29 -12
  39. data/lib/capybara/rails.rb +3 -3
  40. data/lib/capybara/result.rb +104 -9
  41. data/lib/capybara/rspec/compound.rb +95 -0
  42. data/lib/capybara/rspec/features.rb +17 -6
  43. data/lib/capybara/rspec/matcher_proxies.rb +45 -0
  44. data/lib/capybara/rspec/matchers.rb +199 -80
  45. data/lib/capybara/rspec.rb +4 -2
  46. data/lib/capybara/selector/css.rb +30 -0
  47. data/lib/capybara/selector/filter.rb +20 -0
  48. data/lib/capybara/selector/filter_set.rb +74 -0
  49. data/lib/capybara/selector/filters/base.rb +33 -0
  50. data/lib/capybara/selector/filters/expression_filter.rb +40 -0
  51. data/lib/capybara/selector/filters/node_filter.rb +27 -0
  52. data/lib/capybara/selector/selector.rb +276 -0
  53. data/lib/capybara/selector.rb +452 -157
  54. data/lib/capybara/selenium/driver.rb +282 -81
  55. data/lib/capybara/selenium/node.rb +144 -46
  56. data/lib/capybara/server.rb +59 -16
  57. data/lib/capybara/session/config.rb +114 -0
  58. data/lib/capybara/session/matchers.rb +29 -19
  59. data/lib/capybara/session.rb +378 -143
  60. data/lib/capybara/spec/fixtures/no_extension +1 -0
  61. data/lib/capybara/spec/public/jquery-ui.js +13 -791
  62. data/lib/capybara/spec/public/jquery.js +4 -9045
  63. data/lib/capybara/spec/public/test.js +45 -11
  64. data/lib/capybara/spec/session/accept_alert_spec.rb +30 -7
  65. data/lib/capybara/spec/session/accept_confirm_spec.rb +14 -2
  66. data/lib/capybara/spec/session/accept_prompt_spec.rb +35 -6
  67. data/lib/capybara/spec/session/all_spec.rb +45 -32
  68. data/lib/capybara/spec/session/ancestor_spec.rb +85 -0
  69. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +110 -0
  70. data/lib/capybara/spec/session/assert_current_path.rb +15 -2
  71. data/lib/capybara/spec/session/assert_selector.rb +29 -28
  72. data/lib/capybara/spec/session/assert_text.rb +59 -20
  73. data/lib/capybara/spec/session/assert_title.rb +25 -11
  74. data/lib/capybara/spec/session/attach_file_spec.rb +42 -4
  75. data/lib/capybara/spec/session/body_spec.rb +1 -0
  76. data/lib/capybara/spec/session/check_spec.rb +90 -14
  77. data/lib/capybara/spec/session/choose_spec.rb +31 -5
  78. data/lib/capybara/spec/session/click_button_spec.rb +20 -9
  79. data/lib/capybara/spec/session/click_link_or_button_spec.rb +15 -9
  80. data/lib/capybara/spec/session/click_link_spec.rb +39 -15
  81. data/lib/capybara/spec/session/current_scope_spec.rb +2 -1
  82. data/lib/capybara/spec/session/current_url_spec.rb +12 -3
  83. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +6 -5
  84. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +4 -3
  85. data/lib/capybara/spec/session/element/assert_match_selector.rb +36 -0
  86. data/lib/capybara/spec/session/element/match_css_spec.rb +23 -0
  87. data/lib/capybara/spec/session/element/match_xpath_spec.rb +23 -0
  88. data/lib/capybara/spec/session/element/matches_selector_spec.rb +106 -0
  89. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +22 -0
  90. data/lib/capybara/spec/session/evaluate_script_spec.rb +23 -1
  91. data/lib/capybara/spec/session/execute_script_spec.rb +22 -3
  92. data/lib/capybara/spec/session/fill_in_spec.rb +50 -32
  93. data/lib/capybara/spec/session/find_button_spec.rb +43 -2
  94. data/lib/capybara/spec/session/find_by_id_spec.rb +3 -2
  95. data/lib/capybara/spec/session/find_field_spec.rb +42 -6
  96. data/lib/capybara/spec/session/find_link_spec.rb +22 -3
  97. data/lib/capybara/spec/session/find_spec.rb +103 -57
  98. data/lib/capybara/spec/session/first_spec.rb +34 -18
  99. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +103 -0
  100. data/lib/capybara/spec/session/{within_frame_spec.rb → frame/within_frame_spec.rb} +44 -2
  101. data/lib/capybara/spec/session/go_back_spec.rb +2 -1
  102. data/lib/capybara/spec/session/go_forward_spec.rb +2 -1
  103. data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
  104. data/lib/capybara/spec/session/has_button_spec.rb +17 -8
  105. data/lib/capybara/spec/session/has_css_spec.rb +85 -73
  106. data/lib/capybara/spec/session/has_current_path_spec.rb +91 -7
  107. data/lib/capybara/spec/session/has_field_spec.rb +93 -58
  108. data/lib/capybara/spec/session/has_link_spec.rb +9 -8
  109. data/lib/capybara/spec/session/has_none_selectors_spec.rb +76 -0
  110. data/lib/capybara/spec/session/has_select_spec.rb +159 -59
  111. data/lib/capybara/spec/session/has_selector_spec.rb +64 -28
  112. data/lib/capybara/spec/session/has_table_spec.rb +1 -0
  113. data/lib/capybara/spec/session/has_text_spec.rb +27 -12
  114. data/lib/capybara/spec/session/has_title_spec.rb +22 -4
  115. data/lib/capybara/spec/session/has_xpath_spec.rb +32 -29
  116. data/lib/capybara/spec/session/headers.rb +2 -1
  117. data/lib/capybara/spec/session/html_spec.rb +4 -3
  118. data/lib/capybara/spec/session/node_spec.rb +198 -38
  119. data/lib/capybara/spec/session/refresh_spec.rb +28 -0
  120. data/lib/capybara/spec/session/reset_session_spec.rb +46 -5
  121. data/lib/capybara/spec/session/response_code.rb +2 -1
  122. data/lib/capybara/spec/session/save_and_open_page_spec.rb +1 -0
  123. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +6 -5
  124. data/lib/capybara/spec/session/save_page_spec.rb +34 -2
  125. data/lib/capybara/spec/session/save_screenshot_spec.rb +31 -1
  126. data/lib/capybara/spec/session/screenshot_spec.rb +4 -2
  127. data/lib/capybara/spec/session/select_spec.rb +34 -32
  128. data/lib/capybara/spec/session/selectors_spec.rb +65 -0
  129. data/lib/capybara/spec/session/sibling_spec.rb +52 -0
  130. data/lib/capybara/spec/session/text_spec.rb +4 -4
  131. data/lib/capybara/spec/session/title_spec.rb +2 -1
  132. data/lib/capybara/spec/session/uncheck_spec.rb +42 -2
  133. data/lib/capybara/spec/session/unselect_spec.rb +17 -16
  134. data/lib/capybara/spec/session/visit_spec.rb +77 -2
  135. data/lib/capybara/spec/session/window/become_closed_spec.rb +12 -11
  136. data/lib/capybara/spec/session/window/current_window_spec.rb +1 -0
  137. data/lib/capybara/spec/session/window/open_new_window_spec.rb +1 -0
  138. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +16 -11
  139. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +7 -4
  140. data/lib/capybara/spec/session/window/window_spec.rb +36 -29
  141. data/lib/capybara/spec/session/window/windows_spec.rb +1 -0
  142. data/lib/capybara/spec/session/window/within_window_spec.rb +31 -7
  143. data/lib/capybara/spec/session/within_spec.rb +14 -6
  144. data/lib/capybara/spec/spec_helper.rb +37 -4
  145. data/lib/capybara/spec/test_app.rb +15 -3
  146. data/lib/capybara/spec/views/buttons.erb +1 -0
  147. data/lib/capybara/spec/views/fieldsets.erb +2 -1
  148. data/lib/capybara/spec/views/form.erb +169 -9
  149. data/lib/capybara/spec/views/frame_child.erb +10 -2
  150. data/lib/capybara/spec/views/frame_one.erb +2 -1
  151. data/lib/capybara/spec/views/frame_parent.erb +3 -2
  152. data/lib/capybara/spec/views/frame_two.erb +2 -1
  153. data/lib/capybara/spec/views/header_links.erb +1 -0
  154. data/lib/capybara/spec/views/host_links.erb +1 -0
  155. data/lib/capybara/spec/views/initial_alert.erb +10 -0
  156. data/lib/capybara/spec/views/path.erb +1 -0
  157. data/lib/capybara/spec/views/popup_one.erb +1 -0
  158. data/lib/capybara/spec/views/popup_two.erb +1 -0
  159. data/lib/capybara/spec/views/postback.erb +2 -1
  160. data/lib/capybara/spec/views/tables.erb +1 -0
  161. data/lib/capybara/spec/views/with_base_tag.erb +1 -0
  162. data/lib/capybara/spec/views/with_count.erb +2 -1
  163. data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
  164. data/lib/capybara/spec/views/with_hover.erb +7 -1
  165. data/lib/capybara/spec/views/with_html.erb +40 -2
  166. data/lib/capybara/spec/views/with_html_entities.erb +1 -0
  167. data/lib/capybara/spec/views/with_js.erb +32 -1
  168. data/lib/capybara/spec/views/with_scope.erb +1 -0
  169. data/lib/capybara/spec/views/with_simple_html.erb +2 -1
  170. data/lib/capybara/spec/views/with_slow_unload.erb +17 -0
  171. data/lib/capybara/spec/views/with_title.erb +2 -1
  172. data/lib/capybara/spec/views/with_unload_alert.erb +14 -0
  173. data/lib/capybara/spec/views/with_windows.erb +7 -0
  174. data/lib/capybara/spec/views/within_frames.erb +3 -2
  175. data/lib/capybara/version.rb +2 -1
  176. data/lib/capybara/window.rb +20 -3
  177. data/lib/capybara.rb +189 -93
  178. data/spec/basic_node_spec.rb +7 -6
  179. data/spec/capybara_spec.rb +90 -4
  180. data/spec/dsl_spec.rb +3 -1
  181. data/spec/filter_set_spec.rb +28 -0
  182. data/spec/fixtures/capybara.csv +1 -0
  183. data/spec/fixtures/selenium_driver_rspec_failure.rb +5 -1
  184. data/spec/fixtures/selenium_driver_rspec_success.rb +5 -1
  185. data/spec/minitest_spec.rb +130 -0
  186. data/spec/minitest_spec_spec.rb +135 -0
  187. data/spec/per_session_config_spec.rb +67 -0
  188. data/spec/rack_test_spec.rb +50 -7
  189. data/spec/result_spec.rb +76 -0
  190. data/spec/rspec/features_spec.rb +21 -8
  191. data/spec/rspec/scenarios_spec.rb +21 -0
  192. data/spec/rspec/{matchers_spec.rb → shared_spec_matchers.rb} +160 -54
  193. data/spec/rspec/views_spec.rb +5 -0
  194. data/spec/rspec_matchers_spec.rb +46 -0
  195. data/spec/rspec_spec.rb +79 -1
  196. data/spec/selector_spec.rb +199 -0
  197. data/spec/selenium_spec_chrome.rb +54 -9
  198. data/spec/selenium_spec_firefox.rb +68 -0
  199. data/spec/selenium_spec_marionette.rb +127 -0
  200. data/spec/server_spec.rb +102 -14
  201. data/spec/session_spec.rb +54 -0
  202. data/spec/shared_selenium_session.rb +215 -0
  203. data/spec/spec_helper.rb +7 -0
  204. metadata +140 -15
  205. data/spec/selenium_spec.rb +0 -128
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+ require 'forwardable'
3
+ require 'capybara/session/config'
4
+
5
+ module Capybara
6
+ class Config
7
+ extend Forwardable
8
+
9
+ OPTIONS = [:app, :reuse_server, :threadsafe, :default_wait_time, :server, :default_driver, :javascript_driver]
10
+
11
+ attr_accessor :app
12
+ attr_reader :reuse_server, :threadsafe
13
+ attr_reader :session_options
14
+ attr_writer :default_driver, :javascript_driver
15
+
16
+ SessionConfig::OPTIONS.each do |method|
17
+ def_delegators :session_options, method, "#{method}="
18
+ end
19
+
20
+ def initialize
21
+ @session_options = Capybara::SessionConfig.new
22
+ end
23
+
24
+ def reuse_server=(bool)
25
+ @reuse_server = bool
26
+ end
27
+
28
+ def threadsafe=(bool)
29
+ warn "Capybara.threadsafe == true is a BETA feature and may change in future minor versions" if bool
30
+ raise "Threadsafe setting cannot be changed once a session is created" if (bool != threadsafe) && Session.instance_created?
31
+ @threadsafe = bool
32
+ end
33
+
34
+ ##
35
+ #
36
+ # Return the proc that Capybara will call to run the Rack application.
37
+ # The block returned receives a rack app, port, and host/ip and should run a Rack handler
38
+ # By default, Capybara will try to run webrick.
39
+ #
40
+ def server(&block)
41
+ if block_given?
42
+ warn "DEPRECATED: Passing a block to Capybara::server is deprecated, please use Capybara::register_server instead"
43
+ @server = block
44
+ else
45
+ @server
46
+ end
47
+ end
48
+
49
+ ##
50
+ #
51
+ # Set the server to use.
52
+ #
53
+ # Capybara.server = :webrick
54
+ # Capybara.server = :puma, { Silent: true }
55
+ #
56
+ # @overload server=(name)
57
+ # @param [Symbol] name Name of the server type to use
58
+ # @overload server=([name, options])
59
+ # @param [Symbol] name Name of the server type to use
60
+ # @param [Hash] options Options to pass to the server block
61
+ # @see register_server
62
+ #
63
+ def server=(name)
64
+ name, options = *name if name.is_a? Array
65
+ @server = if name.respond_to? :call
66
+ name
67
+ else
68
+ if options
69
+ Proc.new { |app, port, host| Capybara.servers[name.to_sym].call(app,port,host,options) }
70
+ else
71
+ Capybara.servers[name.to_sym]
72
+ end
73
+ end
74
+ end
75
+
76
+ ##
77
+ #
78
+ # @return [Symbol] The name of the driver to use by default
79
+ #
80
+ def default_driver
81
+ @default_driver || :rack_test
82
+ end
83
+
84
+ ##
85
+ #
86
+ # @return [Symbol] The name of the driver used when JavaScript is needed
87
+ #
88
+ def javascript_driver
89
+ @javascript_driver || :selenium
90
+ end
91
+
92
+ # @deprecated Use default_max_wait_time instead
93
+ def default_wait_time
94
+ deprecate('default_wait_time', 'default_max_wait_time', true)
95
+ default_max_wait_time
96
+ end
97
+
98
+ # @deprecated Use default_max_wait_time= instead
99
+ def default_wait_time=(t)
100
+ deprecate('default_wait_time=', 'default_max_wait_time=')
101
+ self.default_max_wait_time = t
102
+ end
103
+
104
+ def deprecate(method, alternate_method, once=false)
105
+ @deprecation_notified ||= {}
106
+ warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead" unless once and @deprecation_notified[method]
107
+ @deprecation_notified[method]=true
108
+ end
109
+ end
110
+
111
+ # @api private
112
+ class ConfigureDeprecator
113
+ def initialize(config)
114
+ @config = config
115
+ end
116
+
117
+ def method_missing(m, *args, &block)
118
+ if @config.respond_to?(m)
119
+ @config.public_send(m, *args, &block)
120
+ elsif Capybara.respond_to?(m)
121
+ warn "Calling #{m} from Capybara.configure is deprecated - please call it on Capybara directly ( Capybara.#{m}(...) )"
122
+ Capybara.public_send(m, *args, &block)
123
+ else
124
+ super
125
+ end
126
+ end
127
+
128
+ def respond_to_missing?(m, include_private = false)
129
+ @config.respond_to?(m) || Capybara.respond_to?(m) || super
130
+ end
131
+ end
132
+ end
@@ -1,5 +1,7 @@
1
- require 'capybara'
1
+ # frozen_string_literal: true
2
+ require 'capybara/dsl'
2
3
  require 'capybara/rspec/matchers'
4
+ require 'capybara/rspec/matcher_proxies'
3
5
 
4
6
  World(Capybara::DSL)
5
7
  World(Capybara::RSpecMatchers)
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
1
2
  class Capybara::Driver::Base
3
+ attr_writer :session
4
+
2
5
  def current_url
3
6
  raise NotImplementedError
4
7
  end
@@ -7,6 +10,10 @@ class Capybara::Driver::Base
7
10
  raise NotImplementedError
8
11
  end
9
12
 
13
+ def refresh
14
+ raise NotImplementedError
15
+ end
16
+
10
17
  def find_xpath(query)
11
18
  raise NotImplementedError
12
19
  end
@@ -27,14 +34,18 @@ class Capybara::Driver::Base
27
34
  raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#go_forward'
28
35
  end
29
36
 
30
- def execute_script(script)
37
+ def execute_script(script, *args)
31
38
  raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#execute_script'
32
39
  end
33
40
 
34
- def evaluate_script(script)
41
+ def evaluate_script(script, *args)
35
42
  raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#evaluate_script'
36
43
  end
37
44
 
45
+ def evaluate_async_script(script, *args)
46
+ raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#evaluate_script_asnyc'
47
+ end
48
+
38
49
  def save_screenshot(path, options={})
39
50
  raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#save_screenshot'
40
51
  end
@@ -47,8 +58,12 @@ class Capybara::Driver::Base
47
58
  raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#status_code'
48
59
  end
49
60
 
50
- def within_frame(frame_handle)
51
- raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#within_frame'
61
+ ##
62
+ #
63
+ # @param frame [Capybara::Node::Element, :parent, :top] The iframe element to switch to
64
+ #
65
+ def switch_to_frame(frame)
66
+ raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#switch_to_frame'
52
67
  end
53
68
 
54
69
  def current_window_handle
@@ -90,8 +105,8 @@ class Capybara::Driver::Base
90
105
  def no_such_window_error
91
106
  raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#no_such_window_error'
92
107
  end
93
-
94
-
108
+
109
+
95
110
  ##
96
111
  #
97
112
  # Execute the block, and then accept the modal opened.
@@ -134,7 +149,13 @@ class Capybara::Driver::Base
134
149
  false
135
150
  end
136
151
 
152
+ def session_options
153
+ (@session && @session.config) || Capybara.session_options
154
+ end
155
+
156
+ # @deprecated This method is being removed
137
157
  def browser_initialized?
158
+ warn "DEPRECATED: #browser_initialized? is deprecated and will be removed in the next version of Capybara"
138
159
  true
139
160
  end
140
161
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Capybara
2
3
  module Driver
3
4
  class Node
@@ -41,23 +42,23 @@ module Capybara
41
42
  def click
42
43
  raise NotImplementedError
43
44
  end
44
-
45
+
45
46
  def right_click
46
47
  raise NotImplementedError
47
48
  end
48
-
49
+
49
50
  def double_click
50
51
  raise NotImplementedError
51
52
  end
52
-
53
+
53
54
  def send_keys(*args)
54
55
  raise NotImplementedError
55
56
  end
56
-
57
+
57
58
  def hover
58
59
  raise NotImplementedError
59
60
  end
60
-
61
+
61
62
  def drag_to(element)
62
63
  raise NotImplementedError
63
64
  end
@@ -82,6 +83,14 @@ module Capybara
82
83
  raise NotImplementedError
83
84
  end
84
85
 
86
+ def readonly?
87
+ !!self[:readonly]
88
+ end
89
+
90
+ def multiple?
91
+ !!self[:multiple]
92
+ end
93
+
85
94
  def path
86
95
  raise NotSupportedByDriverError, 'Capybara::Driver::Node#path'
87
96
  end
data/lib/capybara/dsl.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'capybara'
2
3
 
3
4
  module Capybara
@@ -20,12 +21,10 @@ module Capybara
20
21
  Capybara.using_session(name, &block)
21
22
  end
22
23
 
23
- ##
24
- #
25
24
  # Shortcut to using a different wait time.
26
25
  #
27
26
  def using_wait_time(seconds, &block)
28
- Capybara.using_wait_time(seconds, &block)
27
+ page.using_wait_time(seconds, &block)
29
28
  end
30
29
 
31
30
  ##
@@ -1,4 +1,5 @@
1
1
  # encoding: UTF-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module Capybara
4
5
 
@@ -27,8 +28,14 @@ module Capybara
27
28
  # @param [String] text Text to escape
28
29
  # @return [String] Escaped text
29
30
  #
30
- def to_regexp(text)
31
- text.is_a?(Regexp) ? text : Regexp.new(Regexp.escape(normalize_whitespace(text)))
31
+ def to_regexp(text, regexp_options=nil, exact=false)
32
+ if text.is_a?(Regexp)
33
+ text
34
+ else
35
+ escaped = Regexp.escape(normalize_whitespace(text))
36
+ escaped = "\\A#{escaped}\\z" if exact
37
+ Regexp.new(escaped, regexp_options)
38
+ end
32
39
  end
33
40
 
34
41
  ##
@@ -39,76 +46,17 @@ module Capybara
39
46
  # @param [String] html HTML code to inject into
40
47
  # @return [String] The modified HTML code
41
48
  #
42
- def inject_asset_host(html)
43
- if Capybara.asset_host && Nokogiri::HTML(html).css("base").empty?
49
+ def inject_asset_host(html, asset_host = Capybara.asset_host)
50
+ if asset_host && Nokogiri::HTML(html).css("base").empty?
44
51
  match = html.match(/<head[^<]*?>/)
45
52
  if match
46
- return html.clone.insert match.end(0), "<base href='#{Capybara.asset_host}' />"
53
+ return html.clone.insert match.end(0), "<base href='#{asset_host}' />"
47
54
  end
48
55
  end
49
56
 
50
57
  html
51
58
  end
52
59
 
53
- ##
54
- #
55
- # Checks if the given count matches the given count options.
56
- # Defaults to true if no options are specified. If multiple
57
- # options are provided, it tests that all conditions are met;
58
- # however, if :count is supplied, all other options are ignored.
59
- #
60
- # @param [Integer] count The actual number. Should be coercible via Integer()
61
- # @option [Range] between Count must be within the given range
62
- # @option [Integer] count Count must be exactly this
63
- # @option [Integer] maximum Count must be smaller than or equal to this value
64
- # @option [Integer] minimum Count must be larger than or equal to this value
65
- #
66
- def matches_count?(count, options={})
67
- return (Integer(options[:count]) == count) if options[:count]
68
- return false if options[:maximum] && (Integer(options[:maximum]) < count)
69
- return false if options[:minimum] && (Integer(options[:minimum]) > count)
70
- return false if options[:between] && !(options[:between] === count)
71
- return true
72
- end
73
-
74
- ##
75
- #
76
- # Checks if a count of 0 is valid for the given options hash.
77
- # Returns false if options hash does not specify any count options.
78
- #
79
- def expects_none?(options={})
80
- if [:count, :maximum, :minimum, :between].any? { |k| options.has_key? k }
81
- matches_count?(0,options)
82
- else
83
- false
84
- end
85
- end
86
-
87
- ##
88
- #
89
- # Generates a failure message given a description of the query and count
90
- # options.
91
- #
92
- # @param [String] description Description of a query
93
- # @option [Range] between Count should have been within the given range
94
- # @option [Integer] count Count should have been exactly this
95
- # @option [Integer] maximum Count should have been smaller than or equal to this value
96
- # @option [Integer] minimum Count should have been larger than or equal to this value
97
- #
98
- def failure_message(description, options={})
99
- message = "expected to find #{description}"
100
- if options[:count]
101
- message << " #{options[:count]} #{declension('time', 'times', options[:count])}"
102
- elsif options[:between]
103
- message << " between #{options[:between].first} and #{options[:between].last} times"
104
- elsif options[:maximum]
105
- message << " at most #{options[:maximum]} #{declension('time', 'times', options[:maximum])}"
106
- elsif options[:minimum]
107
- message << " at least #{options[:minimum]} #{declension('time', 'times', options[:minimum])}"
108
- end
109
- message
110
- end
111
-
112
60
  ##
113
61
  #
114
62
  # A poor man's `pluralize`. Given two declensions, one singular and one
@@ -129,7 +77,7 @@ module Capybara
129
77
 
130
78
  if defined?(Process::CLOCK_MONOTONIC)
131
79
  def monotonic_time
132
- Process.clock_gettime Process::CLOCK_MONOTONIC
80
+ Process.clock_gettime Process::CLOCK_MONOTONIC
133
81
  end
134
82
  else
135
83
  def monotonic_time
@@ -0,0 +1,177 @@
1
+ require 'minitest/spec'
2
+
3
+ module Capybara
4
+ module Minitest
5
+ module Expectations
6
+ %w(text content title current_path).each do |assertion|
7
+ infect_an_assertion "assert_#{assertion}", "must_have_#{assertion}", :reverse
8
+ infect_an_assertion "refute_#{assertion}", "wont_have_#{assertion}", :reverse
9
+ end
10
+
11
+ (%w(selector xpath css link button field select table checked_field unchecked_field).flat_map do |assertion|
12
+ [["assert_#{assertion}", "must_have_#{assertion}"],
13
+ ["refute_#{assertion}", "wont_have_#{assertion}"]]
14
+ end + [["assert_all_of_selectors", "must_have_all_of_selectors"],
15
+ ["assert_none_of_selectors", "must_have_none_of_selectors"]] +
16
+ %w(selector xpath css).flat_map do |assertion|
17
+ [["assert_matches_#{assertion}", "must_match_#{assertion}"],
18
+ ["refute_matches_#{assertion}", "wont_match_#{assertion}"]]
19
+ end).each do |(meth, new_name)|
20
+ self.class_eval <<-EOM, __FILE__, __LINE__ + 1
21
+ def #{new_name} *args, &block
22
+ ::Minitest::Expectation.new(self, ::Minitest::Spec.current).#{new_name}(*args, &block)
23
+ end
24
+ EOM
25
+
26
+ ::Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1
27
+ def #{new_name} *args, &block
28
+ ctx.#{meth}(target, *args, &block)
29
+ end
30
+ EOM
31
+ end
32
+
33
+ ##
34
+ # Expectation that there is xpath
35
+ #
36
+ # @!method must_have_xpath
37
+ # see Capybara::Node::Matchers#has_xpath?
38
+
39
+ ##
40
+ # Expectation that there is no xpath
41
+ #
42
+ # @!method wont_have_xpath
43
+ # see Capybara::Node::Matchers#has_no_xpath?
44
+
45
+ ##
46
+ # Expectation that there is css
47
+ #
48
+ # @!method must_have_css
49
+ # see Capybara::Node::Matchers#has_css?
50
+
51
+ ##
52
+ # Expectation that there is no css
53
+ #
54
+ # @!method wont_have_css
55
+ # see Capybara::Node::Matchers#has_no_css?
56
+
57
+ ##
58
+ # Expectation that there is link
59
+ #
60
+ # @!method must_have_link
61
+ # see {Capybara::Node::Matchers#has_link?}
62
+
63
+ ##
64
+ # Expectation that there is no link
65
+ #
66
+ # @!method wont_have_link
67
+ # see {Capybara::Node::Matchers#has_no_link?}
68
+
69
+ ##
70
+ # Expectation that there is button
71
+ #
72
+ # @!method must_have_button
73
+ # see {Capybara::Node::Matchers#has_button?}
74
+
75
+ ##
76
+ # Expectation that there is no button
77
+ #
78
+ # @!method wont_have_button
79
+ # see {Capybara::Node::Matchers#has_no_button?}
80
+
81
+ ##
82
+ # Expectation that there is field
83
+ #
84
+ # @!method must_have_field
85
+ # see {Capybara::Node::Matchers#has_field?}
86
+
87
+ ##
88
+ # Expectation that there is no field
89
+ #
90
+ # @!method wont_have_field
91
+ # see {Capybara::Node::Matchers#has_no_field?}
92
+
93
+ ##
94
+ # Expectation that there is checked_field
95
+ #
96
+ # @!method must_have_checked_field
97
+ # see {Capybara::Node::Matchers#has_checked_field?}
98
+
99
+ ##
100
+ # Expectation that there is no checked_field
101
+ #
102
+ # @!method wont_have_chceked_field
103
+
104
+ ##
105
+ # Expectation that there is unchecked_field
106
+ #
107
+ # @!method must_have_unchecked_field
108
+ # see {Capybara::Node::Matchers#has_unchecked_field?}
109
+
110
+ ##
111
+ # Expectation that there is no unchecked_field
112
+ #
113
+ # @!method wont_have_unchceked_field
114
+
115
+ ##
116
+ # Expectation that there is select
117
+ #
118
+ # @!method must_have_select
119
+ # see {Capybara::Node::Matchers#has_select?}
120
+
121
+ ##
122
+ # Expectation that there is no select
123
+ #
124
+ # @!method wont_have_select
125
+ # see {Capybara::Node::Matchers#has_no_select?}
126
+
127
+ ##
128
+ # Expectation that there is table
129
+ #
130
+ # @!method must_have_table
131
+ # see {Capybara::Node::Matchers#has_table?}
132
+
133
+ ##
134
+ # Expectation that there is no table
135
+ #
136
+ # @!method wont_have_table
137
+ # see {Capybara::Node::Matchers#has_no_table?}
138
+
139
+ ##
140
+ # Expectation that page title does match
141
+ #
142
+ # @!method must_have_title
143
+ # see {Capybara::Node::DocumentMatchers#assert_title}
144
+
145
+ ##
146
+ # Expectation that page title does not match
147
+ #
148
+ # @!method wont_have_title
149
+ # see {Capybara::Node::DocumentMatchers#assert_no_title}
150
+
151
+ ##
152
+ # Expectation that current path matches
153
+ #
154
+ # @!method must_have_current_path
155
+ # see {Capybara::SessionMatchers#assert_current_path}
156
+
157
+ ##
158
+ # Expectation that current page does not match
159
+ #
160
+ # @!method wont_have_current_path
161
+ # see {Capybara::SessionMatchers#assert_no_current_path}
162
+
163
+ end
164
+ end
165
+ end
166
+
167
+ class Capybara::Session
168
+ include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
169
+ end
170
+
171
+ class Capybara::Node::Base
172
+ include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
173
+ end
174
+
175
+ class Capybara::Node::Simple
176
+ include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
177
+ end