capybara 2.18.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/.yardopts +1 -1
- data/History.md +945 -12
- data/License.txt +1 -1
- data/README.md +264 -90
- data/lib/capybara/config.rb +29 -57
- data/lib/capybara/cucumber.rb +2 -3
- data/lib/capybara/driver/base.rb +35 -18
- data/lib/capybara/driver/node.rb +40 -10
- data/lib/capybara/dsl.rb +10 -7
- data/lib/capybara/helpers.rb +70 -31
- data/lib/capybara/minitest/spec.rb +185 -83
- data/lib/capybara/minitest.rb +232 -112
- data/lib/capybara/node/actions.rb +274 -171
- data/lib/capybara/node/base.rb +42 -34
- data/lib/capybara/node/document.rb +15 -3
- data/lib/capybara/node/document_matchers.rb +19 -21
- data/lib/capybara/node/element.rb +362 -135
- data/lib/capybara/node/finders.rb +151 -137
- data/lib/capybara/node/matchers.rb +394 -209
- data/lib/capybara/node/simple.rb +59 -26
- 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 +12 -9
- data/lib/capybara/queries/base_query.rb +39 -28
- data/lib/capybara/queries/current_path_query.rb +21 -27
- data/lib/capybara/queries/match_query.rb +14 -7
- data/lib/capybara/queries/selector_query.rb +659 -149
- data/lib/capybara/queries/sibling_query.rb +11 -9
- data/lib/capybara/queries/style_query.rb +45 -0
- data/lib/capybara/queries/text_query.rb +56 -38
- data/lib/capybara/queries/title_query.rb +8 -11
- data/lib/capybara/rack_test/browser.rb +114 -42
- data/lib/capybara/rack_test/css_handlers.rb +6 -4
- data/lib/capybara/rack_test/driver.rb +22 -17
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +93 -58
- data/lib/capybara/rack_test/node.rb +184 -81
- data/lib/capybara/rails.rb +3 -7
- data/lib/capybara/registration_container.rb +41 -0
- data/lib/capybara/registrations/drivers.rb +42 -0
- data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
- data/lib/capybara/registrations/servers.rb +66 -0
- data/lib/capybara/result.rb +97 -63
- data/lib/capybara/rspec/features.rb +17 -50
- data/lib/capybara/rspec/matcher_proxies.rb +52 -15
- data/lib/capybara/rspec/matchers/base.rb +113 -0
- data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
- data/lib/capybara/rspec/matchers/compound.rb +88 -0
- data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
- data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
- data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
- data/lib/capybara/rspec/matchers/have_selector.rb +69 -0
- data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
- data/lib/capybara/rspec/matchers/have_text.rb +33 -0
- data/lib/capybara/rspec/matchers/have_title.rb +29 -0
- data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
- data/lib/capybara/rspec/matchers/match_style.rb +43 -0
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
- data/lib/capybara/rspec/matchers.rb +146 -310
- data/lib/capybara/rspec.rb +7 -11
- data/lib/capybara/selector/builders/css_builder.rb +84 -0
- data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
- data/lib/capybara/selector/css.rb +85 -13
- data/lib/capybara/selector/definition/button.rb +68 -0
- data/lib/capybara/selector/definition/checkbox.rb +26 -0
- data/lib/capybara/selector/definition/css.rb +10 -0
- data/lib/capybara/selector/definition/datalist_input.rb +35 -0
- data/lib/capybara/selector/definition/datalist_option.rb +25 -0
- data/lib/capybara/selector/definition/element.rb +28 -0
- data/lib/capybara/selector/definition/field.rb +40 -0
- data/lib/capybara/selector/definition/fieldset.rb +14 -0
- data/lib/capybara/selector/definition/file_field.rb +13 -0
- data/lib/capybara/selector/definition/fillable_field.rb +33 -0
- data/lib/capybara/selector/definition/frame.rb +17 -0
- data/lib/capybara/selector/definition/id.rb +6 -0
- data/lib/capybara/selector/definition/label.rb +62 -0
- data/lib/capybara/selector/definition/link.rb +55 -0
- data/lib/capybara/selector/definition/link_or_button.rb +16 -0
- data/lib/capybara/selector/definition/option.rb +27 -0
- data/lib/capybara/selector/definition/radio_button.rb +27 -0
- data/lib/capybara/selector/definition/select.rb +81 -0
- data/lib/capybara/selector/definition/table.rb +109 -0
- data/lib/capybara/selector/definition/table_row.rb +21 -0
- data/lib/capybara/selector/definition/xpath.rb +5 -0
- data/lib/capybara/selector/definition.rb +280 -0
- data/lib/capybara/selector/filter.rb +2 -17
- data/lib/capybara/selector/filter_set.rb +80 -33
- data/lib/capybara/selector/filters/base.rb +50 -6
- data/lib/capybara/selector/filters/expression_filter.rb +8 -26
- data/lib/capybara/selector/filters/locator_filter.rb +29 -0
- data/lib/capybara/selector/filters/node_filter.rb +16 -12
- data/lib/capybara/selector/regexp_disassembler.rb +211 -0
- data/lib/capybara/selector/selector.rb +93 -210
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +475 -523
- data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
- data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
- data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
- data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
- data/lib/capybara/selenium/driver.rb +298 -267
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +84 -0
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
- data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
- data/lib/capybara/selenium/extensions/find.rb +110 -0
- data/lib/capybara/selenium/extensions/html5_drag.rb +229 -0
- data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
- data/lib/capybara/selenium/extensions/scroll.rb +76 -0
- data/lib/capybara/selenium/node.rb +517 -145
- data/lib/capybara/selenium/nodes/chrome_node.rb +125 -0
- data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +136 -0
- data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
- data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
- data/lib/capybara/selenium/patches/atoms.rb +18 -0
- data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
- data/lib/capybara/selenium/patches/logs.rb +45 -0
- data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
- data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
- data/lib/capybara/server/animation_disabler.rb +80 -0
- data/lib/capybara/server/checker.rb +44 -0
- data/lib/capybara/server/middleware.rb +71 -0
- data/lib/capybara/server.rb +59 -67
- data/lib/capybara/session/config.rb +81 -67
- data/lib/capybara/session/matchers.rb +28 -20
- data/lib/capybara/session.rb +337 -365
- data/lib/capybara/spec/public/jquery.js +5 -5
- data/lib/capybara/spec/public/offset.js +6 -0
- data/lib/capybara/spec/public/test.js +151 -12
- data/lib/capybara/spec/session/accept_alert_spec.rb +12 -11
- data/lib/capybara/spec/session/accept_confirm_spec.rb +6 -5
- data/lib/capybara/spec/session/accept_prompt_spec.rb +10 -10
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +161 -57
- data/lib/capybara/spec/session/ancestor_spec.rb +27 -24
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +68 -38
- data/lib/capybara/spec/session/assert_current_path_spec.rb +75 -0
- data/lib/capybara/spec/session/assert_selector_spec.rb +143 -0
- data/lib/capybara/spec/session/assert_style_spec.rb +26 -0
- data/lib/capybara/spec/session/assert_text_spec.rb +258 -0
- data/lib/capybara/spec/session/{assert_title.rb → assert_title_spec.rb} +22 -12
- data/lib/capybara/spec/session/attach_file_spec.rb +144 -69
- data/lib/capybara/spec/session/body_spec.rb +12 -13
- data/lib/capybara/spec/session/check_spec.rb +117 -55
- data/lib/capybara/spec/session/choose_spec.rb +64 -31
- data/lib/capybara/spec/session/click_button_spec.rb +231 -173
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +55 -35
- data/lib/capybara/spec/session/click_link_spec.rb +93 -58
- data/lib/capybara/spec/session/current_scope_spec.rb +12 -11
- data/lib/capybara/spec/session/current_url_spec.rb +57 -39
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +4 -4
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +3 -2
- data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +11 -9
- data/lib/capybara/spec/session/element/match_css_spec.rb +18 -10
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +9 -7
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +71 -57
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +8 -7
- data/lib/capybara/spec/session/evaluate_script_spec.rb +29 -8
- data/lib/capybara/spec/session/execute_script_spec.rb +10 -8
- data/lib/capybara/spec/session/fill_in_spec.rb +134 -43
- data/lib/capybara/spec/session/find_button_spec.rb +25 -24
- data/lib/capybara/spec/session/find_by_id_spec.rb +10 -9
- data/lib/capybara/spec/session/find_field_spec.rb +37 -41
- data/lib/capybara/spec/session/find_link_spec.rb +46 -17
- data/lib/capybara/spec/session/find_spec.rb +260 -145
- data/lib/capybara/spec/session/first_spec.rb +80 -52
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +33 -20
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +52 -32
- data/lib/capybara/spec/session/go_back_spec.rb +2 -1
- data/lib/capybara/spec/session/go_forward_spec.rb +2 -1
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +31 -31
- data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +29 -0
- data/lib/capybara/spec/session/has_button_spec.rb +100 -13
- data/lib/capybara/spec/session/has_css_spec.rb +272 -137
- data/lib/capybara/spec/session/has_current_path_spec.rb +60 -61
- data/lib/capybara/spec/session/has_element_spec.rb +47 -0
- data/lib/capybara/spec/session/has_field_spec.rb +139 -59
- data/lib/capybara/spec/session/has_link_spec.rb +47 -6
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +42 -40
- data/lib/capybara/spec/session/has_select_spec.rb +107 -72
- data/lib/capybara/spec/session/has_selector_spec.rb +120 -71
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +183 -5
- data/lib/capybara/spec/session/has_text_spec.rb +106 -62
- data/lib/capybara/spec/session/has_title_spec.rb +20 -14
- data/lib/capybara/spec/session/has_xpath_spec.rb +57 -38
- data/lib/capybara/spec/session/{headers.rb → headers_spec.rb} +3 -2
- data/lib/capybara/spec/session/html_spec.rb +14 -6
- data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
- data/lib/capybara/spec/session/node_spec.rb +1024 -153
- data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
- data/lib/capybara/spec/session/refresh_spec.rb +12 -6
- data/lib/capybara/spec/session/reset_session_spec.rb +82 -35
- data/lib/capybara/spec/session/{response_code.rb → response_code_spec.rb} +2 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +3 -2
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +8 -12
- data/lib/capybara/spec/session/save_page_spec.rb +42 -55
- data/lib/capybara/spec/session/save_screenshot_spec.rb +16 -14
- data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/scroll_spec.rb +119 -0
- data/lib/capybara/spec/session/select_spec.rb +107 -81
- data/lib/capybara/spec/session/selectors_spec.rb +52 -19
- data/lib/capybara/spec/session/sibling_spec.rb +10 -10
- data/lib/capybara/spec/session/text_spec.rb +37 -21
- data/lib/capybara/spec/session/title_spec.rb +17 -5
- data/lib/capybara/spec/session/uncheck_spec.rb +43 -23
- data/lib/capybara/spec/session/unselect_spec.rb +39 -38
- data/lib/capybara/spec/session/visit_spec.rb +85 -53
- data/lib/capybara/spec/session/window/become_closed_spec.rb +24 -20
- data/lib/capybara/spec/session/window/current_window_spec.rb +5 -3
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +5 -3
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +27 -22
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +12 -6
- data/lib/capybara/spec/session/window/window_spec.rb +97 -63
- data/lib/capybara/spec/session/window/windows_spec.rb +12 -10
- data/lib/capybara/spec/session/window/within_window_spec.rb +31 -86
- data/lib/capybara/spec/session/within_spec.rb +83 -44
- data/lib/capybara/spec/spec_helper.rb +54 -44
- data/lib/capybara/spec/test_app.rb +158 -43
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/form.erb +163 -42
- data/lib/capybara/spec/views/frame_child.erb +4 -3
- data/lib/capybara/spec/views/frame_one.erb +2 -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 +47 -0
- data/lib/capybara/spec/views/offset.erb +33 -0
- 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 +45 -0
- data/lib/capybara/spec/views/scroll.erb +21 -0
- data/lib/capybara/spec/views/spatial.erb +31 -0
- data/lib/capybara/spec/views/tables.erb +68 -1
- data/lib/capybara/spec/views/with_animation.erb +81 -0
- data/lib/capybara/spec/views/with_base_tag.erb +2 -2
- data/lib/capybara/spec/views/with_dragula.erb +24 -0
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
- data/lib/capybara/spec/views/with_hover.erb +3 -2
- data/lib/capybara/spec/views/with_hover1.erb +10 -0
- data/lib/capybara/spec/views/with_html.erb +69 -12
- data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +30 -5
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_namespace.erb +21 -0
- data/lib/capybara/spec/views/with_scope.erb +2 -2
- data/lib/capybara/spec/views/with_scope_other.erb +6 -0
- 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 +21 -0
- 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 +5 -2
- data/lib/capybara/version.rb +2 -1
- data/lib/capybara/window.rb +36 -34
- data/lib/capybara.rb +134 -107
- data/spec/basic_node_spec.rb +60 -34
- data/spec/capybara_spec.rb +63 -88
- data/spec/counter_spec.rb +35 -0
- data/spec/css_builder_spec.rb +101 -0
- data/spec/css_splitter_spec.rb +38 -0
- data/spec/dsl_spec.rb +85 -64
- data/spec/filter_set_spec.rb +27 -9
- data/spec/fixtures/certificate.pem +25 -0
- data/spec/fixtures/key.pem +27 -0
- data/spec/fixtures/selenium_driver_rspec_failure.rb +6 -5
- data/spec/fixtures/selenium_driver_rspec_success.rb +6 -5
- data/spec/minitest_spec.rb +52 -7
- data/spec/minitest_spec_spec.rb +94 -63
- data/spec/per_session_config_spec.rb +14 -13
- data/spec/rack_test_spec.rb +194 -125
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +111 -50
- data/spec/rspec/features_spec.rb +37 -31
- data/spec/rspec/scenarios_spec.rb +10 -8
- data/spec/rspec/shared_spec_matchers.rb +473 -422
- data/spec/rspec/views_spec.rb +5 -3
- data/spec/rspec_matchers_spec.rb +52 -11
- data/spec/rspec_spec.rb +109 -89
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +397 -68
- data/spec/selenium_spec_chrome.rb +187 -40
- data/spec/selenium_spec_chrome_remote.rb +96 -0
- data/spec/selenium_spec_edge.rb +60 -0
- data/spec/selenium_spec_firefox.rb +201 -41
- data/spec/selenium_spec_firefox_remote.rb +94 -0
- data/spec/selenium_spec_ie.rb +149 -0
- data/spec/selenium_spec_safari.rb +162 -0
- data/spec/server_spec.rb +213 -102
- data/spec/session_spec.rb +53 -16
- data/spec/shared_selenium_node.rb +79 -0
- data/spec/shared_selenium_session.rb +473 -122
- data/spec/spec_helper.rb +126 -7
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +355 -73
- data/.yard/templates_custom/default/class/html/selectors.erb +0 -38
- data/.yard/templates_custom/default/class/html/setup.rb +0 -17
- data/.yard/yard_extensions.rb +0 -78
- data/lib/capybara/query.rb +0 -7
- data/lib/capybara/rspec/compound.rb +0 -95
- data/lib/capybara/spec/session/assert_current_path.rb +0 -72
- data/lib/capybara/spec/session/assert_selector.rb +0 -148
- data/lib/capybara/spec/session/assert_text.rb +0 -234
- data/lib/capybara/spec/session/source_spec.rb +0 -0
- data/lib/capybara/spec/views/with_title.erb +0 -5
- data/spec/selenium_spec_marionette.rb +0 -127
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Puma
|
|
4
|
+
module MiniSSL
|
|
5
|
+
class Socket
|
|
6
|
+
def read_nonblock(size, *_)
|
|
7
|
+
wait_states = %i[wait_readable wait_writable]
|
|
8
|
+
|
|
9
|
+
loop do
|
|
10
|
+
output = engine_read_all
|
|
11
|
+
return output if output
|
|
12
|
+
|
|
13
|
+
data = @socket.read_nonblock(size, exception: false)
|
|
14
|
+
raise IO::EAGAINWaitReadable if wait_states.include? data
|
|
15
|
+
return nil if data.nil?
|
|
16
|
+
|
|
17
|
+
@engine.inject(data)
|
|
18
|
+
output = engine_read_all
|
|
19
|
+
|
|
20
|
+
return output if output
|
|
21
|
+
|
|
22
|
+
while (neg_data = @engine.extract)
|
|
23
|
+
@socket.write neg_data
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Capybara.register_server :default do |app, port, _host|
|
|
4
|
+
Capybara.run_default_server(app, port)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
Capybara.register_server :webrick do |app, port, host, **options|
|
|
8
|
+
base_class = begin
|
|
9
|
+
require 'rack/handler/webrick'
|
|
10
|
+
Rack
|
|
11
|
+
rescue LoadError
|
|
12
|
+
# Rack 3 separated out the webrick handle - no way test currently in Capybaras automated
|
|
13
|
+
# tests due to Sinatra not yet supporting Rack 3 - experimental
|
|
14
|
+
require 'rackup/handler/webrick'
|
|
15
|
+
Rackup
|
|
16
|
+
end
|
|
17
|
+
options = { Host: host, Port: port, AccessLog: [], Logger: WEBrick::Log.new(nil, 0) }.merge(options)
|
|
18
|
+
base_class::Handler::WEBrick.run(app, **options)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
Capybara.register_server :puma do |app, port, host, **options| # rubocop:disable Metrics/BlockLength
|
|
22
|
+
begin
|
|
23
|
+
require 'rackup'
|
|
24
|
+
rescue LoadError # rubocop:disable Lint/SuppressedException
|
|
25
|
+
end
|
|
26
|
+
begin
|
|
27
|
+
require 'rack/handler/puma'
|
|
28
|
+
rescue LoadError
|
|
29
|
+
raise LoadError, 'Capybara is unable to load `puma` for its server, please add `puma` to your project or specify a different server via something like `Capybara.server = :webrick`.'
|
|
30
|
+
end
|
|
31
|
+
puma_rack_handler = defined?(Rackup::Handler::Puma) ? Rackup::Handler::Puma : Rack::Handler::Puma
|
|
32
|
+
|
|
33
|
+
unless puma_rack_handler.respond_to?(:config)
|
|
34
|
+
raise LoadError, 'Capybara requires `puma` version 3.8.0 or higher, please upgrade `puma` or register and specify your own server block'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# If we just run the Puma Rack handler it installs signal handlers which prevent us from being able to interrupt tests.
|
|
38
|
+
# Therefore construct and run the Server instance ourselves.
|
|
39
|
+
# puma_rack_handler.run(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options))
|
|
40
|
+
default_options = { Host: host, Port: port, Threads: '0:4', workers: 0, daemon: false }
|
|
41
|
+
options = default_options.merge(options)
|
|
42
|
+
|
|
43
|
+
conf = puma_rack_handler.config(app, options)
|
|
44
|
+
conf.clamp
|
|
45
|
+
|
|
46
|
+
puma_ver = Gem::Version.new(Puma::Const::PUMA_VERSION)
|
|
47
|
+
require_relative 'patches/puma_ssl' if Gem::Requirement.new('>=4.0.0', '< 4.1.0').satisfied_by?(puma_ver)
|
|
48
|
+
|
|
49
|
+
logger = (defined?(Puma::LogWriter) ? Puma::LogWriter : Puma::Events).then do |cls|
|
|
50
|
+
conf.options[:Silent] ? cls.strings : cls.stdio
|
|
51
|
+
end
|
|
52
|
+
conf.options[:log_writer] = logger
|
|
53
|
+
|
|
54
|
+
logger.log 'Capybara starting Puma...'
|
|
55
|
+
logger.log "* Version #{Puma::Const::PUMA_VERSION}, codename: #{Puma::Const::CODE_NAME}"
|
|
56
|
+
logger.log "* Min threads: #{conf.options[:min_threads]}, max threads: #{conf.options[:max_threads]}"
|
|
57
|
+
|
|
58
|
+
Puma::Server.new(
|
|
59
|
+
conf.app,
|
|
60
|
+
defined?(Puma::LogWriter) ? nil : logger,
|
|
61
|
+
conf.options
|
|
62
|
+
).tap do |s|
|
|
63
|
+
s.binder.parse conf.options[:binds], (s.log_writer rescue s.events) # rubocop:disable Style/RescueModifier
|
|
64
|
+
s.min_threads, s.max_threads = conf.options[:min_threads], conf.options[:max_threads] if s.respond_to? :min_threads=
|
|
65
|
+
end.run.join
|
|
66
|
+
end
|
data/lib/capybara/result.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'forwardable'
|
|
3
4
|
|
|
4
5
|
module Capybara
|
|
5
|
-
|
|
6
6
|
##
|
|
7
7
|
# A {Capybara::Result} represents a collection of {Capybara::Node::Element} on the page. It is possible to interact with this
|
|
8
8
|
# collection similar to an Array because it implements Enumerable and offers the following Array methods through delegation:
|
|
9
9
|
#
|
|
10
|
-
# * []
|
|
10
|
+
# * \[\]
|
|
11
11
|
# * each()
|
|
12
12
|
# * at()
|
|
13
13
|
# * size()
|
|
@@ -16,6 +16,8 @@ module Capybara
|
|
|
16
16
|
# * first()
|
|
17
17
|
# * last()
|
|
18
18
|
# * empty?()
|
|
19
|
+
# * values_at()
|
|
20
|
+
# * sample()
|
|
19
21
|
#
|
|
20
22
|
# @see Capybara::Node::Element
|
|
21
23
|
#
|
|
@@ -26,35 +28,52 @@ module Capybara
|
|
|
26
28
|
def initialize(elements, query)
|
|
27
29
|
@elements = elements
|
|
28
30
|
@result_cache = []
|
|
29
|
-
@
|
|
31
|
+
@filter_errors = []
|
|
32
|
+
@results_enum = lazy_select_elements { |node| query.matches_filters?(node, @filter_errors) }
|
|
30
33
|
@query = query
|
|
34
|
+
@allow_reload = false
|
|
31
35
|
end
|
|
32
36
|
|
|
33
|
-
def_delegators :full_results, :size, :length, :last, :values_at, :inspect, :sample
|
|
37
|
+
def_delegators :full_results, :size, :length, :last, :values_at, :inspect, :sample, :to_ary
|
|
34
38
|
|
|
35
|
-
alias
|
|
39
|
+
alias index find_index
|
|
36
40
|
|
|
37
41
|
def each(&block)
|
|
38
|
-
return enum_for(:each) unless
|
|
42
|
+
return enum_for(:each) unless block
|
|
39
43
|
|
|
40
44
|
@result_cache.each(&block)
|
|
41
45
|
loop do
|
|
42
46
|
next_result = @results_enum.next
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
add_to_cache(next_result)
|
|
48
|
+
yield next_result
|
|
45
49
|
end
|
|
46
50
|
self
|
|
47
51
|
end
|
|
48
52
|
|
|
49
53
|
def [](*args)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
idx, length = args
|
|
55
|
+
max_idx = case idx
|
|
56
|
+
when Integer
|
|
57
|
+
if idx.negative?
|
|
58
|
+
nil
|
|
59
|
+
else
|
|
60
|
+
length.nil? ? idx : idx + length - 1
|
|
61
|
+
end
|
|
62
|
+
when Range
|
|
63
|
+
# idx.max is broken with beginless ranges
|
|
64
|
+
# idx.end && idx.max # endless range will have end == nil
|
|
65
|
+
max = idx.end
|
|
66
|
+
max = nil if max&.negative?
|
|
67
|
+
max -= 1 if max && idx.exclude_end?
|
|
68
|
+
max
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if max_idx.nil?
|
|
54
72
|
full_results[*args]
|
|
73
|
+
else
|
|
74
|
+
load_up_to(max_idx + 1)
|
|
75
|
+
@result_cache[*args]
|
|
55
76
|
end
|
|
56
|
-
rescue StopIteration
|
|
57
|
-
return nil
|
|
58
77
|
end
|
|
59
78
|
alias :at :[]
|
|
60
79
|
|
|
@@ -62,57 +81,47 @@ module Capybara
|
|
|
62
81
|
!any?
|
|
63
82
|
end
|
|
64
83
|
|
|
65
|
-
def
|
|
84
|
+
def compare_count
|
|
85
|
+
return 0 unless @query
|
|
86
|
+
|
|
87
|
+
count, min, max, between = @query.options.values_at(:count, :minimum, :maximum, :between)
|
|
88
|
+
|
|
66
89
|
# Only check filters for as many elements as necessary to determine result
|
|
67
|
-
if
|
|
68
|
-
|
|
69
|
-
loop do
|
|
70
|
-
break if @result_cache.size > count_opt
|
|
71
|
-
@result_cache << @results_enum.next
|
|
72
|
-
end
|
|
73
|
-
return @result_cache.size == count_opt
|
|
90
|
+
if count && (count = Integer(count))
|
|
91
|
+
return load_up_to(count + 1) <=> count
|
|
74
92
|
end
|
|
75
93
|
|
|
76
|
-
if
|
|
77
|
-
min_opt = Integer(@query.options[:minimum])
|
|
78
|
-
begin
|
|
79
|
-
@result_cache << @results_enum.next while @result_cache.size < min_opt
|
|
80
|
-
rescue StopIteration
|
|
81
|
-
return false
|
|
82
|
-
end
|
|
83
|
-
end
|
|
94
|
+
return -1 if min && (min = Integer(min)) && (load_up_to(min) < min)
|
|
84
95
|
|
|
85
|
-
if
|
|
86
|
-
max_opt = Integer(@query.options[:maximum])
|
|
87
|
-
begin
|
|
88
|
-
@result_cache << @results_enum.next while @result_cache.size <= max_opt
|
|
89
|
-
return false
|
|
90
|
-
rescue StopIteration
|
|
91
|
-
end
|
|
92
|
-
end
|
|
96
|
+
return 1 if max && (max = Integer(max)) && (load_up_to(max + 1) > max)
|
|
93
97
|
|
|
94
|
-
if
|
|
95
|
-
max =
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return false unless (@query.options[:between] === @result_cache.size)
|
|
98
|
+
if between
|
|
99
|
+
min, max = (between.begin && between.min) || 1, between.end
|
|
100
|
+
max -= 1 if max && between.exclude_end?
|
|
101
|
+
|
|
102
|
+
size = load_up_to(max ? max + 1 : min)
|
|
103
|
+
return size <=> min unless between.include?(size)
|
|
101
104
|
end
|
|
102
105
|
|
|
103
|
-
|
|
106
|
+
0
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def matches_count?
|
|
110
|
+
compare_count.zero?
|
|
104
111
|
end
|
|
105
112
|
|
|
106
113
|
def failure_message
|
|
107
114
|
message = @query.failure_message
|
|
108
|
-
if count
|
|
109
|
-
message <<
|
|
115
|
+
if count.zero?
|
|
116
|
+
message << ' but there were no matches'
|
|
110
117
|
else
|
|
111
|
-
message << "
|
|
118
|
+
message << ", found #{count} #{Capybara::Helpers.declension('match', 'matches', count)}: " \
|
|
119
|
+
<< full_results.map { |r| r.text.inspect }.join(', ')
|
|
112
120
|
end
|
|
113
121
|
unless rest.empty?
|
|
114
|
-
elements = rest.map
|
|
115
|
-
message <<
|
|
122
|
+
elements = rest.map { |el| el.text rescue '<<ERROR>>' }.map(&:inspect).join(', ') # rubocop:disable Style/RescueModifier
|
|
123
|
+
message << '. Also found ' << elements << ', which matched the selector but not all filters. '
|
|
124
|
+
message << @filter_errors.join('. ') if (rest.size == 1) && count.zero?
|
|
116
125
|
end
|
|
117
126
|
message
|
|
118
127
|
end
|
|
@@ -121,7 +130,33 @@ module Capybara
|
|
|
121
130
|
failure_message.sub(/(to find)/, 'not \1')
|
|
122
131
|
end
|
|
123
132
|
|
|
124
|
-
|
|
133
|
+
def unfiltered_size
|
|
134
|
+
@elements.length
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
##
|
|
138
|
+
# @api private
|
|
139
|
+
#
|
|
140
|
+
def allow_reload!
|
|
141
|
+
@allow_reload = true
|
|
142
|
+
self
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
private
|
|
146
|
+
|
|
147
|
+
def add_to_cache(elem)
|
|
148
|
+
elem.allow_reload!(@result_cache.size) if @allow_reload
|
|
149
|
+
@result_cache << elem
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def load_up_to(num)
|
|
153
|
+
loop do
|
|
154
|
+
break if @result_cache.size >= num
|
|
155
|
+
|
|
156
|
+
add_to_cache(@results_enum.next)
|
|
157
|
+
end
|
|
158
|
+
@result_cache.size
|
|
159
|
+
end
|
|
125
160
|
|
|
126
161
|
def full_results
|
|
127
162
|
loop { @result_cache << @results_enum.next }
|
|
@@ -132,20 +167,19 @@ module Capybara
|
|
|
132
167
|
@rest ||= @elements - full_results
|
|
133
168
|
end
|
|
134
169
|
|
|
135
|
-
|
|
136
|
-
# JRuby has an issue with lazy enumerators which
|
|
170
|
+
if RUBY_PLATFORM == 'java'
|
|
171
|
+
# JRuby < 9.2.8.0 has an issue with lazy enumerators which
|
|
137
172
|
# causes a concurrency issue with network requests here
|
|
138
173
|
# https://github.com/jruby/jruby/issues/4212
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
174
|
+
# while JRuby >= 9.2.8.0 leaks threads when using lazy enumerators
|
|
175
|
+
# https://github.com/teamcapybara/capybara/issues/2349
|
|
176
|
+
# so disable the use and JRuby users will need to pay a performance penalty
|
|
177
|
+
def lazy_select_elements(&block)
|
|
178
|
+
@elements.select(&block).to_enum # non-lazy evaluation
|
|
179
|
+
end
|
|
180
|
+
else
|
|
181
|
+
def lazy_select_elements(&block)
|
|
142
182
|
@elements.lazy.select(&block)
|
|
143
|
-
else
|
|
144
|
-
Enumerator.new do |yielder|
|
|
145
|
-
@elements.each do |val|
|
|
146
|
-
yielder.yield(val) if block.call(val)
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
183
|
end
|
|
150
184
|
end
|
|
151
185
|
end
|
|
@@ -1,56 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
if RSpec::Core::Version::STRING.to_f >= 3.0
|
|
3
|
-
RSpec.shared_context "Capybara Features", capybara_feature: true do
|
|
4
|
-
instance_eval do
|
|
5
|
-
alias background before
|
|
6
|
-
alias given let
|
|
7
|
-
alias given! let!
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
# ensure shared_context is included if default shared_context_metadata_behavior is changed
|
|
12
|
-
if RSpec::Core::Version::STRING.to_f >= 3.5
|
|
13
|
-
RSpec.configure do |config|
|
|
14
|
-
config.include_context "Capybara Features", capybara_feature: true
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
2
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
config.alias_example_to :xscenario, skip: "Temporarily disabled with xscenario"
|
|
24
|
-
config.alias_example_to :fscenario, focus: true
|
|
3
|
+
RSpec.shared_context 'Capybara Features', capybara_feature: true do
|
|
4
|
+
instance_eval do
|
|
5
|
+
alias background before
|
|
6
|
+
alias given let
|
|
7
|
+
alias given! let!
|
|
25
8
|
end
|
|
26
|
-
|
|
27
|
-
module Capybara
|
|
28
|
-
module Features
|
|
29
|
-
def self.included(base)
|
|
30
|
-
base.instance_eval do
|
|
31
|
-
alias :background :before
|
|
32
|
-
alias :scenario :it
|
|
33
|
-
alias :xscenario :xit
|
|
34
|
-
alias :given :let
|
|
35
|
-
alias :given! :let!
|
|
36
|
-
alias :feature :describe
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def self.feature(*args, &block)
|
|
43
|
-
options = if args.last.is_a?(Hash) then args.pop else {} end
|
|
44
|
-
options[:capybara_feature] = true
|
|
45
|
-
options[:type] = :feature
|
|
46
|
-
options[:caller] ||= caller
|
|
47
|
-
args.push(options)
|
|
9
|
+
end
|
|
48
10
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
11
|
+
# ensure shared_context is included if default shared_context_metadata_behavior is changed
|
|
12
|
+
RSpec.configure do |config|
|
|
13
|
+
config.include_context 'Capybara Features', capybara_feature: true if config.respond_to?(:include_context)
|
|
14
|
+
end
|
|
52
15
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
16
|
+
RSpec.configure do |config|
|
|
17
|
+
config.alias_example_group_to :feature, :capybara_feature, type: :feature
|
|
18
|
+
config.alias_example_group_to :xfeature, :capybara_feature, type: :feature, skip: 'Temporarily disabled with xfeature'
|
|
19
|
+
config.alias_example_group_to :ffeature, :capybara_feature, :focus, type: :feature
|
|
20
|
+
config.alias_example_to :scenario
|
|
21
|
+
config.alias_example_to :xscenario, skip: 'Temporarily disabled with xscenario'
|
|
22
|
+
config.alias_example_to :fscenario, :focus
|
|
56
23
|
end
|
|
@@ -1,45 +1,82 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
module Capybara
|
|
3
4
|
module RSpecMatcherProxies
|
|
4
|
-
def all(*args)
|
|
5
|
+
def all(*args, **kwargs, &block)
|
|
5
6
|
if defined?(::RSpec::Matchers::BuiltIn::All) && args.first.respond_to?(:matches?)
|
|
6
7
|
::RSpec::Matchers::BuiltIn::All.new(*args)
|
|
7
8
|
else
|
|
8
|
-
find_all(*args)
|
|
9
|
+
find_all(*args, **kwargs, &block)
|
|
9
10
|
end
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
def within(*args)
|
|
13
|
-
if
|
|
14
|
-
within_element(*args, &
|
|
13
|
+
def within(*args, **kwargs, &block)
|
|
14
|
+
if block
|
|
15
|
+
within_element(*args, **kwargs, &block)
|
|
15
16
|
else
|
|
16
17
|
be_within(*args)
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
end
|
|
21
|
+
end
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
if RUBY_ENGINE == 'jruby'
|
|
24
|
+
# :nocov:
|
|
25
|
+
module Capybara::DSL
|
|
26
|
+
class << self
|
|
23
27
|
remove_method :included
|
|
24
28
|
|
|
25
29
|
def included(base)
|
|
26
|
-
warn
|
|
27
|
-
|
|
30
|
+
warn 'including Capybara::DSL in the global scope is not recommended!' if base == Object
|
|
28
31
|
if defined?(::RSpec::Matchers) && base.include?(::RSpec::Matchers)
|
|
29
32
|
base.send(:include, ::Capybara::RSpecMatcherProxies)
|
|
30
33
|
end
|
|
34
|
+
super
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
31
38
|
|
|
39
|
+
if defined?(RSpec::Matchers)
|
|
40
|
+
module ::RSpec::Matchers
|
|
41
|
+
def self.included(base)
|
|
42
|
+
base.send(:include, ::Capybara::RSpecMatcherProxies) if base.include?(::Capybara::DSL)
|
|
32
43
|
super
|
|
33
44
|
end
|
|
34
45
|
end
|
|
35
46
|
end
|
|
36
|
-
|
|
47
|
+
# :nocov:
|
|
48
|
+
else
|
|
49
|
+
module Capybara::DSLRSpecProxyInstaller
|
|
50
|
+
module ClassMethods
|
|
51
|
+
def included(base)
|
|
52
|
+
base.include(::Capybara::RSpecMatcherProxies) if defined?(::RSpec::Matchers) && base.include?(::RSpec::Matchers)
|
|
53
|
+
super
|
|
54
|
+
end
|
|
55
|
+
end
|
|
37
56
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
57
|
+
def self.prepended(base)
|
|
58
|
+
class << base
|
|
59
|
+
prepend ClassMethods
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
module Capybara::RSpecMatcherProxyInstaller
|
|
65
|
+
module ClassMethods
|
|
66
|
+
def included(base)
|
|
67
|
+
base.include(::Capybara::RSpecMatcherProxies) if base.include?(::Capybara::DSL)
|
|
68
|
+
super
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def self.prepended(base)
|
|
73
|
+
class << base
|
|
74
|
+
prepend ClassMethods
|
|
75
|
+
end
|
|
43
76
|
end
|
|
44
77
|
end
|
|
78
|
+
|
|
79
|
+
Capybara::DSL.prepend Capybara::DSLRSpecProxyInstaller
|
|
80
|
+
|
|
81
|
+
RSpec::Matchers.prepend Capybara::RSpecMatcherProxyInstaller if defined?(RSpec::Matchers)
|
|
45
82
|
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'capybara/rspec/matchers/compound'
|
|
4
|
+
require 'capybara/rspec/matchers/count_sugar'
|
|
5
|
+
require 'capybara/rspec/matchers/spatial_sugar'
|
|
6
|
+
|
|
7
|
+
module Capybara
|
|
8
|
+
module RSpecMatchers
|
|
9
|
+
module Matchers
|
|
10
|
+
class Base
|
|
11
|
+
include ::Capybara::RSpecMatchers::Matchers::Compound if defined?(::Capybara::RSpecMatchers::Matchers::Compound)
|
|
12
|
+
|
|
13
|
+
attr_reader :failure_message, :failure_message_when_negated
|
|
14
|
+
|
|
15
|
+
def initialize(*args, **kw_args, &filter_block)
|
|
16
|
+
@args = args.dup
|
|
17
|
+
@kw_args = kw_args || {}
|
|
18
|
+
@filter_block = filter_block
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def session_query_args
|
|
24
|
+
# if @args.last.is_a? Hash
|
|
25
|
+
# @args.last[:session_options] = session_options
|
|
26
|
+
# else
|
|
27
|
+
# @args.push(session_options: session_options)
|
|
28
|
+
# end
|
|
29
|
+
@args
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def session_query_options
|
|
33
|
+
@kw_args[:session_options] = session_options
|
|
34
|
+
@kw_args
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def session_options
|
|
38
|
+
@context_el ||= nil
|
|
39
|
+
if @context_el.respond_to? :session_options
|
|
40
|
+
@context_el.session_options
|
|
41
|
+
elsif @context_el.respond_to? :current_scope
|
|
42
|
+
@context_el.current_scope.session_options
|
|
43
|
+
else
|
|
44
|
+
Capybara.session_options
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class WrappedElementMatcher < Base
|
|
50
|
+
def matches?(actual, &filter_block)
|
|
51
|
+
@filter_block ||= filter_block
|
|
52
|
+
element_matches?(wrap(actual))
|
|
53
|
+
rescue Capybara::ExpectationNotMet => e
|
|
54
|
+
@failure_message = e.message
|
|
55
|
+
false
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def does_not_match?(actual, &filter_block)
|
|
59
|
+
@filter_block ||= filter_block
|
|
60
|
+
element_does_not_match?(wrap(actual))
|
|
61
|
+
rescue Capybara::ExpectationNotMet => e
|
|
62
|
+
@failure_message_when_negated = e.message
|
|
63
|
+
false
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def wrap(actual)
|
|
69
|
+
actual = actual.to_capybara_node if actual.respond_to?(:to_capybara_node)
|
|
70
|
+
@context_el = if actual.respond_to?(:has_selector?)
|
|
71
|
+
actual
|
|
72
|
+
else
|
|
73
|
+
Capybara.string(actual.to_s)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
class CountableWrappedElementMatcher < WrappedElementMatcher
|
|
79
|
+
include ::Capybara::RSpecMatchers::CountSugar
|
|
80
|
+
include ::Capybara::RSpecMatchers::SpatialSugar
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
class NegatedMatcher
|
|
84
|
+
include ::Capybara::RSpecMatchers::Matchers::Compound if defined?(::Capybara::RSpecMatchers::Matchers::Compound)
|
|
85
|
+
|
|
86
|
+
def initialize(matcher)
|
|
87
|
+
super()
|
|
88
|
+
@matcher = matcher
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def matches?(actual, &filter_block)
|
|
92
|
+
@matcher.does_not_match?(actual, &filter_block)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def does_not_match?(actual, &filter_block)
|
|
96
|
+
@matcher.matches?(actual, &filter_block)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def description
|
|
100
|
+
"not #{@matcher.description}"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def failure_message
|
|
104
|
+
@matcher.failure_message_when_negated
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def failure_message_when_negated
|
|
108
|
+
@matcher.failure_message
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Capybara
|
|
4
|
+
module RSpecMatchers
|
|
5
|
+
module Matchers
|
|
6
|
+
class BecomeClosed
|
|
7
|
+
def initialize(options)
|
|
8
|
+
@options = options
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def matches?(window)
|
|
12
|
+
@window = window
|
|
13
|
+
@wait_time = Capybara::Queries::BaseQuery.wait(@options, window.session.config.default_max_wait_time)
|
|
14
|
+
timer = Capybara::Helpers.timer(expire_in: @wait_time)
|
|
15
|
+
while window.exists?
|
|
16
|
+
return false if timer.expired?
|
|
17
|
+
|
|
18
|
+
sleep 0.01
|
|
19
|
+
end
|
|
20
|
+
true
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def failure_message
|
|
24
|
+
"expected #{@window.inspect} to become closed after #{@wait_time} seconds"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def failure_message_when_negated
|
|
28
|
+
"expected #{@window.inspect} not to become closed after #{@wait_time} seconds"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|