capybara 3.3.1 → 3.4.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 +4 -4
- data/History.md +16 -0
- data/README.md +5 -7
- data/lib/capybara.rb +7 -6
- data/lib/capybara/config.rb +1 -1
- data/lib/capybara/dsl.rb +2 -2
- data/lib/capybara/helpers.rb +3 -3
- data/lib/capybara/minitest/spec.rb +3 -3
- data/lib/capybara/node/actions.rb +18 -18
- data/lib/capybara/node/base.rb +1 -1
- data/lib/capybara/node/element.rb +2 -2
- data/lib/capybara/node/finders.rb +6 -6
- data/lib/capybara/node/matchers.rb +5 -5
- data/lib/capybara/node/simple.rb +2 -2
- data/lib/capybara/queries/ancestor_query.rb +1 -1
- data/lib/capybara/queries/base_query.rb +12 -11
- data/lib/capybara/queries/current_path_query.rb +1 -1
- data/lib/capybara/queries/selector_query.rb +39 -15
- data/lib/capybara/queries/sibling_query.rb +1 -1
- data/lib/capybara/queries/text_query.rb +1 -1
- data/lib/capybara/rack_test/browser.rb +7 -7
- data/lib/capybara/rack_test/driver.rb +1 -1
- data/lib/capybara/rack_test/form.rb +7 -7
- data/lib/capybara/rack_test/node.rb +16 -16
- data/lib/capybara/rails.rb +1 -1
- data/lib/capybara/result.rb +8 -4
- data/lib/capybara/rspec/features.rb +4 -4
- data/lib/capybara/rspec/matchers.rb +6 -6
- data/lib/capybara/selector.rb +106 -90
- data/lib/capybara/selector/css.rb +4 -4
- data/lib/capybara/selector/filter_set.rb +52 -8
- data/lib/capybara/selector/selector.rb +39 -15
- data/lib/capybara/selenium/driver.rb +10 -10
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +8 -0
- data/lib/capybara/selenium/node.rb +9 -10
- data/lib/capybara/selenium/nodes/chrome_node.rb +18 -0
- data/lib/capybara/selenium/nodes/marionette_node.rb +32 -7
- data/lib/capybara/server.rb +3 -3
- data/lib/capybara/server/animation_disabler.rb +1 -1
- data/lib/capybara/server/middleware.rb +1 -1
- data/lib/capybara/session.rb +23 -19
- data/lib/capybara/session/config.rb +18 -3
- data/lib/capybara/spec/public/test.js +1 -1
- data/lib/capybara/spec/session/accept_alert_spec.rb +10 -10
- data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -3
- data/lib/capybara/spec/session/accept_prompt_spec.rb +9 -10
- data/lib/capybara/spec/session/all_spec.rb +33 -32
- data/lib/capybara/spec/session/ancestor_spec.rb +19 -19
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +38 -38
- data/lib/capybara/spec/session/assert_current_path_spec.rb +16 -16
- data/lib/capybara/spec/session/assert_selector_spec.rb +53 -53
- data/lib/capybara/spec/session/assert_style_spec.rb +3 -3
- data/lib/capybara/spec/session/assert_text_spec.rb +31 -30
- data/lib/capybara/spec/session/assert_title_spec.rb +12 -12
- data/lib/capybara/spec/session/attach_file_spec.rb +51 -52
- data/lib/capybara/spec/session/body_spec.rb +6 -6
- data/lib/capybara/spec/session/check_spec.rb +52 -47
- data/lib/capybara/spec/session/choose_spec.rb +32 -32
- data/lib/capybara/spec/session/click_button_spec.rb +103 -103
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +24 -23
- data/lib/capybara/spec/session/click_link_spec.rb +49 -48
- data/lib/capybara/spec/session/current_scope_spec.rb +7 -7
- data/lib/capybara/spec/session/current_url_spec.rb +26 -27
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +2 -2
- data/lib/capybara/spec/session/element/assert_match_selector_spec.rb +8 -8
- data/lib/capybara/spec/session/element/match_css_spec.rb +10 -10
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +6 -6
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +51 -51
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +7 -7
- data/lib/capybara/spec/session/evaluate_script_spec.rb +15 -8
- data/lib/capybara/spec/session/execute_script_spec.rb +7 -7
- data/lib/capybara/spec/session/fill_in_spec.rb +43 -42
- data/lib/capybara/spec/session/find_button_spec.rb +23 -23
- data/lib/capybara/spec/session/find_by_id_spec.rb +7 -7
- data/lib/capybara/spec/session/find_field_spec.rb +32 -30
- data/lib/capybara/spec/session/find_link_spec.rb +21 -21
- data/lib/capybara/spec/session/find_spec.rb +153 -135
- data/lib/capybara/spec/session/first_spec.rb +41 -41
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +5 -5
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +5 -5
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +17 -17
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +31 -17
- data/lib/capybara/spec/session/go_back_spec.rb +1 -1
- data/lib/capybara/spec/session/go_forward_spec.rb +1 -1
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +17 -17
- data/lib/capybara/spec/session/has_button_spec.rb +13 -13
- data/lib/capybara/spec/session/has_css_spec.rb +133 -131
- data/lib/capybara/spec/session/has_current_path_spec.rb +29 -29
- data/lib/capybara/spec/session/has_field_spec.rb +58 -58
- data/lib/capybara/spec/session/has_link_spec.rb +4 -4
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +24 -24
- data/lib/capybara/spec/session/has_select_spec.rb +43 -43
- data/lib/capybara/spec/session/has_selector_spec.rb +71 -71
- data/lib/capybara/spec/session/has_style_spec.rb +3 -3
- data/lib/capybara/spec/session/has_table_spec.rb +4 -4
- data/lib/capybara/spec/session/has_text_spec.rb +53 -52
- data/lib/capybara/spec/session/has_title_spec.rb +14 -14
- data/lib/capybara/spec/session/has_xpath_spec.rb +39 -38
- data/lib/capybara/spec/session/headers_spec.rb +1 -1
- data/lib/capybara/spec/session/html_spec.rb +6 -6
- data/lib/capybara/spec/session/node_spec.rb +129 -123
- data/lib/capybara/spec/session/node_wrapper_spec.rb +10 -7
- data/lib/capybara/spec/session/refresh_spec.rb +4 -7
- data/lib/capybara/spec/session/reset_session_spec.rb +28 -28
- data/lib/capybara/spec/session/response_code_spec.rb +1 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +2 -2
- data/lib/capybara/spec/session/save_page_spec.rb +37 -37
- data/lib/capybara/spec/session/save_screenshot_spec.rb +6 -6
- data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/select_spec.rb +81 -81
- data/lib/capybara/spec/session/selectors_spec.rb +17 -17
- data/lib/capybara/spec/session/sibling_spec.rb +9 -9
- data/lib/capybara/spec/session/text_spec.rb +23 -23
- data/lib/capybara/spec/session/title_spec.rb +5 -5
- data/lib/capybara/spec/session/uncheck_spec.rb +24 -20
- data/lib/capybara/spec/session/unselect_spec.rb +37 -37
- data/lib/capybara/spec/session/visit_spec.rb +48 -49
- data/lib/capybara/spec/session/window/current_window_spec.rb +1 -1
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +16 -16
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +2 -2
- data/lib/capybara/spec/session/window/window_spec.rb +4 -4
- data/lib/capybara/spec/session/window/within_window_spec.rb +14 -14
- data/lib/capybara/spec/session/within_spec.rb +41 -41
- data/lib/capybara/spec/spec_helper.rb +11 -9
- data/lib/capybara/spec/test_app.rb +18 -17
- data/lib/capybara/spec/views/form.erb +29 -31
- data/lib/capybara/spec/views/with_html.erb +2 -2
- data/lib/capybara/version.rb +1 -1
- data/spec/basic_node_spec.rb +23 -23
- data/spec/capybara_spec.rb +20 -20
- data/spec/css_splitter_spec.rb +7 -7
- data/spec/dsl_spec.rb +37 -32
- data/spec/filter_set_spec.rb +4 -4
- data/spec/fixtures/selenium_driver_rspec_failure.rb +1 -1
- data/spec/fixtures/selenium_driver_rspec_success.rb +1 -1
- data/spec/minitest_spec.rb +4 -4
- data/spec/minitest_spec_spec.rb +23 -23
- data/spec/per_session_config_spec.rb +5 -5
- data/spec/rack_test_spec.rb +44 -44
- data/spec/result_spec.rb +14 -14
- data/spec/rspec/features_spec.rb +13 -13
- data/spec/rspec/scenarios_spec.rb +4 -4
- data/spec/rspec/shared_spec_matchers.rb +282 -281
- data/spec/rspec/views_spec.rb +3 -3
- data/spec/rspec_matchers_spec.rb +10 -10
- data/spec/rspec_spec.rb +29 -29
- data/spec/selector_spec.rb +64 -64
- data/spec/selenium_spec_chrome.rb +14 -22
- data/spec/selenium_spec_chrome_remote.rb +28 -8
- data/spec/selenium_spec_edge.rb +9 -4
- data/spec/selenium_spec_firefox_remote.rb +87 -0
- data/spec/selenium_spec_ie.rb +9 -4
- data/spec/selenium_spec_marionette.rb +42 -18
- data/spec/server_spec.rb +29 -27
- data/spec/session_spec.rb +17 -17
- data/spec/shared_selenium_session.rb +70 -52
- data/spec/spec_helper.rb +1 -1
- metadata +4 -2
@@ -10,7 +10,7 @@ module Capybara
|
|
10
10
|
super(options)
|
11
11
|
@expected_path = expected_path
|
12
12
|
@options = {
|
13
|
-
url: !@expected_path.is_a?(Regexp) && !::Addressable::URI.parse(@expected_path ||
|
13
|
+
url: !@expected_path.is_a?(Regexp) && !::Addressable::URI.parse(@expected_path || '').hostname.nil?,
|
14
14
|
ignore_query: false
|
15
15
|
}.merge(options)
|
16
16
|
assert_valid_keys
|
@@ -8,7 +8,12 @@ module Capybara
|
|
8
8
|
VALID_KEYS = COUNT_KEYS + %i[text id class visible exact exact_text match wait filter_set]
|
9
9
|
VALID_MATCH = %i[first smart prefer_exact one].freeze
|
10
10
|
|
11
|
-
def initialize(*args,
|
11
|
+
def initialize(*args,
|
12
|
+
session_options:,
|
13
|
+
enable_aria_label: session_options.enable_aria_label,
|
14
|
+
test_id: session_options.test_id,
|
15
|
+
**options,
|
16
|
+
&filter_block)
|
12
17
|
@resolved_node = nil
|
13
18
|
@options = options.dup
|
14
19
|
super(@options)
|
@@ -20,7 +25,7 @@ module Capybara
|
|
20
25
|
|
21
26
|
raise ArgumentError, "Unused parameters passed to #{self.class.name} : #{args}" unless args.empty?
|
22
27
|
|
23
|
-
@expression = @selector.call(@locator, @options.merge(enable_aria_label:
|
28
|
+
@expression = @selector.call(@locator, @options.merge(selector_config: { enable_aria_label: enable_aria_label, test_id: test_id }))
|
24
29
|
|
25
30
|
warn_exact_usage
|
26
31
|
|
@@ -30,22 +35,31 @@ module Capybara
|
|
30
35
|
def name; selector.name; end
|
31
36
|
def label; selector.label || selector.name; end
|
32
37
|
|
33
|
-
def description
|
34
|
-
@description = +
|
35
|
-
|
36
|
-
|
38
|
+
def description(applied = false)
|
39
|
+
@description = +''
|
40
|
+
if !applied || @applied_filters
|
41
|
+
@description << 'visible ' if visible == :visible
|
42
|
+
@description << 'non-visible ' if visible == :hidden
|
43
|
+
end
|
37
44
|
@description << "#{label} #{locator.inspect}"
|
38
|
-
|
39
|
-
|
45
|
+
if !applied || @applied_filters
|
46
|
+
@description << " with#{' exact' if exact_text == true} text #{options[:text].inspect}" if options[:text]
|
47
|
+
@description << " with exact text #{exact_text}" if exact_text.is_a?(String)
|
48
|
+
end
|
40
49
|
@description << " with id #{options[:id]}" if options[:id]
|
41
50
|
@description << " with classes [#{Array(options[:class]).join(',')}]" if options[:class]
|
42
|
-
@description << selector.description(options)
|
43
|
-
@description <<
|
51
|
+
@description << selector.description(node_filters: !applied || (@applied_filters == :node), **options)
|
52
|
+
@description << ' that also matches the custom filter block' if @filter_block && (!applied || (@applied_filters == :node))
|
44
53
|
@description << " within #{@resolved_node.inspect}" if describe_within?
|
45
54
|
@description
|
46
55
|
end
|
47
56
|
|
57
|
+
def applied_description
|
58
|
+
description(true)
|
59
|
+
end
|
60
|
+
|
48
61
|
def matches_filters?(node)
|
62
|
+
@applied_filters ||= :system
|
49
63
|
return false if options[:text] && !matches_text_filter(node, options[:text])
|
50
64
|
return false if exact_text.is_a?(String) && !matches_exact_text_filter(node, exact_text)
|
51
65
|
|
@@ -54,6 +68,7 @@ module Capybara
|
|
54
68
|
when :hidden then return false if node.visible?
|
55
69
|
end
|
56
70
|
|
71
|
+
@applied_filters = :node
|
57
72
|
matches_node_filters?(node) && matches_filter_block?(node)
|
58
73
|
rescue *(node.respond_to?(:session) ? node.session.driver.invalid_element_errors : [])
|
59
74
|
false
|
@@ -88,6 +103,7 @@ module Capybara
|
|
88
103
|
|
89
104
|
# @api private
|
90
105
|
def resolve_for(node, exact = nil)
|
106
|
+
@applied_filters = false
|
91
107
|
@resolved_node = node
|
92
108
|
node.synchronize do
|
93
109
|
children = if selector.format == :css
|
@@ -110,6 +126,14 @@ module Capybara
|
|
110
126
|
@expression.respond_to? :to_xpath
|
111
127
|
end
|
112
128
|
|
129
|
+
def failure_message
|
130
|
+
+"expected to find #{applied_description}" << count_message
|
131
|
+
end
|
132
|
+
|
133
|
+
def negative_failure_message
|
134
|
+
+"expected not to find #{applied_description}" << count_message
|
135
|
+
end
|
136
|
+
|
113
137
|
private
|
114
138
|
|
115
139
|
def find_selector(locator)
|
@@ -184,8 +208,8 @@ module Capybara
|
|
184
208
|
end
|
185
209
|
|
186
210
|
return if unhandled_options.empty?
|
187
|
-
invalid_names = unhandled_options.map(&:inspect).join(
|
188
|
-
valid_names = valid_keys.map(&:inspect).join(
|
211
|
+
invalid_names = unhandled_options.map(&:inspect).join(', ')
|
212
|
+
valid_names = valid_keys.map(&:inspect).join(', ')
|
189
213
|
raise ArgumentError, "invalid keys #{invalid_names}, should be one of #{valid_names}"
|
190
214
|
end
|
191
215
|
|
@@ -219,10 +243,10 @@ module Capybara
|
|
219
243
|
process_class = options.key?(:class) && !custom_keys.include?(:class)
|
220
244
|
|
221
245
|
if process_id && options[:id].is_a?(XPath::Expression)
|
222
|
-
raise ArgumentError,
|
246
|
+
raise ArgumentError, 'XPath expressions are not supported for the :id filter with CSS based selectors'
|
223
247
|
end
|
224
248
|
if process_class && options[:class].is_a?(XPath::Expression)
|
225
|
-
raise ArgumentError,
|
249
|
+
raise ArgumentError, 'XPath expressions are not supported for the :class filter with CSS based selectors'
|
226
250
|
end
|
227
251
|
|
228
252
|
if process_id || process_class
|
@@ -230,7 +254,7 @@ module Capybara
|
|
230
254
|
sel += "##{::Capybara::Selector::CSS.escape(options[:id])}" if process_id
|
231
255
|
sel += css_from_classes(Array(options[:class])) if process_class
|
232
256
|
sel
|
233
|
-
end.join(
|
257
|
+
end.join(', ')
|
234
258
|
end
|
235
259
|
|
236
260
|
expr
|
@@ -46,9 +46,9 @@ class Capybara::RackTest::Browser
|
|
46
46
|
driver.redirect_limit.times do
|
47
47
|
if last_response.redirect?
|
48
48
|
if [307, 308].include? last_response.status
|
49
|
-
process(last_request.request_method, last_response[
|
49
|
+
process(last_request.request_method, last_response['Location'], last_request.params, env)
|
50
50
|
else
|
51
|
-
process(:get, last_response[
|
51
|
+
process(:get, last_response['Location'], {}, env)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
@@ -61,8 +61,8 @@ class Capybara::RackTest::Browser
|
|
61
61
|
if path.empty?
|
62
62
|
new_uri.path = request_path
|
63
63
|
else
|
64
|
-
new_uri.path = request_path if path.start_with?(
|
65
|
-
new_uri.path =
|
64
|
+
new_uri.path = request_path if path.start_with?('?')
|
65
|
+
new_uri.path = '/' if new_uri.path.empty?
|
66
66
|
new_uri.path = request_path.sub(%r{/[^/]*$}, '/') + new_uri.path unless new_uri.path.start_with?('/')
|
67
67
|
end
|
68
68
|
new_uri.scheme ||= @current_scheme
|
@@ -78,7 +78,7 @@ class Capybara::RackTest::Browser
|
|
78
78
|
def current_url
|
79
79
|
last_request.url
|
80
80
|
rescue Rack::Test::Error
|
81
|
-
|
81
|
+
''
|
82
82
|
end
|
83
83
|
|
84
84
|
def reset_host!
|
@@ -105,7 +105,7 @@ class Capybara::RackTest::Browser
|
|
105
105
|
def html
|
106
106
|
last_response.body
|
107
107
|
rescue Rack::Test::Error
|
108
|
-
|
108
|
+
''
|
109
109
|
end
|
110
110
|
|
111
111
|
def title
|
@@ -122,7 +122,7 @@ protected
|
|
122
122
|
def request_path
|
123
123
|
last_request.path
|
124
124
|
rescue Rack::Test::Error
|
125
|
-
|
125
|
+
'/'
|
126
126
|
end
|
127
127
|
|
128
128
|
private
|
@@ -15,7 +15,7 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
|
|
15
15
|
attr_reader :app, :options
|
16
16
|
|
17
17
|
def initialize(app, **options)
|
18
|
-
raise ArgumentError,
|
18
|
+
raise ArgumentError, 'rack-test requires a rack application, but none was given' unless app
|
19
19
|
@session = nil
|
20
20
|
@app = app
|
21
21
|
@options = DEFAULT_OPTIONS.merge(options)
|
@@ -7,15 +7,15 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node
|
|
7
7
|
# which should probably be provided to Rack::Test in its non-GET request methods.
|
8
8
|
class NilUploadedFile < Rack::Test::UploadedFile
|
9
9
|
def initialize
|
10
|
-
@empty_file = Tempfile.new(
|
10
|
+
@empty_file = Tempfile.new('nil_uploaded_file')
|
11
11
|
@empty_file.close
|
12
12
|
end
|
13
13
|
|
14
|
-
def original_filename;
|
15
|
-
def content_type;
|
14
|
+
def original_filename; ''; end
|
15
|
+
def content_type; 'application/octet-stream'; end
|
16
16
|
def path; @empty_file.path; end
|
17
17
|
def size; 0; end
|
18
|
-
def read;
|
18
|
+
def read; ''; end
|
19
19
|
end
|
20
20
|
|
21
21
|
def params(button)
|
@@ -35,7 +35,7 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node
|
|
35
35
|
when 'textarea' then add_textarea_param(field, params)
|
36
36
|
end
|
37
37
|
end
|
38
|
-
merge_param!(params, button[:name], button[:value] ||
|
38
|
+
merge_param!(params, button[:name], button[:value] || '') if button[:name]
|
39
39
|
|
40
40
|
params.to_params_hash
|
41
41
|
end
|
@@ -47,7 +47,7 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def multipart?
|
50
|
-
self[:enctype] ==
|
50
|
+
self[:enctype] == 'multipart/form-data'
|
51
51
|
end
|
52
52
|
|
53
53
|
private
|
@@ -107,7 +107,7 @@ private
|
|
107
107
|
|
108
108
|
def add_select_param(field, params)
|
109
109
|
if field.has_attribute?('multiple')
|
110
|
-
field.xpath(
|
110
|
+
field.xpath('.//option[@selected]').each do |option|
|
111
111
|
merge_param!(params, field['name'], (option['value'] || option.text).to_s)
|
112
112
|
end
|
113
113
|
else
|
@@ -7,16 +7,16 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
7
7
|
native.text
|
8
8
|
.gsub(/[\u200b\u200e\u200f]/, '')
|
9
9
|
.gsub(/[\ \n\f\t\v\u2028\u2029]+/, ' ')
|
10
|
-
.gsub(/\A[[:space:]&&[^\u00a0]]+/,
|
11
|
-
.gsub(/[[:space:]&&[^\u00a0]]+\z/,
|
10
|
+
.gsub(/\A[[:space:]&&[^\u00a0]]+/, '')
|
11
|
+
.gsub(/[[:space:]&&[^\u00a0]]+\z/, '')
|
12
12
|
.tr("\u00a0", ' ')
|
13
13
|
end
|
14
14
|
|
15
15
|
def visible_text
|
16
16
|
displayed_text.gsub(/\ +/, ' ')
|
17
17
|
.gsub(/[\ \n]*\n[\ \n]*/, "\n")
|
18
|
-
.gsub(/\A[[:space:]&&[^\u00a0]]+/,
|
19
|
-
.gsub(/[[:space:]&&[^\u00a0]]+\z/,
|
18
|
+
.gsub(/\A[[:space:]&&[^\u00a0]]+/, '')
|
19
|
+
.gsub(/[[:space:]&&[^\u00a0]]+\z/, '')
|
20
20
|
.tr("\u00a0", ' ')
|
21
21
|
end
|
22
22
|
|
@@ -25,7 +25,7 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def style(_styles)
|
28
|
-
raise NotImplementedError,
|
28
|
+
raise NotImplementedError, 'The rack_test driver does not process CSS'
|
29
29
|
end
|
30
30
|
|
31
31
|
def value
|
@@ -51,16 +51,16 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
51
51
|
def select_option
|
52
52
|
return if disabled?
|
53
53
|
deselect_options unless select_node.multiple?
|
54
|
-
native[
|
54
|
+
native['selected'] = 'selected'
|
55
55
|
end
|
56
56
|
|
57
57
|
def unselect_option
|
58
|
-
raise Capybara::UnselectNotAllowed,
|
58
|
+
raise Capybara::UnselectNotAllowed, 'Cannot unselect option from single select box.' unless select_node.multiple?
|
59
59
|
native.remove_attribute('selected')
|
60
60
|
end
|
61
61
|
|
62
62
|
def click(keys = [], **offset)
|
63
|
-
raise ArgumentError,
|
63
|
+
raise ArgumentError, 'The RackTest driver does not support click options' unless keys.empty? && offset.empty?
|
64
64
|
|
65
65
|
if link?
|
66
66
|
follow_link
|
@@ -94,9 +94,9 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
94
94
|
return true if string_node.disabled?
|
95
95
|
|
96
96
|
if %w[option optgroup].include? tag_name
|
97
|
-
find_xpath(
|
97
|
+
find_xpath('parent::*[self::optgroup or self::select or self::datalist]')[0].disabled?
|
98
98
|
else
|
99
|
-
!find_xpath(
|
99
|
+
!find_xpath('parent::fieldset[@disabled] | ancestor::*[not(self::legend) or preceding-sibling::legend][parent::fieldset[@disabled]]').empty?
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
@@ -140,7 +140,7 @@ protected
|
|
140
140
|
private
|
141
141
|
|
142
142
|
def deselect_options
|
143
|
-
select_node.find_xpath(
|
143
|
+
select_node.find_xpath('.//option[@selected]').each { |node| node.native.remove_attribute('selected') }
|
144
144
|
end
|
145
145
|
|
146
146
|
def string_node
|
@@ -166,7 +166,7 @@ private
|
|
166
166
|
|
167
167
|
def set_radio(_value) # rubocop:disable Naming/AccessorMethodName
|
168
168
|
other_radios_xpath = XPath.generate { |x| x.anywhere(:input)[x.attr(:name) == self[:name]] }.to_s
|
169
|
-
driver.dom.xpath(other_radios_xpath).each { |node| node.remove_attribute(
|
169
|
+
driver.dom.xpath(other_radios_xpath).each { |node| node.remove_attribute('checked') }
|
170
170
|
native['checked'] = 'checked'
|
171
171
|
end
|
172
172
|
|
@@ -202,7 +202,7 @@ private
|
|
202
202
|
end
|
203
203
|
|
204
204
|
def follow_link
|
205
|
-
method = self[
|
205
|
+
method = self['data-method'] if driver.options[:respect_data_method]
|
206
206
|
method ||= :get
|
207
207
|
driver.follow(method, self[:href].to_s)
|
208
208
|
end
|
@@ -211,7 +211,7 @@ private
|
|
211
211
|
labelled_control = if native[:for]
|
212
212
|
find_xpath("//input[@id='#{native[:for]}']")
|
213
213
|
else
|
214
|
-
find_xpath(
|
214
|
+
find_xpath('.//input')
|
215
215
|
end.first
|
216
216
|
|
217
217
|
labelled_control.set(!labelled_control.checked?) if checkbox_or_radio?(labelled_control)
|
@@ -222,7 +222,7 @@ private
|
|
222
222
|
end
|
223
223
|
|
224
224
|
def submits?
|
225
|
-
(tag_name == 'input' && %w[submit image].include?(type)) || (tag_name == 'button' && [nil,
|
225
|
+
(tag_name == 'input' && %w[submit image].include?(type)) || (tag_name == 'button' && [nil, 'submit'].include?(type))
|
226
226
|
end
|
227
227
|
|
228
228
|
def checkable?
|
@@ -252,6 +252,6 @@ protected
|
|
252
252
|
end
|
253
253
|
|
254
254
|
def textarea?
|
255
|
-
tag_name ==
|
255
|
+
tag_name == 'textarea'
|
256
256
|
end
|
257
257
|
end
|
data/lib/capybara/rails.rb
CHANGED
data/lib/capybara/result.rb
CHANGED
@@ -123,13 +123,13 @@ module Capybara
|
|
123
123
|
def failure_message
|
124
124
|
message = @query.failure_message
|
125
125
|
if count.zero?
|
126
|
-
message <<
|
126
|
+
message << ' but there were no matches'
|
127
127
|
else
|
128
|
-
message << ", found #{count} #{Capybara::Helpers.declension('match', 'matches', count)}: " << full_results.map(&:text).map(&:inspect).join(
|
128
|
+
message << ", found #{count} #{Capybara::Helpers.declension('match', 'matches', count)}: " << full_results.map(&:text).map(&:inspect).join(', ')
|
129
129
|
end
|
130
130
|
unless rest.empty?
|
131
|
-
elements = rest.map { |el| el.text rescue
|
132
|
-
message <<
|
131
|
+
elements = rest.map { |el| el.text rescue '<<ERROR>>' }.map(&:inspect).join(', ') # rubocop:disable Style/RescueModifier
|
132
|
+
message << '. Also found ' << elements << ', which matched the selector but not all filters.'
|
133
133
|
end
|
134
134
|
message
|
135
135
|
end
|
@@ -138,6 +138,10 @@ module Capybara
|
|
138
138
|
failure_message.sub(/(to find)/, 'not \1')
|
139
139
|
end
|
140
140
|
|
141
|
+
def unfiltered_size
|
142
|
+
@elements.length
|
143
|
+
end
|
144
|
+
|
141
145
|
private
|
142
146
|
|
143
147
|
def full_results
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
RSpec.shared_context
|
3
|
+
RSpec.shared_context 'Capybara Features', capybara_feature: true do
|
4
4
|
instance_eval do
|
5
5
|
alias background before
|
6
6
|
alias given let
|
@@ -10,14 +10,14 @@ end
|
|
10
10
|
|
11
11
|
# ensure shared_context is included if default shared_context_metadata_behavior is changed
|
12
12
|
RSpec.configure do |config|
|
13
|
-
config.include_context
|
13
|
+
config.include_context 'Capybara Features', capybara_feature: true if config.respond_to?(:include_context)
|
14
14
|
end
|
15
15
|
|
16
16
|
RSpec.configure do |config|
|
17
17
|
config.alias_example_group_to :feature, capybara_feature: true, type: :feature
|
18
|
-
config.alias_example_group_to :xfeature, capybara_feature: true, type: :feature, skip:
|
18
|
+
config.alias_example_group_to :xfeature, capybara_feature: true, type: :feature, skip: 'Temporarily disabled with xfeature'
|
19
19
|
config.alias_example_group_to :ffeature, capybara_feature: true, type: :feature, focus: true
|
20
20
|
config.alias_example_to :scenario
|
21
|
-
config.alias_example_to :xscenario, skip:
|
21
|
+
config.alias_example_to :xscenario, skip: 'Temporarily disabled with xscenario'
|
22
22
|
config.alias_example_to :fscenario, focus: true
|
23
23
|
end
|
@@ -89,11 +89,11 @@ module Capybara
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def does_not_match?(_actual)
|
92
|
-
raise ArgumentError,
|
92
|
+
raise ArgumentError, 'The have_all_selectors matcher does not support use with not_to/should_not'
|
93
93
|
end
|
94
94
|
|
95
95
|
def description
|
96
|
-
|
96
|
+
'have all selectors'
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
@@ -108,11 +108,11 @@ module Capybara
|
|
108
108
|
end
|
109
109
|
|
110
110
|
def does_not_match?(_actual)
|
111
|
-
raise ArgumentError,
|
111
|
+
raise ArgumentError, 'The have_none_of_selectors matcher does not support use with not_to/should_not'
|
112
112
|
end
|
113
113
|
|
114
114
|
def description
|
115
|
-
|
115
|
+
'have no selectors'
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
@@ -235,11 +235,11 @@ module Capybara
|
|
235
235
|
end
|
236
236
|
|
237
237
|
def does_not_match?(_actual)
|
238
|
-
raise ArgumentError,
|
238
|
+
raise ArgumentError, 'The have_style matcher does not support use with not_to/should_not'
|
239
239
|
end
|
240
240
|
|
241
241
|
def description
|
242
|
-
|
242
|
+
'have style'
|
243
243
|
end
|
244
244
|
end
|
245
245
|
|