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.
- checksums.yaml +5 -5
- data/History.md +218 -18
- data/README.md +54 -23
- data/lib/capybara/config.rb +132 -0
- data/lib/capybara/cucumber.rb +1 -0
- data/lib/capybara/driver/base.rb +14 -0
- data/lib/capybara/dsl.rb +1 -3
- data/lib/capybara/helpers.rb +3 -3
- data/lib/capybara/minitest/spec.rb +14 -37
- data/lib/capybara/minitest.rb +95 -114
- data/lib/capybara/node/actions.rb +10 -10
- data/lib/capybara/node/base.rb +7 -2
- data/lib/capybara/node/element.rb +9 -3
- data/lib/capybara/node/finders.rb +92 -18
- data/lib/capybara/node/matchers.rb +21 -9
- data/lib/capybara/node/simple.rb +5 -0
- data/lib/capybara/queries/ancestor_query.rb +25 -0
- data/lib/capybara/queries/base_query.rb +12 -3
- data/lib/capybara/queries/current_path_query.rb +13 -9
- data/lib/capybara/queries/selector_query.rb +62 -23
- data/lib/capybara/queries/sibling_query.rb +25 -0
- data/lib/capybara/queries/text_query.rb +10 -5
- data/lib/capybara/queries/title_query.rb +1 -0
- data/lib/capybara/rack_test/browser.rb +13 -5
- data/lib/capybara/rack_test/driver.rb +6 -1
- data/lib/capybara/rack_test/form.rb +4 -3
- data/lib/capybara/rack_test/node.rb +1 -1
- data/lib/capybara/rspec/compound.rb +95 -0
- data/lib/capybara/rspec/matcher_proxies.rb +45 -0
- data/lib/capybara/rspec/matchers.rb +108 -7
- data/lib/capybara/rspec.rb +3 -1
- data/lib/capybara/selector/filter.rb +13 -41
- data/lib/capybara/selector/filter_set.rb +30 -4
- data/lib/capybara/selector/filters/base.rb +33 -0
- data/lib/capybara/selector/filters/expression_filter.rb +40 -0
- data/lib/capybara/selector/filters/node_filter.rb +27 -0
- data/lib/capybara/selector/selector.rb +36 -15
- data/lib/capybara/selector.rb +63 -42
- data/lib/capybara/selenium/driver.rb +177 -33
- data/lib/capybara/selenium/node.rb +106 -55
- data/lib/capybara/server.rb +6 -5
- data/lib/capybara/session/config.rb +114 -0
- data/lib/capybara/session/matchers.rb +15 -4
- data/lib/capybara/session.rb +178 -65
- data/lib/capybara/spec/fixtures/no_extension +1 -0
- data/lib/capybara/spec/public/test.js +18 -3
- data/lib/capybara/spec/session/accept_alert_spec.rb +9 -1
- data/lib/capybara/spec/session/accept_prompt_spec.rb +29 -1
- data/lib/capybara/spec/session/all_spec.rb +13 -1
- data/lib/capybara/spec/session/ancestor_spec.rb +85 -0
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +24 -8
- data/lib/capybara/spec/session/assert_selector.rb +1 -1
- data/lib/capybara/spec/session/assert_text.rb +8 -0
- data/lib/capybara/spec/session/assert_title.rb +22 -9
- data/lib/capybara/spec/session/attach_file_spec.rb +8 -1
- data/lib/capybara/spec/session/check_spec.rb +4 -4
- data/lib/capybara/spec/session/choose_spec.rb +2 -2
- data/lib/capybara/spec/session/click_button_spec.rb +1 -1
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +3 -3
- data/lib/capybara/spec/session/click_link_spec.rb +1 -1
- data/lib/capybara/spec/session/current_url_spec.rb +3 -3
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +1 -1
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +22 -0
- data/lib/capybara/spec/session/evaluate_script_spec.rb +1 -1
- data/lib/capybara/spec/session/fill_in_spec.rb +8 -2
- data/lib/capybara/spec/session/find_field_spec.rb +1 -0
- data/lib/capybara/spec/session/find_spec.rb +8 -6
- data/lib/capybara/spec/session/first_spec.rb +10 -5
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
- data/lib/capybara/spec/session/has_css_spec.rb +11 -0
- data/lib/capybara/spec/session/has_current_path_spec.rb +52 -7
- data/lib/capybara/spec/session/has_link_spec.rb +4 -4
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +76 -0
- data/lib/capybara/spec/session/has_select_spec.rb +64 -6
- data/lib/capybara/spec/session/has_selector_spec.rb +1 -3
- data/lib/capybara/spec/session/has_text_spec.rb +5 -3
- data/lib/capybara/spec/session/has_title_spec.rb +4 -2
- data/lib/capybara/spec/session/has_xpath_spec.rb +5 -3
- data/lib/capybara/spec/session/node_spec.rb +50 -26
- data/lib/capybara/spec/session/refresh_spec.rb +28 -0
- data/lib/capybara/spec/session/reset_session_spec.rb +3 -3
- data/lib/capybara/spec/session/select_spec.rb +3 -2
- data/lib/capybara/spec/session/sibling_spec.rb +52 -0
- data/lib/capybara/spec/session/uncheck_spec.rb +2 -2
- data/lib/capybara/spec/session/unselect_spec.rb +2 -2
- data/lib/capybara/spec/session/visit_spec.rb +56 -1
- data/lib/capybara/spec/session/window/become_closed_spec.rb +11 -11
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +11 -9
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +4 -4
- data/lib/capybara/spec/session/window/within_window_spec.rb +27 -2
- data/lib/capybara/spec/spec_helper.rb +28 -4
- data/lib/capybara/spec/test_app.rb +3 -1
- data/lib/capybara/spec/views/form.erb +27 -1
- data/lib/capybara/spec/views/initial_alert.erb +10 -0
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
- data/lib/capybara/spec/views/with_hover.erb +5 -0
- data/lib/capybara/spec/views/with_html.erb +33 -2
- data/lib/capybara/spec/views/with_js.erb +12 -0
- data/lib/capybara/spec/views/with_windows.erb +4 -0
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +1 -1
- data/lib/capybara.rb +102 -124
- data/spec/capybara_spec.rb +43 -21
- data/spec/dsl_spec.rb +1 -0
- data/spec/filter_set_spec.rb +28 -0
- data/spec/minitest_spec.rb +9 -1
- data/spec/minitest_spec_spec.rb +19 -5
- data/spec/per_session_config_spec.rb +67 -0
- data/spec/result_spec.rb +20 -0
- data/spec/rspec/shared_spec_matchers.rb +148 -44
- data/spec/rspec/views_spec.rb +4 -0
- data/spec/rspec_matchers_spec.rb +46 -0
- data/spec/rspec_spec.rb +77 -0
- data/spec/selector_spec.rb +2 -1
- data/spec/selenium_spec_chrome.rb +25 -17
- data/spec/selenium_spec_firefox.rb +2 -1
- data/spec/selenium_spec_marionette.rb +18 -5
- data/spec/session_spec.rb +44 -0
- data/spec/shared_selenium_session.rb +72 -8
- data/spec/spec_helper.rb +4 -0
- metadata +55 -8
@@ -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
|
data/lib/capybara/cucumber.rb
CHANGED
data/lib/capybara/driver/base.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
class Capybara::Driver::Base
|
3
|
+
attr_writer :session
|
4
|
+
|
3
5
|
def current_url
|
4
6
|
raise NotImplementedError
|
5
7
|
end
|
@@ -8,6 +10,10 @@ class Capybara::Driver::Base
|
|
8
10
|
raise NotImplementedError
|
9
11
|
end
|
10
12
|
|
13
|
+
def refresh
|
14
|
+
raise NotImplementedError
|
15
|
+
end
|
16
|
+
|
11
17
|
def find_xpath(query)
|
12
18
|
raise NotImplementedError
|
13
19
|
end
|
@@ -36,6 +42,10 @@ class Capybara::Driver::Base
|
|
36
42
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#evaluate_script'
|
37
43
|
end
|
38
44
|
|
45
|
+
def evaluate_async_script(script, *args)
|
46
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#evaluate_script_asnyc'
|
47
|
+
end
|
48
|
+
|
39
49
|
def save_screenshot(path, options={})
|
40
50
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#save_screenshot'
|
41
51
|
end
|
@@ -139,6 +149,10 @@ class Capybara::Driver::Base
|
|
139
149
|
false
|
140
150
|
end
|
141
151
|
|
152
|
+
def session_options
|
153
|
+
(@session && @session.config) || Capybara.session_options
|
154
|
+
end
|
155
|
+
|
142
156
|
# @deprecated This method is being removed
|
143
157
|
def browser_initialized?
|
144
158
|
warn "DEPRECATED: #browser_initialized? is deprecated and will be removed in the next version of Capybara"
|
data/lib/capybara/dsl.rb
CHANGED
@@ -21,12 +21,10 @@ module Capybara
|
|
21
21
|
Capybara.using_session(name, &block)
|
22
22
|
end
|
23
23
|
|
24
|
-
##
|
25
|
-
#
|
26
24
|
# Shortcut to using a different wait time.
|
27
25
|
#
|
28
26
|
def using_wait_time(seconds, &block)
|
29
|
-
|
27
|
+
page.using_wait_time(seconds, &block)
|
30
28
|
end
|
31
29
|
|
32
30
|
##
|
data/lib/capybara/helpers.rb
CHANGED
@@ -46,11 +46,11 @@ module Capybara
|
|
46
46
|
# @param [String] html HTML code to inject into
|
47
47
|
# @return [String] The modified HTML code
|
48
48
|
#
|
49
|
-
def inject_asset_host(html)
|
50
|
-
if
|
49
|
+
def inject_asset_host(html, asset_host = Capybara.asset_host)
|
50
|
+
if asset_host && Nokogiri::HTML(html).css("base").empty?
|
51
51
|
match = html.match(/<head[^<]*?>/)
|
52
52
|
if match
|
53
|
-
return html.clone.insert match.end(0), "<base href='#{
|
53
|
+
return html.clone.insert match.end(0), "<base href='#{asset_host}' />"
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -8,47 +8,24 @@ module Capybara
|
|
8
8
|
infect_an_assertion "refute_#{assertion}", "wont_have_#{assertion}", :reverse
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
::Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
24
|
-
def must_have_#{assertion} *args, &optional_filter_block
|
25
|
-
ctx.assert_#{assertion}(target, *args, &optional_filter_block)
|
26
|
-
end
|
27
|
-
|
28
|
-
def wont_have_#{assertion} *args, &optional_filter_block
|
29
|
-
ctx.refute_#{assertion}(target, *args, &optional_filter_block)
|
30
|
-
end
|
31
|
-
EOM
|
32
|
-
end
|
33
|
-
|
34
|
-
%w(selector xpath css).each do |assertion|
|
35
|
-
self.class_eval <<-EOM
|
36
|
-
def must_match_#{assertion} *args, &optional_filter_block
|
37
|
-
::Minitest::Expectation.new(self, ::Minitest::Spec.current).must_match_#{assertion}(*args, &optional_filter_block)
|
38
|
-
end
|
39
|
-
|
40
|
-
def wont_match_#{assertion} *args, &optional_filter_block
|
41
|
-
::Minitest::Expectation.new(self, ::Minitest::Spec.current).wont_match_#{assertion}(*args, &optional_filter_block)
|
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)
|
42
23
|
end
|
43
24
|
EOM
|
44
25
|
|
45
26
|
::Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
46
|
-
def
|
47
|
-
ctx
|
48
|
-
end
|
49
|
-
|
50
|
-
def wont_match_#{assertion} *args, &optional_filter_block
|
51
|
-
ctx.refute_matches_#{assertion}(target, *args, &optional_filter_block)
|
27
|
+
def #{new_name} *args, &block
|
28
|
+
ctx.#{meth}(target, *args, &block)
|
52
29
|
end
|
53
30
|
EOM
|
54
31
|
end
|
data/lib/capybara/minitest.rb
CHANGED
@@ -6,141 +6,142 @@ module Capybara
|
|
6
6
|
module Minitest
|
7
7
|
module Assertions
|
8
8
|
## Assert text exists
|
9
|
+
#
|
10
|
+
# @!method assert_text
|
9
11
|
# see {Capybara::Node::Matchers#assert_text}
|
10
|
-
def assert_text(*args)
|
11
|
-
self.assertions += 1
|
12
|
-
subject, *args = determine_subject(args)
|
13
|
-
subject.assert_text(*args)
|
14
|
-
rescue Capybara::ExpectationNotMet => e
|
15
|
-
raise ::Minitest::Assertion, e.message
|
16
|
-
end
|
17
|
-
alias_method :assert_content, :assert_text
|
18
12
|
|
19
13
|
## Assert text does not exist
|
14
|
+
#
|
15
|
+
# @!method assert_no_text
|
20
16
|
# see {Capybara::Node::Matchers#assert_no_text}
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
17
|
+
|
18
|
+
##
|
19
|
+
# Assertion that page title does match
|
20
|
+
#
|
21
|
+
# @!method assert_title
|
22
|
+
# see {Capybara::Node::DocumentMatchers#assert_title}
|
23
|
+
|
24
|
+
##
|
25
|
+
# Assertion that page title does not match
|
26
|
+
#
|
27
|
+
# @!method refute_title
|
28
|
+
# @!method assert_no_title
|
29
|
+
# see {Capybara::Node::DocumentMatchers#assert_no_title}
|
30
|
+
|
31
|
+
##
|
32
|
+
# Assertion that current path matches
|
33
|
+
#
|
34
|
+
# @!method assert_current_path
|
35
|
+
# see {Capybara::SessionMatchers#assert_current_path}
|
36
|
+
|
37
|
+
##
|
38
|
+
# Assertion that current page does not match
|
39
|
+
#
|
40
|
+
# @!method refute_current_path
|
41
|
+
# @!method assert_no_current_path
|
42
|
+
# see {Capybara::SessionMatchers#assert_no_current_path}
|
43
|
+
|
44
|
+
|
45
|
+
%w(assert_text assert_no_text assert_title assert_no_title assert_current_path assert_no_current_path).each do |assertion_name|
|
46
|
+
self.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
47
|
+
def #{assertion_name} *args
|
48
|
+
self.assertions +=1
|
49
|
+
subject, *args = determine_subject(args)
|
50
|
+
subject.#{assertion_name}(*args)
|
51
|
+
rescue Capybara::ExpectationNotMet => e
|
52
|
+
raise ::Minitest::Assertion, e.message
|
53
|
+
end
|
54
|
+
EOM
|
27
55
|
end
|
56
|
+
|
57
|
+
alias_method :refute_title, :assert_no_title
|
28
58
|
alias_method :refute_text, :assert_no_text
|
29
59
|
alias_method :refute_content, :refute_text
|
60
|
+
alias_method :refute_current_path, :assert_no_current_path
|
61
|
+
alias_method :assert_content, :assert_text
|
30
62
|
alias_method :assert_no_content, :refute_text
|
31
63
|
|
32
64
|
## Assert selector exists on page
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
subject, *args = determine_subject(args)
|
37
|
-
subject.assert_selector(*args, &optional_filter_block)
|
38
|
-
rescue Capybara::ExpectationNotMet => e
|
39
|
-
raise ::Minitest::Assertion, e.message
|
40
|
-
end
|
65
|
+
#
|
66
|
+
# @!method assert_selector
|
67
|
+
# see {Capybara::Node::Matchers#assert_selector}
|
41
68
|
|
42
69
|
## Assert selector does not exist on page
|
43
|
-
#
|
44
|
-
|
45
|
-
|
46
|
-
subject, *args = determine_subject(args)
|
47
|
-
subject.assert_no_selector(*args, &optional_filter_block)
|
48
|
-
rescue Capybara::ExpectationNotMet => e
|
49
|
-
raise ::Minitest::Assertion, e.message
|
50
|
-
end
|
51
|
-
alias_method :refute_selector, :assert_no_selector
|
70
|
+
#
|
71
|
+
# @!method assert_no_selector
|
72
|
+
# see {Capybara::Node::Matchers#assert_no_selector}
|
52
73
|
|
53
74
|
## Assert element matches selector
|
54
|
-
#
|
55
|
-
|
56
|
-
|
57
|
-
subject, *args = determine_subject(args)
|
58
|
-
subject.assert_matches_selector(*args, &optional_filter_block)
|
59
|
-
rescue Capybara::ExpectationNotMet => e
|
60
|
-
raise ::Minitest::Assertion, e.message
|
61
|
-
end
|
75
|
+
#
|
76
|
+
# @!method assert_matches_selector
|
77
|
+
# see {Capybara::Node::Matchers#assert_matches_selector}
|
62
78
|
|
63
79
|
## Assert element does not match selector
|
64
|
-
#
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
%w(title current_path).each do |selector_type|
|
75
|
-
define_method "assert_#{selector_type}" do |*args|
|
76
|
-
begin
|
77
|
-
self.assertions += 1
|
78
|
-
subject, *args = determine_subject(args)
|
79
|
-
subject.public_send("assert_#{selector_type}",*args)
|
80
|
-
rescue Capybara::ExpectationNotMet => e
|
81
|
-
raise ::Minitest::Assertion, e.message
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
define_method "assert_no_#{selector_type}" do |*args|
|
86
|
-
begin
|
87
|
-
self.assertions += 1
|
80
|
+
#
|
81
|
+
# @!method assert_xpath
|
82
|
+
# see {Capybara::Node::Matchers#assert_not_matches_selector}
|
83
|
+
|
84
|
+
%w(assert_selector assert_no_selector
|
85
|
+
assert_all_of_selectors assert_none_of_selectors
|
86
|
+
assert_matches_selector assert_not_matches_selector).each do |assertion_name|
|
87
|
+
self.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
88
|
+
def #{assertion_name} *args, &optional_filter_block
|
89
|
+
self.assertions +=1
|
88
90
|
subject, *args = determine_subject(args)
|
89
|
-
subject
|
91
|
+
subject.#{assertion_name}(*args, &optional_filter_block)
|
90
92
|
rescue Capybara::ExpectationNotMet => e
|
91
93
|
raise ::Minitest::Assertion, e.message
|
92
94
|
end
|
93
|
-
|
94
|
-
alias_method "refute_#{selector_type}", "assert_no_#{selector_type}"
|
95
|
+
EOM
|
95
96
|
end
|
96
97
|
|
98
|
+
alias_method :refute_selector, :assert_no_selector
|
99
|
+
alias_method :refute_matches_selector, :assert_not_matches_selector
|
100
|
+
|
97
101
|
%w(xpath css link button field select table).each do |selector_type|
|
98
102
|
define_method "assert_#{selector_type}" do |*args, &optional_filter_block|
|
99
103
|
subject, *args = determine_subject(args)
|
100
|
-
locator, options =
|
101
|
-
locator, options = nil, locator if locator.is_a? Hash
|
104
|
+
locator, options = extract_locator(args)
|
102
105
|
assert_selector(subject, selector_type.to_sym, locator, options, &optional_filter_block)
|
103
106
|
end
|
104
107
|
|
105
108
|
define_method "assert_no_#{selector_type}" do |*args, &optional_filter_block|
|
106
109
|
subject, *args = determine_subject(args)
|
107
|
-
locator, options =
|
108
|
-
locator, options = nil, locator if locator.is_a? Hash
|
110
|
+
locator, options = extract_locator(args)
|
109
111
|
assert_no_selector(subject, selector_type.to_sym, locator, options, &optional_filter_block)
|
110
112
|
end
|
111
113
|
alias_method "refute_#{selector_type}", "assert_no_#{selector_type}"
|
112
114
|
end
|
113
115
|
|
114
|
-
%w(
|
115
|
-
define_method "
|
116
|
+
%w(checked unchecked).each do |field_type|
|
117
|
+
define_method "assert_#{field_type}_field" do |*args, &optional_filter_block|
|
116
118
|
subject, *args = determine_subject(args)
|
117
|
-
|
119
|
+
locator, options = extract_locator(args)
|
120
|
+
assert_selector(subject, :field, locator, options.merge(field_type.to_sym => true), &optional_filter_block)
|
118
121
|
end
|
119
122
|
|
120
|
-
define_method "
|
123
|
+
define_method "assert_no_#{field_type}_field" do |*args, &optional_filter_block|
|
121
124
|
subject, *args = determine_subject(args)
|
122
|
-
|
125
|
+
locator, options = extract_locator(args)
|
126
|
+
assert_no_selector(subject, :field, locator, options.merge(field_type.to_sym => true), &optional_filter_block)
|
123
127
|
end
|
124
|
-
alias_method "
|
128
|
+
alias_method "refute_#{field_type}_field", "assert_no_#{field_type}_field"
|
125
129
|
end
|
126
130
|
|
127
|
-
%w(
|
128
|
-
define_method "
|
131
|
+
%w(xpath css).each do |selector_type|
|
132
|
+
define_method "assert_matches_#{selector_type}" do |*args, &optional_filter_block|
|
129
133
|
subject, *args = determine_subject(args)
|
130
|
-
|
131
|
-
locator, options = nil, locator if locator.is_a? Hash
|
132
|
-
assert_selector(subject, :field, locator, options.merge(field_type.to_sym => true), &optional_filter_block)
|
134
|
+
assert_matches_selector(subject, selector_type.to_sym, *args, &optional_filter_block)
|
133
135
|
end
|
134
136
|
|
135
|
-
define_method "
|
137
|
+
define_method "assert_not_matches_#{selector_type}" do |*args, &optional_filter_block|
|
136
138
|
subject, *args = determine_subject(args)
|
137
|
-
|
138
|
-
locator, options = nil, locator if locator.is_a? Hash
|
139
|
-
assert_no_selector(subject, :field, locator, options.merge(field_type.to_sym => true), &optional_filter_block)
|
139
|
+
assert_not_matches_selector(subject, selector_type.to_sym, *args, &optional_filter_block)
|
140
140
|
end
|
141
|
-
alias_method "
|
141
|
+
alias_method "refute_matches_#{selector_type}", "assert_not_matches_#{selector_type}"
|
142
142
|
end
|
143
143
|
|
144
|
+
|
144
145
|
##
|
145
146
|
# Assertion that there is xpath
|
146
147
|
#
|
@@ -216,7 +217,7 @@ module Capybara
|
|
216
217
|
# Assertion that there is no checked_field
|
217
218
|
#
|
218
219
|
# @!method assert_no_checked_field
|
219
|
-
# @!method
|
220
|
+
# @!method refute_checked_field
|
220
221
|
|
221
222
|
##
|
222
223
|
# Assertion that there is unchecked_field
|
@@ -228,7 +229,7 @@ module Capybara
|
|
228
229
|
# Assertion that there is no unchecked_field
|
229
230
|
#
|
230
231
|
# @!method assert_no_unchecked_field
|
231
|
-
# @!method
|
232
|
+
# @!method refute_unchecked_field
|
232
233
|
|
233
234
|
##
|
234
235
|
# Assertion that there is select
|
@@ -256,32 +257,6 @@ module Capybara
|
|
256
257
|
# @!method assert_no_table
|
257
258
|
# see {Capybara::Node::Matchers#has_no_table?}
|
258
259
|
|
259
|
-
##
|
260
|
-
# Assertion that page title does match
|
261
|
-
#
|
262
|
-
# @!method assert_title
|
263
|
-
# see {Capybara::Node::DocumentMatchers#assert_title}
|
264
|
-
|
265
|
-
##
|
266
|
-
# Assertion that page title does not match
|
267
|
-
#
|
268
|
-
# @!method refute_title
|
269
|
-
# @!method assert_no_title
|
270
|
-
# see {Capybara::Node::DocumentMatchers#assert_no_title}
|
271
|
-
|
272
|
-
##
|
273
|
-
# Assertion that current path matches
|
274
|
-
#
|
275
|
-
# @!method assert_current_path
|
276
|
-
# see {Capybara::SessionMatchers#assert_current_path}
|
277
|
-
|
278
|
-
##
|
279
|
-
# Assertion that current page does not match
|
280
|
-
#
|
281
|
-
# @!method refute_current_path
|
282
|
-
# @!method assert_no_current_path
|
283
|
-
# see {Capybara::SessionMatchers#assert_no_current_path}
|
284
|
-
|
285
260
|
private
|
286
261
|
|
287
262
|
def determine_subject(args)
|
@@ -292,6 +267,12 @@ module Capybara
|
|
292
267
|
[page, *args]
|
293
268
|
end
|
294
269
|
end
|
270
|
+
|
271
|
+
def extract_locator(args)
|
272
|
+
locator, options = *args, {}
|
273
|
+
locator, options = nil, locator if locator.is_a? Hash
|
274
|
+
[locator, options]
|
275
|
+
end
|
295
276
|
end
|
296
277
|
end
|
297
278
|
end
|
@@ -5,8 +5,8 @@ module Capybara
|
|
5
5
|
|
6
6
|
##
|
7
7
|
#
|
8
|
-
# Finds a button or link
|
9
|
-
#
|
8
|
+
# Finds a button or link and clicks it. See {Capybara::Node::Actions#click_button} and
|
9
|
+
# {Capybara::Node::Actions#click_link} for what locator will match against for each type of element
|
10
10
|
# @!macro waiting_behavior
|
11
11
|
# If the driver is capable of executing JavaScript, +$0+ will wait for a set amount of time
|
12
12
|
# and continuously retry finding the element until either the element is found or the time
|
@@ -16,7 +16,7 @@ module Capybara
|
|
16
16
|
#
|
17
17
|
# @overload click_link_or_button([locator], options)
|
18
18
|
#
|
19
|
-
# @param [String] locator
|
19
|
+
# @param [String] locator See {Capybara::Node::Actions#click_button} and {Capybara::Node::Actions#click_link}
|
20
20
|
#
|
21
21
|
# @return [Capybara::Node::Element] The element clicked
|
22
22
|
#
|
@@ -80,7 +80,7 @@ module Capybara
|
|
80
80
|
# @option options [String] :id Match fields that match the id attribute
|
81
81
|
# @option options [String] :name Match fields that match the name attribute
|
82
82
|
# @option options [String] :placeholder Match fields that match the placeholder attribute
|
83
|
-
# @option options [String, Array<String>] :class Match
|
83
|
+
# @option options [String, Array<String>] :class Match fields that match the class(es) provided
|
84
84
|
#
|
85
85
|
# @return [Capybara::Node::Element] The element filled_in
|
86
86
|
def fill_in(locator, options={})
|
@@ -108,7 +108,7 @@ module Capybara
|
|
108
108
|
# @option options [String] :option Value of the radio_button to choose
|
109
109
|
# @option options [String] :id Match fields that match the id attribute
|
110
110
|
# @option options [String] :name Match fields that match the name attribute
|
111
|
-
# @option options [String, Array<String>] :class Match
|
111
|
+
# @option options [String, Array<String>] :class Match fields that match the class(es) provided
|
112
112
|
# @macro waiting_behavior
|
113
113
|
# @macro label_click
|
114
114
|
#
|
@@ -131,7 +131,7 @@ module Capybara
|
|
131
131
|
# @option options [String] :option Value of the checkbox to select
|
132
132
|
# @option options [String] id Match fields that match the id attribute
|
133
133
|
# @option options [String] name Match fields that match the name attribute
|
134
|
-
# @option options [String, Array<String>] :class Match
|
134
|
+
# @option options [String, Array<String>] :class Match fields that match the class(es) provided
|
135
135
|
# @macro label_click
|
136
136
|
# @macro waiting_behavior
|
137
137
|
#
|
@@ -154,7 +154,7 @@ module Capybara
|
|
154
154
|
# @option options [String] :option Value of the checkbox to deselect
|
155
155
|
# @option options [String] id Match fields that match the id attribute
|
156
156
|
# @option options [String] name Match fields that match the name attribute
|
157
|
-
# @option options [String, Array<String>] :class Match
|
157
|
+
# @option options [String, Array<String>] :class Match fields that match the class(es) provided
|
158
158
|
# @macro label_click
|
159
159
|
# @macro waiting_behavior
|
160
160
|
#
|
@@ -229,7 +229,7 @@ module Capybara
|
|
229
229
|
# @option options [Boolean] multiple Match field which allows multiple file selection
|
230
230
|
# @option options [String] id Match fields that match the id attribute
|
231
231
|
# @option options [String] name Match fields that match the name attribute
|
232
|
-
# @option options [String, Array<String>] :class Match
|
232
|
+
# @option options [String, Array<String>] :class Match fields that match the class(es) provided
|
233
233
|
# @option options [true, Hash] make_visible A Hash of CSS styles to change before attempting to attach the file, if `true` { opacity: 1, display: 'block', visibility: 'visible' } is used (may not be supported by all drivers)
|
234
234
|
#
|
235
235
|
# @return [Capybara::Node::Element] The file field element
|
@@ -293,9 +293,9 @@ module Capybara
|
|
293
293
|
|
294
294
|
def _check_with_label(selector, checked, locator, options)
|
295
295
|
locator, options = nil, locator if locator.is_a? Hash
|
296
|
-
allow_label_click = options.delete(:allow_label_click) {
|
296
|
+
allow_label_click = options.delete(:allow_label_click) { session_options.automatic_label_click }
|
297
297
|
|
298
|
-
synchronize(Capybara::Queries::BaseQuery
|
298
|
+
synchronize(Capybara::Queries::BaseQuery.wait(options, session_options.default_max_wait_time)) do
|
299
299
|
begin
|
300
300
|
el = find(selector, locator, options)
|
301
301
|
el.set(checked)
|
data/lib/capybara/node/base.rb
CHANGED
@@ -74,7 +74,7 @@ module Capybara
|
|
74
74
|
# @return [Object] The result of the given block
|
75
75
|
# @raise [Capybara::FrozenInTime] If the return value of `Time.now` appears stuck
|
76
76
|
#
|
77
|
-
def synchronize(seconds=
|
77
|
+
def synchronize(seconds=session_options.default_max_wait_time, options = {})
|
78
78
|
start_time = Capybara::Helpers.monotonic_time
|
79
79
|
|
80
80
|
if session.synchronized
|
@@ -90,7 +90,7 @@ module Capybara
|
|
90
90
|
raise e if (Capybara::Helpers.monotonic_time - start_time) >= seconds
|
91
91
|
sleep(0.05)
|
92
92
|
raise Capybara::FrozenInTime, "time appears to be frozen, Capybara does not work with libraries which freeze time, consider using time travelling instead" if Capybara::Helpers.monotonic_time == start_time
|
93
|
-
reload if
|
93
|
+
reload if session_options.automatic_reload
|
94
94
|
retry
|
95
95
|
ensure
|
96
96
|
session.synchronized = false
|
@@ -114,6 +114,11 @@ module Capybara
|
|
114
114
|
query_scope
|
115
115
|
end
|
116
116
|
|
117
|
+
# @api private
|
118
|
+
def session_options
|
119
|
+
session.config
|
120
|
+
end
|
121
|
+
|
117
122
|
protected
|
118
123
|
|
119
124
|
def catch_error?(error, errors = nil)
|