capybara 3.35.0 → 3.40.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 +168 -5
- data/README.md +199 -39
- data/lib/capybara/config.rb +16 -4
- data/lib/capybara/driver/base.rb +4 -0
- data/lib/capybara/driver/node.rb +5 -1
- data/lib/capybara/dsl.rb +4 -10
- data/lib/capybara/helpers.rb +9 -14
- data/lib/capybara/minitest/spec.rb +18 -6
- data/lib/capybara/minitest.rb +14 -1
- data/lib/capybara/node/actions.rb +14 -9
- data/lib/capybara/node/base.rb +2 -1
- data/lib/capybara/node/document.rb +2 -2
- data/lib/capybara/node/element.rb +13 -2
- data/lib/capybara/node/finders.rb +11 -2
- data/lib/capybara/node/matchers.rb +25 -0
- data/lib/capybara/node/simple.rb +5 -1
- data/lib/capybara/node/whitespace_normalizer.rb +81 -0
- data/lib/capybara/queries/active_element_query.rb +18 -0
- data/lib/capybara/queries/ancestor_query.rb +2 -1
- data/lib/capybara/queries/base_query.rb +2 -2
- data/lib/capybara/queries/current_path_query.rb +1 -1
- data/lib/capybara/queries/selector_query.rb +40 -11
- data/lib/capybara/queries/sibling_query.rb +2 -1
- data/lib/capybara/queries/text_query.rb +1 -1
- data/lib/capybara/rack_test/browser.rb +64 -8
- data/lib/capybara/rack_test/driver.rb +4 -4
- data/lib/capybara/rack_test/form.rb +29 -7
- data/lib/capybara/rack_test/node.rb +32 -33
- data/lib/capybara/registration_container.rb +2 -5
- data/lib/capybara/registrations/drivers.rb +7 -7
- data/lib/capybara/registrations/servers.rb +37 -16
- data/lib/capybara/result.rb +2 -2
- data/lib/capybara/rspec/matcher_proxies.rb +6 -6
- data/lib/capybara/rspec/matchers/base.rb +8 -6
- data/lib/capybara/rspec/matchers/compound.rb +1 -1
- data/lib/capybara/rspec/matchers/have_selector.rb +9 -17
- data/lib/capybara/rspec/matchers.rb +21 -16
- data/lib/capybara/selector/builders/css_builder.rb +1 -1
- data/lib/capybara/selector/builders/xpath_builder.rb +1 -1
- data/lib/capybara/selector/css.rb +6 -6
- data/lib/capybara/selector/definition/button.rb +10 -5
- data/lib/capybara/selector/definition/checkbox.rb +1 -1
- data/lib/capybara/selector/definition/file_field.rb +1 -1
- data/lib/capybara/selector/definition/fillable_field.rb +1 -1
- data/lib/capybara/selector/definition/link.rb +2 -1
- data/lib/capybara/selector/definition/radio_button.rb +1 -1
- data/lib/capybara/selector/definition/table.rb +1 -1
- data/lib/capybara/selector/definition/table_row.rb +2 -2
- data/lib/capybara/selector/definition.rb +4 -2
- data/lib/capybara/selector/filter_set.rb +4 -7
- data/lib/capybara/selector/regexp_disassembler.rb +2 -5
- data/lib/capybara/selector/selector.rb +5 -1
- data/lib/capybara/selector.rb +252 -0
- data/lib/capybara/selenium/driver.rb +31 -54
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +1 -1
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +9 -5
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +2 -7
- data/lib/capybara/selenium/extensions/html5_drag.rb +5 -4
- data/lib/capybara/selenium/node.rb +60 -38
- data/lib/capybara/selenium/nodes/chrome_node.rb +4 -16
- data/lib/capybara/selenium/nodes/edge_node.rb +19 -13
- data/lib/capybara/selenium/nodes/firefox_node.rb +3 -3
- data/lib/capybara/selenium/nodes/safari_node.rb +4 -4
- data/lib/capybara/selenium/patches/atoms.rb +1 -1
- data/lib/capybara/selenium/patches/pause_duration_fix.rb +1 -1
- data/lib/capybara/server/animation_disabler.rb +40 -23
- data/lib/capybara/server/middleware.rb +1 -1
- data/lib/capybara/server.rb +1 -1
- data/lib/capybara/session/config.rb +4 -2
- data/lib/capybara/session.rb +34 -34
- data/lib/capybara/spec/public/test.js +4 -0
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +11 -15
- data/lib/capybara/spec/session/assert_text_spec.rb +17 -17
- data/lib/capybara/spec/session/attach_file_spec.rb +6 -0
- data/lib/capybara/spec/session/check_spec.rb +10 -0
- data/lib/capybara/spec/session/choose_spec.rb +6 -0
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +9 -0
- data/lib/capybara/spec/session/click_link_spec.rb +12 -1
- data/lib/capybara/spec/session/current_scope_spec.rb +1 -1
- data/lib/capybara/spec/session/fill_in_spec.rb +6 -0
- data/lib/capybara/spec/session/find_link_spec.rb +10 -0
- data/lib/capybara/spec/session/find_spec.rb +15 -1
- data/lib/capybara/spec/session/first_spec.rb +1 -1
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +2 -0
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +5 -5
- data/lib/capybara/spec/session/has_ancestor_spec.rb +2 -2
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +6 -2
- data/lib/capybara/spec/session/has_button_spec.rb +30 -0
- data/lib/capybara/spec/session/has_current_path_spec.rb +3 -3
- data/lib/capybara/spec/session/has_element_spec.rb +47 -0
- data/lib/capybara/spec/session/has_field_spec.rb +25 -1
- data/lib/capybara/spec/session/has_link_spec.rb +40 -0
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +7 -7
- data/lib/capybara/spec/session/has_select_spec.rb +10 -4
- data/lib/capybara/spec/session/has_selector_spec.rb +15 -0
- data/lib/capybara/spec/session/has_table_spec.rb +13 -2
- data/lib/capybara/spec/session/has_text_spec.rb +6 -14
- data/lib/capybara/spec/session/matches_style_spec.rb +2 -0
- data/lib/capybara/spec/session/node_spec.rb +88 -1
- data/lib/capybara/spec/session/node_wrapper_spec.rb +1 -1
- data/lib/capybara/spec/session/reset_session_spec.rb +13 -0
- data/lib/capybara/spec/session/scroll_spec.rb +7 -5
- data/lib/capybara/spec/session/uncheck_spec.rb +1 -1
- data/lib/capybara/spec/session/visit_spec.rb +20 -0
- 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/session/within_spec.rb +13 -0
- data/lib/capybara/spec/spec_helper.rb +12 -5
- data/lib/capybara/spec/test_app.rb +91 -14
- data/lib/capybara/spec/views/animated.erb +1 -1
- data/lib/capybara/spec/views/form.erb +34 -4
- data/lib/capybara/spec/views/frame_child.erb +1 -1
- data/lib/capybara/spec/views/frame_one.erb +1 -1
- data/lib/capybara/spec/views/frame_parent.erb +1 -1
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +2 -1
- data/lib/capybara/spec/views/layout.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +1 -1
- data/lib/capybara/spec/views/offset.erb +2 -1
- data/lib/capybara/spec/views/path.erb +2 -2
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/react.erb +2 -2
- data/lib/capybara/spec/views/scroll.erb +2 -1
- data/lib/capybara/spec/views/spatial.erb +1 -1
- data/lib/capybara/spec/views/with_animation.erb +2 -3
- data/lib/capybara/spec/views/with_base_tag.erb +2 -2
- data/lib/capybara/spec/views/with_dragula.erb +2 -2
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
- data/lib/capybara/spec/views/with_hover.erb +2 -2
- data/lib/capybara/spec/views/with_html.erb +5 -3
- data/lib/capybara/spec/views/with_jquery_animation.erb +1 -1
- data/lib/capybara/spec/views/with_js.erb +2 -3
- data/lib/capybara/spec/views/with_jstree.erb +1 -1
- data/lib/capybara/spec/views/with_namespace.erb +1 -0
- data/lib/capybara/spec/views/with_scope.erb +2 -2
- data/lib/capybara/spec/views/with_shadow.erb +31 -0
- data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +2 -2
- data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
- data/lib/capybara/spec/views/with_windows.erb +1 -1
- data/lib/capybara/spec/views/within_frames.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +1 -1
- data/lib/capybara.rb +30 -30
- data/spec/basic_node_spec.rb +16 -3
- data/spec/capybara_spec.rb +12 -0
- data/spec/counter_spec.rb +35 -0
- data/spec/css_builder_spec.rb +1 -1
- data/spec/css_splitter_spec.rb +1 -1
- data/spec/dsl_spec.rb +5 -3
- data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -2
- data/spec/fixtures/selenium_driver_rspec_success.rb +2 -2
- data/spec/minitest_spec.rb +12 -1
- data/spec/minitest_spec_spec.rb +4 -0
- data/spec/per_session_config_spec.rb +1 -1
- data/spec/rack_test_spec.rb +30 -12
- data/spec/result_spec.rb +41 -35
- data/spec/rspec/features_spec.rb +3 -3
- data/spec/rspec/scenarios_spec.rb +2 -2
- data/spec/rspec/shared_spec_matchers.rb +27 -3
- data/spec/rspec_matchers_spec.rb +25 -0
- data/spec/rspec_spec.rb +3 -3
- data/spec/sauce_spec_chrome.rb +5 -5
- data/spec/selector_spec.rb +4 -4
- data/spec/selenium_spec_chrome.rb +20 -18
- data/spec/selenium_spec_chrome_remote.rb +15 -19
- data/spec/selenium_spec_edge.rb +19 -6
- data/spec/selenium_spec_firefox.rb +26 -8
- data/spec/selenium_spec_firefox_remote.rb +18 -4
- data/spec/selenium_spec_ie.rb +7 -8
- data/spec/selenium_spec_safari.rb +34 -20
- data/spec/server_spec.rb +19 -7
- data/spec/shared_selenium_node.rb +0 -4
- data/spec/shared_selenium_session.rb +22 -14
- data/spec/spec_helper.rb +36 -3
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +1 -1
- metadata +49 -30
- data/lib/capybara/selenium/logger_suppressor.rb +0 -34
- data/lib/capybara/selenium/patches/action_pauser.rb +0 -26
- data/lib/capybara/spec/views/with_title.erb +0 -5
@@ -21,8 +21,8 @@ def ensure_selenium_running!
|
|
21
21
|
rescue StandardError
|
22
22
|
if timer.expired?
|
23
23
|
raise 'Selenium is not running. ' \
|
24
|
-
|
25
|
-
|
24
|
+
"You can run a selenium server easily with: \n. " \
|
25
|
+
'$ docker-compose up -d selenium_firefox'
|
26
26
|
else
|
27
27
|
puts 'Waiting for Selenium docker instance...'
|
28
28
|
sleep 1
|
@@ -35,11 +35,10 @@ Capybara.register_driver :selenium_firefox_remote do |app|
|
|
35
35
|
ensure_selenium_running!
|
36
36
|
|
37
37
|
url = "http://#{selenium_host}:#{selenium_port}/wd/hub"
|
38
|
-
browser_options =
|
38
|
+
browser_options = Selenium::WebDriver::Firefox::Options.new
|
39
39
|
|
40
40
|
Capybara::Selenium::Driver.new app,
|
41
41
|
browser: :remote,
|
42
|
-
desired_capabilities: :firefox,
|
43
42
|
options: browser_options,
|
44
43
|
url: url
|
45
44
|
end
|
@@ -65,6 +64,21 @@ Capybara::SpecHelper.run_specs TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVE
|
|
65
64
|
when /#accept_confirm should work with nested modals$/
|
66
65
|
# skip because this is timing based and hence flaky when set to pending
|
67
66
|
skip 'Broken in FF 63 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if firefox_gte?(63, @session)
|
67
|
+
when 'Capybara::Session selenium_firefox_remote #fill_in should handle carriage returns with line feeds in a textarea correctly'
|
68
|
+
pending 'Not sure what firefox is doing here'
|
69
|
+
when 'Capybara::Session selenium_firefox_remote node #shadow_root should find elements inside the shadow dom using CSS',
|
70
|
+
'Capybara::Session selenium_firefox_remote node #shadow_root should find nested shadow roots',
|
71
|
+
'Capybara::Session selenium_firefox_remote node #shadow_root should click on elements',
|
72
|
+
'Capybara::Session selenium_firefox_remote node #shadow_root should use convenience methods once moved to a descendant of the shadow root',
|
73
|
+
'Capybara::Session selenium_firefox_remote node #shadow_root should produce error messages when failing',
|
74
|
+
'Capybara::Session with remote firefox with selenium driver #evaluate_script returns a shadow root'
|
75
|
+
pending "Firefox doesn't yet have full W3C shadow root support"
|
76
|
+
when /Capybara::Session selenium_firefox_remote node #shadow_root should get visible text/
|
77
|
+
pending "Selenium doesn't currently support getting visible text for shadow root elements"
|
78
|
+
when /Capybara::Session selenium_firefox_remote node #shadow_root/
|
79
|
+
skip 'Not supported with this geckodriver version' if geckodriver_lt?('0.31.0', @session)
|
80
|
+
when /Capybara::Session selenium node #set should submit single text input forms if ended with \\n/
|
81
|
+
pending 'Firefox/geckodriver doesn\'t submit with values ending in \n'
|
68
82
|
end
|
69
83
|
end
|
70
84
|
|
data/spec/selenium_spec_ie.rb
CHANGED
@@ -28,7 +28,7 @@ end
|
|
28
28
|
|
29
29
|
Capybara.register_driver :selenium_ie do |app|
|
30
30
|
# ::Selenium::WebDriver.logger.level = "debug"
|
31
|
-
options =
|
31
|
+
options = Selenium::WebDriver::IE::Options.new
|
32
32
|
# options.require_window_focus = true
|
33
33
|
# options.add_option("log", {"level": "trace"})
|
34
34
|
|
@@ -71,13 +71,10 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumIE, 'selenium', capybara_sk
|
|
71
71
|
pending "IE 11 doesn't support date input types"
|
72
72
|
when /#click_link_or_button with :disabled option happily clicks on links which incorrectly have the disabled attribute$/
|
73
73
|
skip 'IE 11 obeys non-standard disabled attribute on anchor tag'
|
74
|
-
when /#
|
75
|
-
skip "Windows can't :meta click because :meta triggers start menu"
|
76
|
-
when /#click should allow modifiers$/
|
74
|
+
when /#click should allow modifiers$/, /#double_click should allow modifiers$/
|
77
75
|
pending "Doesn't work with IE for some unknown reason$"
|
78
|
-
when /#double_click should allow modifiers$/
|
79
76
|
pending "Doesn't work with IE for some unknown reason$"
|
80
|
-
when /#click should allow multiple modifiers$/
|
77
|
+
when /#click should allow multiple modifiers$/, /#right_click should allow modifiers$/
|
81
78
|
skip "Windows can't :meta click because :meta triggers start menu"
|
82
79
|
when /#double_click should allow multiple modifiers$/
|
83
80
|
skip "Windows can't :alt double click due to being properties shortcut"
|
@@ -91,7 +88,7 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumIE, 'selenium', capybara_sk
|
|
91
88
|
pending "Window 7 and 8.1 don't support 308 http status code"
|
92
89
|
when /#scroll_to can scroll an element to the center of the viewport$/,
|
93
90
|
/#scroll_to can scroll an element to the center of the scrolling element$/
|
94
|
-
pending "
|
91
|
+
pending "IE doesn't support ScrollToOptions"
|
95
92
|
when /#attach_file with multipart form should fire change once for each set of files uploaded$/,
|
96
93
|
/#attach_file with multipart form should fire change once when uploading multiple files from empty$/,
|
97
94
|
/#attach_file with multipart form should not break when using HTML5 multiple file input uploading multiple files$/
|
@@ -106,11 +103,13 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumIE, 'selenium', capybara_sk
|
|
106
103
|
when /#attach_file with a block/
|
107
104
|
skip 'Hangs IE testing for unknown reason'
|
108
105
|
when /drag_to.*HTML5/
|
109
|
-
pending "IE doesn't support a DataTransfer
|
106
|
+
pending "IE doesn't support a DataTransfer constructor"
|
110
107
|
when /template elements should not be visible/
|
111
108
|
skip "IE doesn't support template elements"
|
112
109
|
when /Element#drop/
|
113
110
|
pending "IE doesn't support DataTransfer constructor"
|
111
|
+
when /Capybara::Session selenium_chrome node #shadow_root should get visible text/
|
112
|
+
pending "Selenium doesn't currently support getting visible text for shadow root elements"
|
114
113
|
end
|
115
114
|
end
|
116
115
|
|
@@ -8,28 +8,40 @@ require 'rspec/shared_spec_matchers'
|
|
8
8
|
|
9
9
|
SAFARI_DRIVER = :selenium_safari
|
10
10
|
|
11
|
-
if ::Selenium::WebDriver::Service.respond_to? :driver_path=
|
12
|
-
|
13
|
-
else
|
14
|
-
|
15
|
-
end.driver_path = '/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
|
11
|
+
# if ::Selenium::WebDriver::Service.respond_to? :driver_path=
|
12
|
+
# ::Selenium::WebDriver::Safari::Service
|
13
|
+
# else
|
14
|
+
# ::Selenium::WebDriver::Safari
|
15
|
+
# end.driver_path = '/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
|
16
16
|
|
17
|
-
browser_options =
|
17
|
+
browser_options = Selenium::WebDriver::Safari::Options.new
|
18
18
|
# browser_options.headless! if ENV['HEADLESS']
|
19
|
-
# browser_options.add_option(:w3c, !!ENV['W3C'])
|
20
19
|
|
21
20
|
Capybara.register_driver :selenium_safari do |app|
|
22
|
-
Capybara::Selenium::Driver.
|
21
|
+
version = Capybara::Selenium::Driver.load_selenium
|
22
|
+
options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
|
23
|
+
driver_options = { browser: :safari, timeout: 30 }.tap do |opts|
|
24
|
+
opts[options_key] = browser_options
|
25
|
+
end
|
26
|
+
|
27
|
+
Capybara::Selenium::Driver.new(app, **driver_options).tap do |driver|
|
23
28
|
# driver.browser.download_path = Capybara.save_path
|
24
29
|
end
|
25
30
|
end
|
26
31
|
|
27
32
|
Capybara.register_driver :selenium_safari_not_clear_storage do |app|
|
28
|
-
|
33
|
+
version = Capybara::Selenium::Driver.load_selenium
|
34
|
+
options_key = Capybara::Selenium::Driver::CAPS_VERSION.satisfied_by?(version) ? :capabilities : :options
|
35
|
+
driver_options = {
|
29
36
|
browser: :safari,
|
30
|
-
|
31
|
-
|
32
|
-
|
37
|
+
clear_local_storage: false,
|
38
|
+
clear_session_storage: false,
|
39
|
+
timeout: 30
|
40
|
+
}.tap do |opts|
|
41
|
+
opts[options_key] = browser_options
|
42
|
+
end
|
43
|
+
|
44
|
+
Capybara::Selenium::Driver.new(app, **driver_options)
|
33
45
|
end
|
34
46
|
|
35
47
|
module TestSessions
|
@@ -65,16 +77,19 @@ Capybara::SpecHelper.run_specs TestSessions::Safari, SAFARI_DRIVER.to_s, capybar
|
|
65
77
|
when 'Capybara::Session selenium_safari node #double_click should allow to adjust the offset',
|
66
78
|
'Capybara::Session selenium_safari node #double_click should double click an element'
|
67
79
|
pending "safardriver doesn't generate a double click event"
|
68
|
-
when 'Capybara::Session selenium_safari node #
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
pending "safardriver clear doesn't generate change event"
|
80
|
+
when 'Capybara::Session selenium_safari node #double_click should allow modifiers'
|
81
|
+
pending "safaridriver doesn't generate double click with key modifiers"
|
82
|
+
when /when w3c_click_offset is true should offset/
|
83
|
+
pending 'w3c_click_offset is not currently supported with safaridriver'
|
73
84
|
when 'Capybara::Session selenium_safari #go_back should fetch a response from the driver from the previous page',
|
74
85
|
'Capybara::Session selenium_safari #go_forward should fetch a response from the driver from the previous page'
|
75
86
|
skip 'safaridriver loses the ability to find elements in the document after `go_back`'
|
76
|
-
when
|
77
|
-
|
87
|
+
when 'Capybara::Session selenium node #shadow_root should get the shadow root',
|
88
|
+
'Capybara::Session selenium node #shadow_root should find elements inside the shadow dom using CSS',
|
89
|
+
'Capybara::Session selenium node #shadow_root should find nested shadow roots'
|
90
|
+
pending "Safari doesn't yet have W3C shadow root support"
|
91
|
+
when /Capybara::Session selenium_chrome node #shadow_root should get visible text/
|
92
|
+
pending "Selenium doesn't currently support getting visible text for shadow root elements"
|
78
93
|
end
|
79
94
|
end
|
80
95
|
|
@@ -124,7 +139,6 @@ RSpec.describe 'Capybara::Session with safari' do
|
|
124
139
|
end
|
125
140
|
|
126
141
|
it 'should fill in a date input with a String' do
|
127
|
-
pending "Safari doesn't support date inputs"
|
128
142
|
session.fill_in('form_date', with: '06/19/1983')
|
129
143
|
session.click_button('awesome')
|
130
144
|
expect(Date.parse(extract_results(session)['date'])).to eq datetime.to_date
|
data/spec/server_spec.rb
CHANGED
@@ -20,7 +20,7 @@ RSpec.describe Capybara::Server do
|
|
20
20
|
|
21
21
|
it 'should bind to the specified host' do
|
22
22
|
# TODO: travis with jruby in container mode has an issue with this test
|
23
|
-
skip 'This platform has an issue with this test' if (ENV
|
23
|
+
skip 'This platform has an issue with this test' if (ENV.fetch('TRAVIS', nil) && (RUBY_ENGINE == 'jruby')) || Gem.win_platform?
|
24
24
|
|
25
25
|
begin
|
26
26
|
app = proc { |_env| [200, {}, ['Hello Server!']] }
|
@@ -78,7 +78,7 @@ RSpec.describe Capybara::Server do
|
|
78
78
|
# Use a port to force a EADDRINUSE error to be generated
|
79
79
|
server = TCPServer.new('0.0.0.0', 0)
|
80
80
|
server_port = server.addr[1]
|
81
|
-
d_server = instance_double(
|
81
|
+
d_server = instance_double(TCPServer, addr: [nil, server_port, nil, nil], close: nil)
|
82
82
|
call_count = 0
|
83
83
|
allow(TCPServer).to receive(:new).and_wrap_original do |m, *args|
|
84
84
|
call_count.zero? ? d_server : m.call(*args)
|
@@ -95,7 +95,7 @@ RSpec.describe Capybara::Server do
|
|
95
95
|
it 'should return its #base_url' do
|
96
96
|
app = proc { |_env| [200, {}, ['Hello Server!']] }
|
97
97
|
server = described_class.new(app).boot
|
98
|
-
uri =
|
98
|
+
uri = Addressable::URI.parse(server.base_url)
|
99
99
|
expect(uri.to_hash).to include(scheme: 'http', host: server.host, port: server.port)
|
100
100
|
end
|
101
101
|
|
@@ -118,6 +118,18 @@ RSpec.describe Capybara::Server do
|
|
118
118
|
Capybara.server = :default
|
119
119
|
end
|
120
120
|
|
121
|
+
it 'should not emit any warnings when booting puma' do
|
122
|
+
Capybara.server = :puma
|
123
|
+
app_proc = proc { |_env| [200, {}, ['Hello Puma!']] }
|
124
|
+
require 'puma'
|
125
|
+
|
126
|
+
expect do
|
127
|
+
described_class.new(app_proc).boot
|
128
|
+
end.not_to output.to_stderr
|
129
|
+
ensure
|
130
|
+
Capybara.server = :default
|
131
|
+
end
|
132
|
+
|
121
133
|
it 'should support SSL' do
|
122
134
|
key = File.join(Dir.pwd, 'spec', 'fixtures', 'key.pem')
|
123
135
|
cert = File.join(Dir.pwd, 'spec', 'fixtures', 'certificate.pem')
|
@@ -136,7 +148,7 @@ RSpec.describe Capybara::Server do
|
|
136
148
|
end
|
137
149
|
|
138
150
|
expect(res.body).to include('Hello SSL Server!')
|
139
|
-
uri =
|
151
|
+
uri = Addressable::URI.parse(server.base_url)
|
140
152
|
expect(uri.to_hash).to include(scheme: 'https', host: server.host, port: server.port)
|
141
153
|
ensure
|
142
154
|
Capybara.server = :default
|
@@ -184,7 +196,7 @@ RSpec.describe Capybara::Server do
|
|
184
196
|
start_request(server2, 3.0)
|
185
197
|
server1.wait_for_pending_requests
|
186
198
|
end.to change { done }.from(0).to(2)
|
187
|
-
expect(server2.send(:pending_requests?)).to
|
199
|
+
expect(server2.send(:pending_requests?)).to be(false)
|
188
200
|
end
|
189
201
|
end
|
190
202
|
|
@@ -229,7 +241,7 @@ RSpec.describe Capybara::Server do
|
|
229
241
|
start_request(server2, 3.0)
|
230
242
|
server1.wait_for_pending_requests
|
231
243
|
end.to change { done }.from(0).to(1)
|
232
|
-
expect(server2.send(:pending_requests?)).to
|
244
|
+
expect(server2.send(:pending_requests?)).to be(true)
|
233
245
|
expect do
|
234
246
|
server2.wait_for_pending_requests
|
235
247
|
end.to change { done }.from(1).to(2)
|
@@ -274,7 +286,7 @@ RSpec.describe Capybara::Server do
|
|
274
286
|
app = -> { [200, {}, ['Hello, world']] }
|
275
287
|
server = described_class.new(app)
|
276
288
|
allow(Net::HTTP).to receive(:start).and_raise(SystemCallError.allocate)
|
277
|
-
expect(server.responsive?).to
|
289
|
+
expect(server.responsive?).to be false
|
278
290
|
end
|
279
291
|
|
280
292
|
[EOFError, Net::ReadTimeout].each do |err|
|
@@ -61,8 +61,6 @@ RSpec.shared_examples 'Capybara::Node' do |session, _mode|
|
|
61
61
|
end
|
62
62
|
|
63
63
|
it 'will use native displayed if told to' do
|
64
|
-
pending "Chromedriver < 76.0.3809.25 doesn't support native displayed in W3C mode" if chrome_lt?(76, session) && (ENV['W3C'] != 'false')
|
65
|
-
|
66
64
|
session.driver.options[:native_displayed] = true
|
67
65
|
session.visit('/form')
|
68
66
|
session.find(:css, '#address1_city', visible: true)
|
@@ -71,8 +69,6 @@ RSpec.shared_examples 'Capybara::Node' do |session, _mode|
|
|
71
69
|
end
|
72
70
|
|
73
71
|
it "won't use native displayed if told not to" do
|
74
|
-
skip 'Non-W3C uses native' if chrome?(session) && (ENV['W3C'] == 'false')
|
75
|
-
|
76
72
|
session.driver.options[:native_displayed] = false
|
77
73
|
session.visit('/form')
|
78
74
|
session.find(:css, '#address1_city', visible: true)
|
@@ -23,7 +23,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
23
23
|
it 'freshly reset session should not be touched' do
|
24
24
|
session.instance_variable_set(:@touched, true)
|
25
25
|
session.reset!
|
26
|
-
expect(session.instance_variable_get(:@touched)).to
|
26
|
+
expect(session.instance_variable_get(:@touched)).to be false
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -74,7 +74,6 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
74
74
|
|
75
75
|
describe '#fill_in_with empty string and no options' do
|
76
76
|
it 'should trigger change when clearing a field' do
|
77
|
-
pending "safaridriver doesn't trigger change for clear" if safari?(session)
|
78
77
|
session.visit('/with_js')
|
79
78
|
session.fill_in('with_change_event', with: '')
|
80
79
|
# click outside the field to trigger the change event
|
@@ -188,14 +187,12 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
188
187
|
|
189
188
|
it 'should generate standard events on changing value' do
|
190
189
|
pending "IE 11 doesn't support date input type" if ie?(session)
|
191
|
-
pending "Safari doesn't support date input type" if safari?(session)
|
192
190
|
session.fill_in('form_date', with: Date.today)
|
193
191
|
expect(session.evaluate_script('window.capybara_formDateFiredEvents')).to eq %w[focus input change]
|
194
192
|
end
|
195
193
|
|
196
194
|
it 'should not generate input and change events if the value is not changed' do
|
197
195
|
pending "IE 11 doesn't support date input type" if ie?(session)
|
198
|
-
pending "Safari doesn't support date input type" if safari?(session)
|
199
196
|
session.fill_in('form_date', with: Date.today)
|
200
197
|
session.fill_in('form_date', with: Date.today)
|
201
198
|
# Chrome adds an extra focus for some reason - ok for now
|
@@ -223,14 +220,14 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
223
220
|
end
|
224
221
|
|
225
222
|
describe '#send_keys' do
|
226
|
-
it 'defaults to sending keys to the
|
223
|
+
it 'defaults to sending keys to the active_element' do
|
227
224
|
session.visit('/form')
|
228
225
|
|
229
|
-
expect(session.
|
226
|
+
expect(session.active_element).to match_selector(:css, 'body')
|
230
227
|
|
231
228
|
session.send_keys(:tab)
|
232
229
|
|
233
|
-
expect(session.
|
230
|
+
expect(session.active_element).to match_selector(:css, '[tabindex="1"]')
|
234
231
|
end
|
235
232
|
end
|
236
233
|
|
@@ -283,6 +280,13 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
283
280
|
expect(element).to eq session.find(:id, 'form_title')
|
284
281
|
end
|
285
282
|
|
283
|
+
it 'returns a shadow root' do
|
284
|
+
session.visit('/with_shadow')
|
285
|
+
shadow = session.find(:css, '#shadow_host')
|
286
|
+
element = session.evaluate_script('arguments[0].shadowRoot', shadow)
|
287
|
+
expect(element).to be_instance_of(Capybara::Node::Element)
|
288
|
+
end
|
289
|
+
|
286
290
|
it 'can return arrays of nested elements' do
|
287
291
|
session.visit('/form')
|
288
292
|
elements = session.evaluate_script('document.querySelectorAll("#form_city option")')
|
@@ -339,17 +343,15 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
339
343
|
it 'can attach a directory' do
|
340
344
|
pending "Geckodriver doesn't support uploading a directory" if firefox?(session)
|
341
345
|
pending "Selenium remote doesn't support transferring a directory" if remote?(session)
|
342
|
-
pending "Headless Chrome doesn't support directory upload - https://bugs.chromium.org/p/chromedriver/issues/detail?id=2521&q=directory%20upload&colspec=ID%20Status%20Pri%20Owner%20Summary" if chrome?(session) && ENV
|
346
|
+
pending "Headless Chrome doesn't support directory upload - https://bugs.chromium.org/p/chromedriver/issues/detail?id=2521&q=directory%20upload&colspec=ID%20Status%20Pri%20Owner%20Summary" if chrome?(session) && chrome_lt?(110, session) && ENV.fetch('HEADLESS', nil)
|
343
347
|
pending "IE doesn't support uploading a directory" if ie?(session)
|
344
348
|
pending 'Chrome/chromedriver 73 breaks this' if chrome?(session) && chrome_gte?(73, session) && chrome_lt?(75, session)
|
345
|
-
pending "Safari doesn't support uploading a directory" if safari?(session)
|
346
|
-
# pending "Edge/msedgedriver doesn't support directory upload" if edge?(session) && edge_gte?(75, session)
|
347
349
|
|
348
350
|
session.visit('/form')
|
349
351
|
test_file_dir = File.expand_path('./fixtures', File.dirname(__FILE__))
|
350
352
|
session.attach_file('Directory Upload', test_file_dir)
|
351
353
|
session.click_button('Upload Multiple')
|
352
|
-
expect(session
|
354
|
+
expect(session).to have_text('5 | ') # number of files
|
353
355
|
end
|
354
356
|
|
355
357
|
it 'can attach a relative file' do
|
@@ -358,7 +360,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
358
360
|
session.visit('/form')
|
359
361
|
session.attach_file('Single Document', 'spec/fixtures/capybara.csv')
|
360
362
|
session.click_button('Upload Single')
|
361
|
-
expect(session
|
363
|
+
expect(session).to have_text('Content-type: text/csv')
|
362
364
|
end
|
363
365
|
end
|
364
366
|
|
@@ -381,6 +383,12 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
381
383
|
@animation_session = Capybara::Session.new(session.mode, TestApp.new)
|
382
384
|
end
|
383
385
|
|
386
|
+
it 'should add CSS to the <head> element' do
|
387
|
+
@animation_session.visit('with_animation')
|
388
|
+
|
389
|
+
expect(@animation_session).to have_selector(:css, 'head > style', text: 'transition: none', visible: :hidden)
|
390
|
+
end
|
391
|
+
|
384
392
|
it 'should disable CSS transitions' do
|
385
393
|
@animation_session.visit('with_animation')
|
386
394
|
@animation_session.click_link('transition me away')
|
@@ -514,8 +522,8 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
514
522
|
|
515
523
|
it 'can query attributes with strange characters' do
|
516
524
|
session.visit('/form')
|
517
|
-
expect(session).to have_selector(:element,
|
518
|
-
expect(session).to have_selector(:element,
|
525
|
+
expect(session).to have_selector(:element, '{custom}': true)
|
526
|
+
expect(session).to have_selector(:element, '{custom}': 'abcdef')
|
519
527
|
end
|
520
528
|
end
|
521
529
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rspec/expectations'
|
4
|
-
require 'webdrivers' if ENV
|
4
|
+
require 'webdrivers' if ENV.fetch('WEBDRIVERS', nil)
|
5
5
|
require 'selenium_statistics'
|
6
6
|
if ENV['TRAVIS']
|
7
7
|
require 'coveralls'
|
@@ -16,7 +16,7 @@ module Capybara
|
|
16
16
|
module SpecHelper
|
17
17
|
def firefox?(session)
|
18
18
|
browser_name(session) == :firefox &&
|
19
|
-
((defined?(::Selenium::WebDriver::VERSION) && (::Selenium::WebDriver::VERSION
|
19
|
+
((defined?(::Selenium::WebDriver::VERSION) && (Gem::Version.new(::Selenium::WebDriver::VERSION) >= Gem::Version.new('4'))) ||
|
20
20
|
session.driver.browser.capabilities.is_a?(::Selenium::WebDriver::Remote::W3C::Capabilities))
|
21
21
|
end
|
22
22
|
|
@@ -28,6 +28,18 @@ module Capybara
|
|
28
28
|
firefox?(session) && (session.driver.browser.capabilities[:browser_version].to_f >= version)
|
29
29
|
end
|
30
30
|
|
31
|
+
def geckodriver_version(session)
|
32
|
+
Gem::Version.new(session.driver.browser.capabilities['moz:geckodriverVersion'])
|
33
|
+
end
|
34
|
+
|
35
|
+
def geckodriver_gte?(version, session)
|
36
|
+
firefox?(session) && geckodriver_version(session) >= Gem::Version.new(version)
|
37
|
+
end
|
38
|
+
|
39
|
+
def geckodriver_lt?(version, session)
|
40
|
+
firefox?(session) && geckodriver_version(session) < Gem::Version.new(version)
|
41
|
+
end
|
42
|
+
|
31
43
|
def chrome?(session)
|
32
44
|
browser_name(session) == :chrome
|
33
45
|
end
|
@@ -45,6 +57,27 @@ module Capybara
|
|
45
57
|
chrome?(session) && (chrome_version(session) >= version)
|
46
58
|
end
|
47
59
|
|
60
|
+
def chromedriver_version(session)
|
61
|
+
Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0])
|
62
|
+
end
|
63
|
+
|
64
|
+
def chromedriver_gte?(version, session)
|
65
|
+
chrome?(session) && chromedriver_version(session) >= Gem::Version.new(version)
|
66
|
+
end
|
67
|
+
|
68
|
+
def chromedriver_lt?(version, session)
|
69
|
+
chrome?(session) && chromedriver_version(session) < Gem::Version.new(version)
|
70
|
+
end
|
71
|
+
|
72
|
+
def selenium?(session)
|
73
|
+
session.driver.is_a? Capybara::Selenium::Driver
|
74
|
+
end
|
75
|
+
|
76
|
+
def selenium_lt?(version, session)
|
77
|
+
selenium?(session) &&
|
78
|
+
Gem::Version.new(::Selenium::WebDriver::VERSION) < Gem::Version.new(version)
|
79
|
+
end
|
80
|
+
|
48
81
|
def edge?(session)
|
49
82
|
browser_name(session).to_s.start_with?('edge')
|
50
83
|
end
|
@@ -81,7 +114,7 @@ module Capybara
|
|
81
114
|
mod = mod::Service if ::Selenium::WebDriver::Service.respond_to? :driver_path
|
82
115
|
path = mod.driver_path
|
83
116
|
path = path.call if path.respond_to? :call
|
84
|
-
$stdout.puts `#{path.gsub(' ', '\ ')} --version`
|
117
|
+
$stdout.puts `#{path.gsub(' ', '\ ')} --version` if path
|
85
118
|
end
|
86
119
|
end
|
87
120
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'capybara/node/whitespace_normalizer'
|
5
|
+
|
6
|
+
RSpec.describe Capybara::Node::WhitespaceNormalizer do
|
7
|
+
subject(:normalizer) do
|
8
|
+
klass = Class.new do
|
9
|
+
include Capybara::Node::WhitespaceNormalizer
|
10
|
+
end
|
11
|
+
|
12
|
+
klass.new
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:text_needing_correction) do
|
16
|
+
<<~TEXT
|
17
|
+
Some #{described_class::NON_BREAKING_SPACE}text
|
18
|
+
#{described_class::RIGHT_TO_LEFT_MARK}
|
19
|
+
#{described_class::ZERO_WIDTH_SPACE * 30}
|
20
|
+
#{described_class::LEFT_TO_RIGHT_MARK}
|
21
|
+
Here
|
22
|
+
TEXT
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#normalize_spacing' do
|
26
|
+
it 'does nothing to text not containing special characters' do
|
27
|
+
expect(normalizer.normalize_spacing('text')).to eq('text')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'compresses excess breaking spacing' do
|
31
|
+
expect(
|
32
|
+
normalizer.normalize_spacing(text_needing_correction)
|
33
|
+
).to eq('Some text Here')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#normalize_visible_spacing' do
|
38
|
+
it 'does nothing to text not containing special characters' do
|
39
|
+
expect(normalizer.normalize_visible_spacing('text')).to eq('text')
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'compresses excess breaking visible spacing' do
|
43
|
+
expect(
|
44
|
+
normalizer.normalize_visible_spacing(text_needing_correction)
|
45
|
+
).to eq <<~TEXT.chomp
|
46
|
+
Some text
|
47
|
+
#{described_class::RIGHT_TO_LEFT_MARK}
|
48
|
+
#{described_class::ZERO_WIDTH_SPACE * 30}
|
49
|
+
#{described_class::LEFT_TO_RIGHT_MARK}
|
50
|
+
Here
|
51
|
+
TEXT
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/spec/xpath_builder_spec.rb
CHANGED