capybara 3.33.0 → 3.35.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +83 -15
- data/README.md +0 -2
- data/lib/capybara.rb +1 -1
- data/lib/capybara/config.rb +4 -6
- data/lib/capybara/driver/base.rb +4 -0
- data/lib/capybara/helpers.rb +25 -1
- data/lib/capybara/minitest.rb +2 -2
- data/lib/capybara/minitest/spec.rb +14 -11
- data/lib/capybara/node/actions.rb +1 -2
- data/lib/capybara/node/base.rb +6 -6
- data/lib/capybara/node/element.rb +1 -5
- data/lib/capybara/node/finders.rb +7 -6
- data/lib/capybara/node/matchers.rb +8 -6
- data/lib/capybara/node/simple.rb +5 -1
- data/lib/capybara/queries/ancestor_query.rb +1 -1
- data/lib/capybara/queries/current_path_query.rb +14 -4
- data/lib/capybara/queries/selector_query.rb +32 -17
- data/lib/capybara/queries/sibling_query.rb +1 -1
- data/lib/capybara/queries/text_query.rb +2 -2
- data/lib/capybara/rack_test/browser.rb +7 -3
- data/lib/capybara/rack_test/driver.rb +1 -0
- data/lib/capybara/rack_test/form.rb +1 -1
- data/lib/capybara/rack_test/node.rb +1 -1
- data/lib/capybara/registration_container.rb +3 -3
- data/lib/capybara/registrations/drivers.rb +18 -12
- data/lib/capybara/registrations/patches/puma_ssl.rb +3 -1
- data/lib/capybara/registrations/servers.rb +2 -1
- data/lib/capybara/result.rb +6 -10
- data/lib/capybara/rspec.rb +2 -0
- data/lib/capybara/rspec/matcher_proxies.rb +1 -1
- data/lib/capybara/rspec/matchers.rb +7 -6
- data/lib/capybara/rspec/matchers/have_current_path.rb +2 -2
- data/lib/capybara/rspec/matchers/match_style.rb +5 -0
- data/lib/capybara/selector.rb +2 -2
- data/lib/capybara/selector/builders/css_builder.rb +1 -1
- data/lib/capybara/selector/builders/xpath_builder.rb +3 -1
- data/lib/capybara/selector/definition.rb +6 -5
- data/lib/capybara/selector/definition/button.rb +26 -15
- data/lib/capybara/selector/definition/css.rb +1 -1
- data/lib/capybara/selector/definition/datalist_input.rb +1 -1
- data/lib/capybara/selector/definition/element.rb +2 -1
- data/lib/capybara/selector/definition/label.rb +1 -1
- data/lib/capybara/selector/definition/select.rb +1 -1
- data/lib/capybara/selector/definition/table_row.rb +2 -2
- data/lib/capybara/selector/filter_set.rb +2 -2
- data/lib/capybara/selector/selector.rb +5 -1
- data/lib/capybara/selenium/atoms/src/isDisplayed.js +1 -1
- data/lib/capybara/selenium/driver.rb +47 -5
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +3 -3
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +3 -3
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +1 -1
- data/lib/capybara/selenium/extensions/find.rb +4 -4
- data/lib/capybara/selenium/extensions/scroll.rb +8 -10
- data/lib/capybara/selenium/logger_suppressor.rb +8 -2
- data/lib/capybara/selenium/node.rb +6 -3
- data/lib/capybara/selenium/nodes/chrome_node.rb +23 -5
- data/lib/capybara/selenium/nodes/firefox_node.rb +6 -1
- data/lib/capybara/selenium/nodes/safari_node.rb +1 -1
- data/lib/capybara/selenium/patches/atoms.rb +4 -4
- data/lib/capybara/selenium/patches/logs.rb +4 -4
- data/lib/capybara/server/animation_disabler.rb +8 -3
- data/lib/capybara/server/middleware.rb +4 -2
- data/lib/capybara/session.rb +20 -11
- data/lib/capybara/session/matchers.rb +11 -11
- data/lib/capybara/spec/public/test.js +6 -1
- data/lib/capybara/spec/session/accept_alert_spec.rb +1 -1
- data/lib/capybara/spec/session/check_spec.rb +6 -0
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +9 -0
- data/lib/capybara/spec/session/current_url_spec.rb +11 -1
- data/lib/capybara/spec/session/has_button_spec.rb +35 -0
- data/lib/capybara/spec/session/has_css_spec.rb +2 -1
- data/lib/capybara/spec/session/has_current_path_spec.rb +13 -0
- data/lib/capybara/spec/session/has_text_spec.rb +0 -11
- data/lib/capybara/spec/session/html_spec.rb +1 -1
- data/lib/capybara/spec/session/matches_style_spec.rb +2 -2
- data/lib/capybara/spec/session/node_spec.rb +23 -3
- data/lib/capybara/spec/session/refresh_spec.rb +2 -1
- data/lib/capybara/spec/session/save_page_spec.rb +4 -4
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +1 -1
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +1 -1
- data/lib/capybara/spec/session/window/window_spec.rb +1 -1
- data/lib/capybara/spec/session/window/windows_spec.rb +1 -1
- data/lib/capybara/spec/spec_helper.rb +11 -12
- data/lib/capybara/spec/test_app.rb +9 -3
- data/lib/capybara/spec/views/form.erb +23 -1
- data/lib/capybara/spec/views/with_animation.erb +8 -0
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +2 -0
- data/lib/capybara/spec/views/with_sortable_js.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +3 -7
- data/spec/basic_node_spec.rb +9 -8
- data/spec/dsl_spec.rb +1 -1
- data/spec/fixtures/selenium_driver_rspec_success.rb +1 -1
- data/spec/minitest_spec.rb +2 -1
- data/spec/rack_test_spec.rb +15 -5
- data/spec/rspec/features_spec.rb +3 -1
- data/spec/rspec/scenarios_spec.rb +4 -0
- data/spec/rspec/shared_spec_matchers.rb +2 -2
- data/spec/rspec_spec.rb +4 -0
- data/spec/selector_spec.rb +16 -1
- data/spec/selenium_spec_chrome.rb +39 -18
- data/spec/selenium_spec_chrome_remote.rb +5 -1
- data/spec/selenium_spec_firefox.rb +15 -13
- data/spec/server_spec.rb +19 -0
- data/spec/shared_selenium_session.rb +74 -1
- metadata +47 -13
- data/lib/capybara/spec/session/source_spec.rb +0 -0
data/lib/capybara/node/simple.rb
CHANGED
@@ -100,7 +100,7 @@ module Capybara
|
|
100
100
|
# @param [Boolean] check_ancestors Whether to inherit visibility from ancestors
|
101
101
|
# @return [Boolean] Whether the element is visible
|
102
102
|
#
|
103
|
-
def visible?(check_ancestors = true)
|
103
|
+
def visible?(check_ancestors = true) # rubocop:disable Style/OptionalBooleanParameter
|
104
104
|
return false if (tag_name == 'input') && (native[:type] == 'hidden')
|
105
105
|
return false if tag_name == 'template'
|
106
106
|
|
@@ -148,6 +148,10 @@ module Capybara
|
|
148
148
|
native.has_attribute?('multiple')
|
149
149
|
end
|
150
150
|
|
151
|
+
def readonly?
|
152
|
+
native.has_attribute?('readonly')
|
153
|
+
end
|
154
|
+
|
151
155
|
def synchronize(_seconds = nil)
|
152
156
|
yield # simple nodes don't need to wait
|
153
157
|
end
|
@@ -16,7 +16,7 @@ module Capybara
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def description(applied = false)
|
19
|
+
def description(applied = false) # rubocop:disable Style/OptionalBooleanParameter
|
20
20
|
child_query = @child_node&.instance_variable_get(:@query)
|
21
21
|
desc = super
|
22
22
|
desc += " that is an ancestor of #{child_query.description}" if child_query
|
@@ -6,26 +6,30 @@ module Capybara
|
|
6
6
|
# @api private
|
7
7
|
module Queries
|
8
8
|
class CurrentPathQuery < BaseQuery
|
9
|
-
def initialize(expected_path, **options)
|
9
|
+
def initialize(expected_path, **options, &optional_filter_block)
|
10
10
|
super(options)
|
11
11
|
@expected_path = expected_path
|
12
12
|
@options = {
|
13
13
|
url: !@expected_path.is_a?(Regexp) && !::Addressable::URI.parse(@expected_path || '').hostname.nil?,
|
14
14
|
ignore_query: false
|
15
15
|
}.merge(options)
|
16
|
+
@filter_block = optional_filter_block
|
16
17
|
assert_valid_keys
|
17
18
|
end
|
18
19
|
|
19
20
|
def resolves_for?(session)
|
20
21
|
uri = ::Addressable::URI.parse(session.current_url)
|
21
|
-
|
22
|
-
|
22
|
+
@actual_path = (options[:ignore_query] ? uri&.omit(:query) : uri).yield_self do |u|
|
23
|
+
options[:url] ? u&.to_s : u&.request_uri
|
24
|
+
end
|
23
25
|
|
24
|
-
if @expected_path.is_a? Regexp
|
26
|
+
res = if @expected_path.is_a? Regexp
|
25
27
|
@actual_path.to_s.match?(@expected_path)
|
26
28
|
else
|
27
29
|
::Addressable::URI.parse(@expected_path) == ::Addressable::URI.parse(@actual_path)
|
28
30
|
end
|
31
|
+
|
32
|
+
res && matches_filter_block?(uri)
|
29
33
|
end
|
30
34
|
|
31
35
|
def failure_message
|
@@ -38,6 +42,12 @@ module Capybara
|
|
38
42
|
|
39
43
|
private
|
40
44
|
|
45
|
+
def matches_filter_block?(url)
|
46
|
+
return true unless @filter_block
|
47
|
+
|
48
|
+
@filter_block.call(url)
|
49
|
+
end
|
50
|
+
|
41
51
|
def failure_message_helper(negated = '')
|
42
52
|
verb = @expected_path.is_a?(Regexp) ? 'match' : 'equal'
|
43
53
|
"expected #{@actual_path.inspect}#{negated} to #{verb} #{@expected_path.inspect}"
|
@@ -55,7 +55,7 @@ module Capybara
|
|
55
55
|
def name; selector.name; end
|
56
56
|
def label; selector.label || selector.name; end
|
57
57
|
|
58
|
-
def description(only_applied = false)
|
58
|
+
def description(only_applied = false) # rubocop:disable Style/OptionalBooleanParameter
|
59
59
|
desc = +''
|
60
60
|
show_for = show_for_stage(only_applied)
|
61
61
|
|
@@ -95,11 +95,9 @@ module Capybara
|
|
95
95
|
desc << ' that also matches the custom filter block' if @filter_block && show_for[:node]
|
96
96
|
|
97
97
|
desc << " within #{@resolved_node.inspect}" if describe_within?
|
98
|
-
if locator.is_a?(String) && locator.start_with?('#', './/', '//')
|
99
|
-
|
100
|
-
|
101
|
-
"Please see the documentation for acceptable locator values.\n\n"
|
102
|
-
end
|
98
|
+
if locator.is_a?(String) && locator.start_with?('#', './/', '//') && !selector.raw_locator?
|
99
|
+
desc << "\nNote: It appears you may be passing a CSS selector or XPath expression rather than a locator. " \
|
100
|
+
"Please see the documentation for acceptable locator values.\n\n"
|
103
101
|
end
|
104
102
|
desc
|
105
103
|
end
|
@@ -239,17 +237,18 @@ module Capybara
|
|
239
237
|
hints[:styles] = options[:style] if use_default_style_filter?
|
240
238
|
hints[:position] = true if use_spatial_filter?
|
241
239
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
else
|
240
|
+
case selector_format
|
241
|
+
when :css
|
242
|
+
if node.method(:find_css).arity == 1
|
246
243
|
node.find_css(css)
|
247
|
-
end
|
248
|
-
elsif selector_format == :xpath
|
249
|
-
if node.method(:find_xpath).arity != 1
|
250
|
-
node.find_xpath(xpath(exact), **hints)
|
251
244
|
else
|
245
|
+
node.find_css(css, **hints)
|
246
|
+
end
|
247
|
+
when :xpath
|
248
|
+
if node.method(:find_xpath).arity == 1
|
252
249
|
node.find_xpath(xpath(exact))
|
250
|
+
else
|
251
|
+
node.find_xpath(xpath(exact), **hints)
|
253
252
|
end
|
254
253
|
else
|
255
254
|
raise ArgumentError, "Unknown format: #{selector_format}"
|
@@ -483,9 +482,25 @@ module Capybara
|
|
483
482
|
end
|
484
483
|
|
485
484
|
def matches_class_filter?(node)
|
486
|
-
return true unless use_default_class_filter? &&
|
485
|
+
return true unless use_default_class_filter? && need_to_process_classes?
|
486
|
+
|
487
|
+
if options[:class].is_a? Regexp
|
488
|
+
options[:class].match? node[:class]
|
489
|
+
else
|
490
|
+
classes = (node[:class] || '').split
|
491
|
+
options[:class].select { |c| c.is_a? Regexp }.all? do |r|
|
492
|
+
classes.any? { |cls| r.match? cls }
|
493
|
+
end
|
494
|
+
end
|
495
|
+
end
|
487
496
|
|
488
|
-
|
497
|
+
def need_to_process_classes?
|
498
|
+
case options[:class]
|
499
|
+
when Regexp then true
|
500
|
+
when Array then options[:class].any?(Regexp)
|
501
|
+
else
|
502
|
+
false
|
503
|
+
end
|
489
504
|
end
|
490
505
|
|
491
506
|
def matches_style_filter?(node)
|
@@ -652,7 +667,7 @@ module Capybara
|
|
652
667
|
|
653
668
|
d = u.dot w
|
654
669
|
e = v.dot w
|
655
|
-
cap_d = (a * c) - (b
|
670
|
+
cap_d = (a * c) - (b**2)
|
656
671
|
sD = tD = cap_d
|
657
672
|
|
658
673
|
# compute the line parameters of the two closest points
|
@@ -15,7 +15,7 @@ module Capybara
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def description(applied = false)
|
18
|
+
def description(applied = false) # rubocop:disable Style/OptionalBooleanParameter
|
19
19
|
desc = super
|
20
20
|
sibling_query = @sibling_node&.instance_variable_get(:@query)
|
21
21
|
desc += " that is a sibling of #{sibling_query.description}" if sibling_query
|
@@ -6,7 +6,7 @@ module Capybara
|
|
6
6
|
class TextQuery < BaseQuery
|
7
7
|
def initialize(type = nil, expected_text, session_options:, **options) # rubocop:disable Style/OptionalArguments
|
8
8
|
@type = type.nil? ? default_type : type
|
9
|
-
raise ArgumentError,
|
9
|
+
raise ArgumentError, "#{@type} is not a valid type for a text query" unless valid_types.include?(@type)
|
10
10
|
|
11
11
|
@options = options
|
12
12
|
super(@options)
|
@@ -14,7 +14,7 @@ module Capybara
|
|
14
14
|
|
15
15
|
if expected_text.nil? && !exact?
|
16
16
|
warn 'Checking for expected text of nil is confusing and/or pointless since it will always match. '\
|
17
|
-
|
17
|
+
"Please specify a string or regexp instead. #{Capybara::Helpers.filter_backtrace(caller)}"
|
18
18
|
end
|
19
19
|
|
20
20
|
@expected_text = expected_text.is_a?(Regexp) ? expected_text : expected_text.to_s
|
@@ -8,6 +8,7 @@ class Capybara::RackTest::Browser
|
|
8
8
|
|
9
9
|
def initialize(driver)
|
10
10
|
@driver = driver
|
11
|
+
@current_fragment = nil
|
11
12
|
end
|
12
13
|
|
13
14
|
def app
|
@@ -31,7 +32,7 @@ class Capybara::RackTest::Browser
|
|
31
32
|
def submit(method, path, attributes)
|
32
33
|
path = request_path if path.nil? || path.empty?
|
33
34
|
uri = build_uri(path)
|
34
|
-
uri.query = '' if method
|
35
|
+
uri.query = '' if method.to_s.casecmp('get').zero?
|
35
36
|
process_and_follow_redirects(method, uri.to_s, attributes, 'HTTP_REFERER' => current_url)
|
36
37
|
end
|
37
38
|
|
@@ -42,6 +43,7 @@ class Capybara::RackTest::Browser
|
|
42
43
|
end
|
43
44
|
|
44
45
|
def process_and_follow_redirects(method, path, attributes = {}, env = {})
|
46
|
+
@current_fragment = build_uri(path).fragment
|
45
47
|
process(method, path, attributes, env)
|
46
48
|
|
47
49
|
return unless driver.follow_redirects?
|
@@ -65,7 +67,7 @@ class Capybara::RackTest::Browser
|
|
65
67
|
method = method.downcase
|
66
68
|
new_uri = build_uri(path)
|
67
69
|
@current_scheme, @current_host, @current_port = new_uri.select(:scheme, :host, :port)
|
68
|
-
|
70
|
+
@current_fragment = new_uri.fragment || @current_fragment
|
69
71
|
reset_cache!
|
70
72
|
send(method, new_uri.to_s, attributes, env.merge(options[:headers] || {}))
|
71
73
|
end
|
@@ -83,7 +85,9 @@ class Capybara::RackTest::Browser
|
|
83
85
|
end
|
84
86
|
|
85
87
|
def current_url
|
86
|
-
last_request.url
|
88
|
+
uri = build_uri(last_request.url)
|
89
|
+
uri.fragment = @current_fragment if @current_fragment
|
90
|
+
uri.to_s
|
87
91
|
rescue Rack::Test::Error
|
88
92
|
''
|
89
93
|
end
|
@@ -17,6 +17,7 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
|
|
17
17
|
def initialize(app, **options)
|
18
18
|
raise ArgumentError, 'rack-test requires a rack application, but none was given' unless app
|
19
19
|
|
20
|
+
super()
|
20
21
|
@app = app
|
21
22
|
@options = DEFAULT_OPTIONS.merge(options)
|
22
23
|
end
|
@@ -6,7 +6,7 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node
|
|
6
6
|
# That check should be based solely on the form element's 'enctype' attribute value,
|
7
7
|
# which should probably be provided to Rack::Test in its non-GET request methods.
|
8
8
|
class NilUploadedFile < Rack::Test::UploadedFile
|
9
|
-
def initialize
|
9
|
+
def initialize # rubocop:disable Lint/MissingSuper
|
10
10
|
@empty_file = Tempfile.new('nil_uploaded_file')
|
11
11
|
@empty_file.close
|
12
12
|
end
|
@@ -15,7 +15,7 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def visible_text
|
18
|
-
displayed_text.
|
18
|
+
displayed_text.squeeze(' ')
|
19
19
|
.gsub(/[\ \n]*\n[\ \n]*/, "\n")
|
20
20
|
.gsub(/\A[[:space:]&&[^\u00a0]]+/, '')
|
21
21
|
.gsub(/[[:space:]&&[^\u00a0]]+\z/, '')
|
@@ -12,13 +12,13 @@ module Capybara
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def []=(name, value)
|
15
|
-
warn 'DEPRECATED: Directly setting drivers/servers is deprecated, please use Capybara.register_driver/register_server instead'
|
15
|
+
Capybara::Helpers.warn 'DEPRECATED: Directly setting drivers/servers is deprecated, please use Capybara.register_driver/register_server instead'
|
16
16
|
@registered[name] = value
|
17
17
|
end
|
18
18
|
|
19
19
|
def method_missing(method_name, *args, **options, &block)
|
20
20
|
if @registered.respond_to?(method_name)
|
21
|
-
warn "DEPRECATED: Calling '#{method_name}' on the drivers/servers container is deprecated without replacement"
|
21
|
+
Capybara::Helpers.warn "DEPRECATED: Calling '#{method_name}' on the drivers/servers container is deprecated without replacement"
|
22
22
|
# RUBY 2.6 will send an empty hash rather than nothing with **options so fix that
|
23
23
|
return @registered.public_send(method_name, *args, &block) if options.empty?
|
24
24
|
|
@@ -27,7 +27,7 @@ module Capybara
|
|
27
27
|
super
|
28
28
|
end
|
29
29
|
|
30
|
-
def respond_to_missing?(method_name,
|
30
|
+
def respond_to_missing?(method_name, include_all)
|
31
31
|
@registered.respond_to?(method_name) || super
|
32
32
|
end
|
33
33
|
|
@@ -9,28 +9,34 @@ Capybara.register_driver :selenium do |app|
|
|
9
9
|
end
|
10
10
|
|
11
11
|
Capybara.register_driver :selenium_headless do |app|
|
12
|
-
Capybara::Selenium::Driver.load_selenium
|
13
|
-
|
14
|
-
browser_options.
|
15
|
-
|
12
|
+
version = Capybara::Selenium::Driver.load_selenium
|
13
|
+
options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
|
14
|
+
browser_options = ::Selenium::WebDriver::Firefox::Options.new.tap do |opts|
|
15
|
+
opts.add_argument '-headless'
|
16
|
+
end
|
17
|
+
Capybara::Selenium::Driver.new(app, **Hash[:browser => :firefox, options_key => browser_options])
|
16
18
|
end
|
17
19
|
|
18
20
|
Capybara.register_driver :selenium_chrome do |app|
|
19
|
-
Capybara::Selenium::Driver.load_selenium
|
21
|
+
version = Capybara::Selenium::Driver.load_selenium
|
22
|
+
options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
|
20
23
|
browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
|
21
24
|
# Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
|
22
|
-
opts.
|
25
|
+
opts.add_argument('--disable-site-isolation-trials')
|
23
26
|
end
|
24
|
-
|
27
|
+
|
28
|
+
Capybara::Selenium::Driver.new(app, **Hash[:browser => :chrome, options_key => browser_options])
|
25
29
|
end
|
26
30
|
|
27
31
|
Capybara.register_driver :selenium_chrome_headless do |app|
|
28
|
-
Capybara::Selenium::Driver.load_selenium
|
32
|
+
version = Capybara::Selenium::Driver.load_selenium
|
33
|
+
options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
|
29
34
|
browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
|
30
|
-
opts.
|
31
|
-
opts.
|
35
|
+
opts.add_argument('--headless')
|
36
|
+
opts.add_argument('--disable-gpu') if Gem.win_platform?
|
32
37
|
# Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
|
33
|
-
opts.
|
38
|
+
opts.add_argument('--disable-site-isolation-trials')
|
34
39
|
end
|
35
|
-
|
40
|
+
|
41
|
+
Capybara::Selenium::Driver.new(app, **Hash[:browser => :chrome, options_key => browser_options])
|
36
42
|
end
|
@@ -4,12 +4,14 @@ module Puma
|
|
4
4
|
module MiniSSL
|
5
5
|
class Socket
|
6
6
|
def read_nonblock(size, *_)
|
7
|
+
wait_states = %i[wait_readable wait_writable]
|
8
|
+
|
7
9
|
loop do
|
8
10
|
output = engine_read_all
|
9
11
|
return output if output
|
10
12
|
|
11
13
|
data = @socket.read_nonblock(size, exception: false)
|
12
|
-
raise IO::EAGAINWaitReadable if
|
14
|
+
raise IO::EAGAINWaitReadable if wait_states.include? data
|
13
15
|
return nil if data.nil?
|
14
16
|
|
15
17
|
@engine.inject(data)
|
@@ -28,10 +28,11 @@ Capybara.register_server :puma do |app, port, host, **options|
|
|
28
28
|
options = default_options.merge(options)
|
29
29
|
|
30
30
|
conf = Rack::Handler::Puma.config(app, options)
|
31
|
+
conf.clamp
|
31
32
|
events = conf.options[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
|
32
33
|
|
33
34
|
puma_ver = Gem::Version.new(Puma::Const::PUMA_VERSION)
|
34
|
-
require_relative 'patches/puma_ssl' if
|
35
|
+
require_relative 'patches/puma_ssl' if Gem::Requirement.new('>=4.0.0', '< 4.1.0').satisfied_by?(puma_ver)
|
35
36
|
|
36
37
|
events.log 'Capybara starting Puma...'
|
37
38
|
events.log "* Version #{Puma::Const::PUMA_VERSION} , codename: #{Puma::Const::CODE_NAME}"
|
data/lib/capybara/result.rb
CHANGED
@@ -39,7 +39,7 @@ module Capybara
|
|
39
39
|
alias index find_index
|
40
40
|
|
41
41
|
def each(&block)
|
42
|
-
return enum_for(:each) unless
|
42
|
+
return enum_for(:each) unless block
|
43
43
|
|
44
44
|
@result_cache.each(&block)
|
45
45
|
loop do
|
@@ -54,10 +54,10 @@ module Capybara
|
|
54
54
|
idx, length = args
|
55
55
|
max_idx = case idx
|
56
56
|
when Integer
|
57
|
-
if
|
58
|
-
length.nil? ? idx : idx + length - 1
|
59
|
-
else
|
57
|
+
if idx.negative?
|
60
58
|
nil
|
59
|
+
else
|
60
|
+
length.nil? ? idx : idx + length - 1
|
61
61
|
end
|
62
62
|
when Range
|
63
63
|
# idx.max is broken with beginless ranges
|
@@ -91,13 +91,9 @@ module Capybara
|
|
91
91
|
return load_up_to(count + 1) <=> count
|
92
92
|
end
|
93
93
|
|
94
|
-
if min && (min = Integer(min))
|
95
|
-
return -1 if load_up_to(min) < min
|
96
|
-
end
|
94
|
+
return -1 if min && (min = Integer(min)) && (load_up_to(min) < min)
|
97
95
|
|
98
|
-
if max && (max = Integer(max))
|
99
|
-
return 1 if load_up_to(max + 1) > max
|
100
|
-
end
|
96
|
+
return 1 if max && (max = Integer(max)) && (load_up_to(max + 1) > max)
|
101
97
|
|
102
98
|
if between
|
103
99
|
min, max = (between.begin && between.min) || 1, between.end
|
data/lib/capybara/rspec.rb
CHANGED
@@ -9,6 +9,8 @@ require 'capybara/rspec/matcher_proxies'
|
|
9
9
|
RSpec.configure do |config|
|
10
10
|
config.include Capybara::DSL, type: :feature
|
11
11
|
config.include Capybara::RSpecMatchers, type: :feature
|
12
|
+
config.include Capybara::DSL, type: :system
|
13
|
+
config.include Capybara::RSpecMatchers, type: :system
|
12
14
|
config.include Capybara::RSpecMatchers, type: :view
|
13
15
|
|
14
16
|
# The before and after blocks must run instantaneously, because Capybara
|
@@ -94,7 +94,7 @@ module Capybara
|
|
94
94
|
# @see Capybara::Node::Matchers#has_button?
|
95
95
|
|
96
96
|
# @!method have_field(locator = nil, **options, &optional_filter_block)
|
97
|
-
# RSpec matcher for
|
97
|
+
# RSpec matcher for form fields.
|
98
98
|
#
|
99
99
|
# @see Capybara::Node::Matchers#has_field?
|
100
100
|
|
@@ -139,22 +139,23 @@ module Capybara
|
|
139
139
|
# RSpec matcher for the current path.
|
140
140
|
#
|
141
141
|
# @see Capybara::SessionMatchers#assert_current_path
|
142
|
-
def have_current_path(path, **options)
|
143
|
-
Matchers::HaveCurrentPath.new(path, **options)
|
142
|
+
def have_current_path(path, **options, &optional_filter_block)
|
143
|
+
Matchers::HaveCurrentPath.new(path, **options, &optional_filter_block)
|
144
144
|
end
|
145
145
|
|
146
146
|
# RSpec matcher for element style.
|
147
147
|
#
|
148
148
|
# @see Capybara::Node::Matchers#matches_style?
|
149
|
-
def match_style(styles, **options)
|
149
|
+
def match_style(styles = nil, **options)
|
150
|
+
styles, options = options, {} if styles.nil?
|
150
151
|
Matchers::MatchStyle.new(styles, **options)
|
151
152
|
end
|
152
153
|
|
153
154
|
##
|
154
155
|
# @deprecated
|
155
156
|
#
|
156
|
-
def have_style(styles, **options)
|
157
|
-
warn
|
157
|
+
def have_style(styles = nil, **options)
|
158
|
+
Capybara::Helpers.warn "DEPRECATED: have_style is deprecated, please use match_style : #{Capybara::Helpers.filter_backtrace(caller)}"
|
158
159
|
match_style(styles, **options)
|
159
160
|
end
|
160
161
|
|