capybara 2.18.0 → 3.38.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -1
- data/History.md +889 -12
- data/License.txt +1 -1
- data/README.md +108 -78
- 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 +173 -83
- data/lib/capybara/minitest.rb +219 -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 +149 -137
- data/lib/capybara/node/matchers.rb +369 -209
- data/lib/capybara/node/simple.rb +59 -26
- 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 +658 -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 +113 -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 +188 -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 +53 -0
- data/lib/capybara/result.rb +96 -62
- data/lib/capybara/rspec/features.rb +17 -50
- data/lib/capybara/rspec/matcher_proxies.rb +52 -15
- data/lib/capybara/rspec/matchers/base.rb +111 -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 +77 -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 +142 -311
- 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 +89 -17
- 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 +54 -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 +227 -526
- 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 +332 -261
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +124 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +89 -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 +226 -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/logger_suppressor.rb +44 -0
- data/lib/capybara/selenium/node.rb +545 -144
- data/lib/capybara/selenium/nodes/chrome_node.rb +137 -0
- data/lib/capybara/selenium/nodes/edge_node.rb +104 -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/action_pauser.rb +26 -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 +81 -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 +336 -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 +147 -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 +160 -56
- 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 +82 -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 +36 -17
- data/lib/capybara/spec/session/find_spec.rb +251 -144
- data/lib/capybara/spec/session/first_spec.rb +79 -51
- 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 +50 -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 +59 -60
- data/lib/capybara/spec/session/has_field_spec.rb +139 -59
- data/lib/capybara/spec/session/has_link_spec.rb +43 -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 +172 -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 +35 -0
- data/lib/capybara/spec/session/node_spec.rb +1002 -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 +117 -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 +42 -22
- 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 +53 -43
- 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 +154 -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 +67 -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 +129 -103
- 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 +45 -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 +102 -50
- data/spec/rspec/features_spec.rb +37 -31
- data/spec/rspec/scenarios_spec.rb +9 -7
- data/spec/rspec/shared_spec_matchers.rb +449 -422
- data/spec/rspec/views_spec.rb +5 -3
- data/spec/rspec_matchers_spec.rb +27 -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 +186 -40
- data/spec/selenium_spec_chrome_remote.rb +103 -0
- data/spec/selenium_spec_edge.rb +49 -0
- data/spec/selenium_spec_firefox.rb +194 -41
- data/spec/selenium_spec_firefox_remote.rb +82 -0
- data/spec/selenium_spec_ie.rb +149 -0
- data/spec/selenium_spec_safari.rb +162 -0
- data/spec/server_spec.rb +201 -102
- data/spec/session_spec.rb +53 -16
- data/spec/shared_selenium_node.rb +79 -0
- data/spec/shared_selenium_session.rb +474 -122
- data/spec/spec_helper.rb +93 -7
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +360 -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
data/lib/capybara/window.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Capybara
|
3
4
|
##
|
4
|
-
# The Window class represents a browser window.
|
5
|
+
# The {Window} class represents a browser window.
|
5
6
|
#
|
6
|
-
# You can get an instance of the class by calling
|
7
|
+
# You can get an instance of the class by calling any of:
|
7
8
|
#
|
8
9
|
# * {Capybara::Session#windows}
|
9
10
|
# * {Capybara::Session#current_window}
|
@@ -11,12 +12,12 @@ module Capybara
|
|
11
12
|
# * {Capybara::Session#switch_to_window}
|
12
13
|
#
|
13
14
|
# Note that some drivers (e.g. Selenium) support getting size of/resizing/closing only
|
14
|
-
#
|
15
|
+
# current window. So if you invoke such method for:
|
15
16
|
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
17
|
+
# * window that is current, Capybara will make 2 Selenium method invocations
|
18
|
+
# (get handle of current window + get size/resize/close).
|
19
|
+
# * window that is not current, Capybara will make 4 Selenium method invocations
|
20
|
+
# (get handle of current window + switch to given handle + get size/resize/close + switch to original handle)
|
20
21
|
#
|
21
22
|
class Window
|
22
23
|
# @return [String] a string that uniquely identifies window within session
|
@@ -56,12 +57,12 @@ module Capybara
|
|
56
57
|
# Close window.
|
57
58
|
#
|
58
59
|
# If this method was called for window that is current, then after calling this method
|
59
|
-
#
|
60
|
-
#
|
60
|
+
# future invocations of other Capybara methods should raise
|
61
|
+
# {Capybara::Driver::Base#no_such_window_error session.driver.no_such_window_error} until another window will be switched to.
|
61
62
|
#
|
62
63
|
# @!macro about_current
|
63
64
|
# If this method was called for window that is not current, then after calling this method
|
64
|
-
# current window
|
65
|
+
# current window should remain the same as it was before calling this method.
|
65
66
|
#
|
66
67
|
def close
|
67
68
|
@driver.close_window(handle)
|
@@ -81,8 +82,8 @@ module Capybara
|
|
81
82
|
# Resize window.
|
82
83
|
#
|
83
84
|
# @macro about_current
|
84
|
-
# @param width [
|
85
|
-
# @param height [
|
85
|
+
# @param width [Integer] the new window width in pixels
|
86
|
+
# @param height [Integer] the new window height in pixels
|
86
87
|
#
|
87
88
|
def resize_to(width, height)
|
88
89
|
wait_for_stable_size { @driver.resize_window_to(handle, width, height) }
|
@@ -92,7 +93,7 @@ module Capybara
|
|
92
93
|
# Maximize window.
|
93
94
|
#
|
94
95
|
# If a particular driver (e.g. headless driver) doesn't have concept of maximizing it
|
95
|
-
#
|
96
|
+
# may not support this method.
|
96
97
|
#
|
97
98
|
# @macro about_current
|
98
99
|
#
|
@@ -100,41 +101,42 @@ module Capybara
|
|
100
101
|
wait_for_stable_size { @driver.maximize_window(handle) }
|
101
102
|
end
|
102
103
|
|
104
|
+
##
|
105
|
+
# Fullscreen window.
|
106
|
+
#
|
107
|
+
# If a particular driver doesn't have concept of fullscreen it may not support this method.
|
108
|
+
#
|
109
|
+
# @macro about_current
|
110
|
+
#
|
111
|
+
def fullscreen
|
112
|
+
@driver.fullscreen_window(handle)
|
113
|
+
end
|
114
|
+
|
103
115
|
def eql?(other)
|
104
|
-
other.
|
116
|
+
other.is_a?(self.class) && @session == other.session && @handle == other.handle
|
105
117
|
end
|
106
118
|
alias_method :==, :eql?
|
107
119
|
|
108
120
|
def hash
|
109
|
-
@session
|
121
|
+
[@session, @handle].hash
|
110
122
|
end
|
111
123
|
|
112
124
|
def inspect
|
113
125
|
"#<Window @handle=#{@handle.inspect}>"
|
114
126
|
end
|
115
127
|
|
116
|
-
|
128
|
+
private
|
117
129
|
|
118
|
-
def wait_for_stable_size(seconds=session.config.default_max_wait_time)
|
130
|
+
def wait_for_stable_size(seconds = session.config.default_max_wait_time)
|
119
131
|
res = yield if block_given?
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
sleep 0.
|
124
|
-
|
125
|
-
|
126
|
-
prev_size = cur_size
|
127
|
-
end while (Capybara::Helpers.monotonic_time - start_time) < seconds
|
128
|
-
#TODO raise error in 3.0
|
129
|
-
#raise Capybara::WindowError, "Window size not stable."
|
130
|
-
warn "Window size not stable in #{seconds} seconds. This will raise an exception in a future version of Capybara"
|
131
|
-
return res
|
132
|
-
end
|
133
|
-
|
134
|
-
def raise_unless_current(what)
|
135
|
-
unless current?
|
136
|
-
raise Capybara::WindowError, "#{what} not current window is not possible."
|
132
|
+
timer = Capybara::Helpers.timer(expire_in: seconds)
|
133
|
+
loop do
|
134
|
+
prev_size = size
|
135
|
+
sleep 0.025
|
136
|
+
return res if prev_size == size
|
137
|
+
break if timer.expired?
|
137
138
|
end
|
139
|
+
raise Capybara::WindowError, "Window size not stable within #{seconds} seconds."
|
138
140
|
end
|
139
141
|
end
|
140
142
|
end
|
data/lib/capybara.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'timeout'
|
3
4
|
require 'nokogiri'
|
4
5
|
require 'xpath'
|
5
6
|
require 'forwardable'
|
6
7
|
require 'capybara/config'
|
8
|
+
require 'capybara/registration_container'
|
7
9
|
|
8
10
|
module Capybara
|
9
11
|
class CapybaraError < StandardError; end
|
@@ -21,7 +23,6 @@ module Capybara
|
|
21
23
|
class WindowError < CapybaraError; end
|
22
24
|
class ReadOnlyElementError < CapybaraError; end
|
23
25
|
|
24
|
-
|
25
26
|
class << self
|
26
27
|
extend Forwardable
|
27
28
|
|
@@ -38,6 +39,8 @@ module Capybara
|
|
38
39
|
# See {Capybara.configure}
|
39
40
|
# @!method javascript_driver
|
40
41
|
# See {Capybara.configure}
|
42
|
+
# @!method use_html5_parsing
|
43
|
+
# See {Capybara.configure}
|
41
44
|
Config::OPTIONS.each do |method|
|
42
45
|
def_delegators :config, method, "#{method}="
|
43
46
|
end
|
@@ -51,8 +54,6 @@ module Capybara
|
|
51
54
|
# See {Capybara.configure}
|
52
55
|
# @!method always_include_port
|
53
56
|
# See {Capybara.configure}
|
54
|
-
# @!method wait_on_first_by_default
|
55
|
-
# See {Capybara.configure}
|
56
57
|
SessionConfig::OPTIONS.each do |method|
|
57
58
|
def_delegators :config, method, "#{method}="
|
58
59
|
end
|
@@ -66,35 +67,52 @@ module Capybara
|
|
66
67
|
# config.app_host = 'http://www.google.com'
|
67
68
|
# end
|
68
69
|
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
70
|
+
# #### Configurable options
|
71
|
+
#
|
72
|
+
# - **use_html5_parsing** (Boolean = `false`) - When Nokogiri >= 1.12.0 or `nokogumbo` is installed, whether HTML5 parsing will be used for HTML strings.
|
73
|
+
# - **always_include_port** (Boolean = `false`) - Whether the Rack server's port should automatically be inserted into every visited URL
|
74
|
+
# unless another port is explicitly specified.
|
75
|
+
# - **app_host** (String, `nil`) - The default host to use when giving a relative URL to visit, must be a valid URL e.g. `http://www.example.com`.
|
76
|
+
# - **asset_host** (String = `nil`) - Where dynamic assets are hosted - will be prepended to relative asset locations if present.
|
77
|
+
# - **automatic_label_click** (Boolean = `false`) - Whether {Capybara::Node::Element#choose Element#choose}, {Capybara::Node::Element#check Element#check},
|
78
|
+
# {Capybara::Node::Element#uncheck Element#uncheck} will attempt to click the associated `<label>` element if the checkbox/radio button are non-visible.
|
79
|
+
# - **automatic_reload** (Boolean = `true`) - Whether to automatically reload elements as Capybara is waiting.
|
80
|
+
# - **default_max_wait_time** (Numeric = `2`) - The maximum number of seconds to wait for asynchronous processes to finish.
|
81
|
+
# - **default_normalize_ws** (Boolean = `false`) - Whether text predicates and matchers use normalize whitespace behavior.
|
82
|
+
# - **default_retry_interval** (Numeric = `0.01`) - The number of seconds to delay the next check in asynchronous processes.
|
83
|
+
# - **default_selector** (`:css`, `:xpath` = `:css`) - Methods which take a selector use the given type by default. See also {Capybara::Selector}.
|
84
|
+
# - **default_set_options** (Hash = `{}`) - The default options passed to {Capybara::Node::Element#set Element#set}.
|
85
|
+
# - **enable_aria_label** (Boolean = `false`) - Whether fields, links, and buttons will match against `aria-label` attribute.
|
86
|
+
# - **enable_aria_role** (Boolean = `false`) - Selectors will check for relevant aria role (currently only `button`).
|
87
|
+
# - **exact** (Boolean = `false`) - Whether locators are matched exactly or with substrings. Only affects selector conditions
|
88
|
+
# written using the `XPath#is` method.
|
89
|
+
# - **exact_text** (Boolean = `false`) - Whether the text matchers and `:text` filter match exactly or on substrings.
|
90
|
+
# - **ignore_hidden_elements** (Boolean = `true`) - Whether to ignore hidden elements on the page.
|
91
|
+
# - **match** (`:one`, `:first`, `:prefer_exact`, `:smart` = `:smart`) - The matching strategy to find nodes.
|
92
|
+
# - **predicates_wait** (Boolean = `true`) - Whether Capybara's predicate matchers use waiting behavior by default.
|
93
|
+
# - **raise_server_errors** (Boolean = `true`) - Should errors raised in the server be raised in the tests?
|
94
|
+
# - **reuse_server** (Boolean = `true`) - Whether to reuse the server thread between multiple sessions using the same app object.
|
95
|
+
# - **run_server** (Boolean = `true`) - Whether to start a Rack server for the given Rack app.
|
96
|
+
# - **save_path** (String = `Dir.pwd`) - Where to put pages saved through {Capybara::Session#save_page save_page}, {Capybara::Session#save_screenshot save_screenshot},
|
97
|
+
# {Capybara::Session#save_and_open_page save_and_open_page}, or {Capybara::Session#save_and_open_screenshot save_and_open_screenshot}.
|
98
|
+
# - **server** (Symbol = `:default` (which uses puma)) - The name of the registered server to use when running the app under test.
|
99
|
+
# - **server_port** (Integer) - The port Capybara will run the application server on, if not specified a random port will be used.
|
100
|
+
# - **server_host** (String = "127.0.0.1") - The IP address Capybara will bind the application server to. If the test application is to be accessed from an external host, you will want to change this to "0.0.0.0" or to a more specific IP address that your test client can reach.
|
101
|
+
# - **server_errors** (Array\<Class> = `[Exception]`) - Error classes that should be raised in the tests if they are raised in the server
|
102
|
+
# and {configure raise_server_errors} is `true`.
|
103
|
+
# - **test_id** (Symbol, String, `nil` = `nil`) - Optional attribute to match locator against with built-in selectors along with id.
|
104
|
+
# - **threadsafe** (Boolean = `false`) - Whether sessions can be configured individually.
|
105
|
+
# - **w3c_click_offset** (Boolean = 'true') - Whether click offsets should be from element center (true) or top left (false)
|
106
|
+
#
|
107
|
+
# #### DSL Options
|
108
|
+
#
|
109
|
+
# When using `capybara/dsl`, the following options are also available:
|
110
|
+
#
|
111
|
+
# - **default_driver** (Symbol = `:rack_test`) - The name of the driver to use by default.
|
112
|
+
# - **javascript_driver** (Symbol = `:selenium`) - The name of a driver to use for JavaScript enabled tests.
|
95
113
|
#
|
96
114
|
def configure
|
97
|
-
yield
|
115
|
+
yield config
|
98
116
|
end
|
99
117
|
|
100
118
|
##
|
@@ -111,7 +129,7 @@ module Capybara
|
|
111
129
|
# @yieldreturn [Capybara::Driver::Base] A Capybara driver instance
|
112
130
|
#
|
113
131
|
def register_driver(name, &block)
|
114
|
-
drivers
|
132
|
+
drivers.send(:register, name, block)
|
115
133
|
end
|
116
134
|
|
117
135
|
##
|
@@ -128,10 +146,9 @@ module Capybara
|
|
128
146
|
# @yieldparam [<Rack>] app The rack application that this server will contain.
|
129
147
|
# @yieldparam port The port number the server should listen on
|
130
148
|
# @yieldparam host The host/ip to bind to
|
131
|
-
# @yieldreturn [Capybara::Driver::Base] A Capybara driver instance
|
132
149
|
#
|
133
150
|
def register_server(name, &block)
|
134
|
-
servers
|
151
|
+
servers.send(:register, name.to_sym, block)
|
135
152
|
end
|
136
153
|
|
137
154
|
##
|
@@ -162,8 +179,8 @@ module Capybara
|
|
162
179
|
# @param [Symbol] name The name of the selector to add
|
163
180
|
# @yield A block executed in the context of the new {Capybara::Selector}
|
164
181
|
#
|
165
|
-
def add_selector(name, &block)
|
166
|
-
Capybara::Selector.add(name, &block)
|
182
|
+
def add_selector(name, **options, &block)
|
183
|
+
Capybara::Selector.add(name, **options, &block)
|
167
184
|
end
|
168
185
|
|
169
186
|
##
|
@@ -173,7 +190,7 @@ module Capybara
|
|
173
190
|
# button style (a class) might look like this
|
174
191
|
#
|
175
192
|
# Capybara.modify_selector(:button) do
|
176
|
-
# filter (:
|
193
|
+
# filter (:btn_style, valid_values: [:primary, :secondary]) { |node, style| node[:class].split.include? "btn-#{style}" }
|
177
194
|
# end
|
178
195
|
#
|
179
196
|
#
|
@@ -185,30 +202,26 @@ module Capybara
|
|
185
202
|
end
|
186
203
|
|
187
204
|
def drivers
|
188
|
-
@drivers ||=
|
205
|
+
@drivers ||= RegistrationContainer.new
|
189
206
|
end
|
190
207
|
|
191
208
|
def servers
|
192
|
-
@servers ||=
|
209
|
+
@servers ||= RegistrationContainer.new
|
193
210
|
end
|
194
211
|
|
195
|
-
##
|
196
|
-
#
|
197
212
|
# Wraps the given string, which should contain an HTML document or fragment
|
198
213
|
# in a {Capybara::Node::Simple} which exposes all {Capybara::Node::Matchers},
|
199
214
|
# {Capybara::Node::Finders} and {Capybara::Node::DocumentMatchers}. This allows you to query
|
200
215
|
# any string containing HTML in the exact same way you would query the current document in a Capybara
|
201
216
|
# session.
|
202
217
|
#
|
203
|
-
#
|
204
|
-
#
|
218
|
+
# @example A single element
|
205
219
|
# node = Capybara.string('<a href="foo">bar</a>')
|
206
220
|
# anchor = node.first('a')
|
207
221
|
# anchor[:href] #=> 'foo'
|
208
222
|
# anchor.text #=> 'bar'
|
209
223
|
#
|
210
|
-
#
|
211
|
-
#
|
224
|
+
# @example Multiple elements
|
212
225
|
# node = Capybara.string <<-HTML
|
213
226
|
# <ul>
|
214
227
|
# <li id="home">Home</li>
|
@@ -238,7 +251,7 @@ module Capybara
|
|
238
251
|
# @param [Integer] port The port to run the application on
|
239
252
|
#
|
240
253
|
def run_default_server(app, port)
|
241
|
-
servers[:
|
254
|
+
servers[:puma].call(app, port, server_host)
|
242
255
|
end
|
243
256
|
|
244
257
|
##
|
@@ -296,12 +309,12 @@ module Capybara
|
|
296
309
|
|
297
310
|
##
|
298
311
|
#
|
299
|
-
# The current Capybara::Session based on what is set as
|
312
|
+
# The current {Capybara::Session} based on what is set as {app} and {current_driver}.
|
300
313
|
#
|
301
314
|
# @return [Capybara::Session] The currently used session
|
302
315
|
#
|
303
316
|
def current_session
|
304
|
-
session_pool["#{current_driver}:#{session_name}:#{app.object_id}"]
|
317
|
+
specified_session || session_pool["#{current_driver}:#{session_name}:#{app.object_id}"]
|
305
318
|
end
|
306
319
|
|
307
320
|
##
|
@@ -310,7 +323,7 @@ module Capybara
|
|
310
323
|
# as cookies.
|
311
324
|
#
|
312
325
|
def reset_sessions!
|
313
|
-
#reset in reverse so sessions that started servers are reset last
|
326
|
+
# reset in reverse so sessions that started servers are reset last
|
314
327
|
session_pool.reverse_each { |_mode, session| session.reset! }
|
315
328
|
end
|
316
329
|
alias_method :reset!, :reset_sessions!
|
@@ -339,22 +352,31 @@ module Capybara
|
|
339
352
|
|
340
353
|
##
|
341
354
|
#
|
342
|
-
# Yield a block using a specific session name.
|
355
|
+
# Yield a block using a specific session name or {Capybara::Session} instance.
|
343
356
|
#
|
344
|
-
def using_session(
|
357
|
+
def using_session(name_or_session, &block)
|
358
|
+
previous_session = current_session
|
345
359
|
previous_session_info = {
|
360
|
+
specified_session: specified_session,
|
346
361
|
session_name: session_name,
|
347
362
|
current_driver: current_driver,
|
348
363
|
app: app
|
349
364
|
}
|
350
|
-
self.session_name =
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
365
|
+
self.specified_session = self.session_name = nil
|
366
|
+
if name_or_session.is_a? Capybara::Session
|
367
|
+
self.specified_session = name_or_session
|
368
|
+
else
|
369
|
+
self.session_name = name_or_session
|
370
|
+
end
|
371
|
+
|
372
|
+
if block.arity.zero?
|
373
|
+
yield
|
374
|
+
else
|
375
|
+
yield current_session, previous_session
|
357
376
|
end
|
377
|
+
ensure
|
378
|
+
self.session_name, self.specified_session = previous_session_info.values_at(:session_name, :specified_session)
|
379
|
+
self.current_driver, self.app = previous_session_info.values_at(:current_driver, :app) if threadsafe
|
358
380
|
end
|
359
381
|
|
360
382
|
##
|
@@ -364,10 +386,22 @@ module Capybara
|
|
364
386
|
# @param [String] html The raw html
|
365
387
|
# @return [Nokogiri::HTML::Document] HTML document
|
366
388
|
#
|
367
|
-
def HTML(html)
|
368
|
-
Nokogiri
|
389
|
+
def HTML(html) # rubocop:disable Naming/MethodName
|
390
|
+
# Nokogiri >= 1.12.0 or Nokogumbo installed and allowed for use
|
391
|
+
html_parser, using_html5 = if defined?(Nokogiri::HTML5) && Capybara.use_html5_parsing
|
392
|
+
[Nokogiri::HTML5, true]
|
393
|
+
else
|
394
|
+
[defined?(Nokogiri::HTML4) ? Nokogiri::HTML4 : Nokogiri::HTML, false]
|
395
|
+
end
|
396
|
+
|
397
|
+
html_parser.parse(html).tap do |document|
|
398
|
+
document.xpath('//template').each do |template|
|
399
|
+
# template elements content is not part of the document
|
400
|
+
template.inner_html = ''
|
401
|
+
end
|
369
402
|
document.xpath('//textarea').each do |textarea|
|
370
|
-
|
403
|
+
# The Nokogiri HTML5 parser already returns spec compliant contents
|
404
|
+
textarea['_capybara_raw_value'] = using_html5 ? textarea.content : textarea.content.delete_prefix("\n")
|
371
405
|
end
|
372
406
|
end
|
373
407
|
end
|
@@ -376,18 +410,32 @@ module Capybara
|
|
376
410
|
config.session_options
|
377
411
|
end
|
378
412
|
|
379
|
-
def included(base)
|
380
|
-
base.send(:include, Capybara::DSL)
|
381
|
-
warn "`include Capybara` is deprecated. Please use `include Capybara::DSL` instead."
|
382
|
-
end
|
383
|
-
|
384
413
|
private
|
414
|
+
|
385
415
|
def config
|
386
416
|
@config ||= Capybara::Config.new
|
387
417
|
end
|
388
418
|
|
389
419
|
def session_pool
|
390
|
-
@session_pool ||=
|
420
|
+
@session_pool ||= Hash.new do |hash, name|
|
421
|
+
hash[name] = Capybara::Session.new(current_driver, app)
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
def specified_session
|
426
|
+
if threadsafe
|
427
|
+
Thread.current['capybara_specified_session']
|
428
|
+
else
|
429
|
+
@specified_session ||= nil
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
def specified_session=(session)
|
434
|
+
if threadsafe
|
435
|
+
Thread.current['capybara_specified_session'] = session
|
436
|
+
else
|
437
|
+
@specified_session = session
|
438
|
+
end
|
391
439
|
end
|
392
440
|
end
|
393
441
|
|
@@ -415,7 +463,8 @@ module Capybara
|
|
415
463
|
require 'capybara/queries/match_query'
|
416
464
|
require 'capybara/queries/ancestor_query'
|
417
465
|
require 'capybara/queries/sibling_query'
|
418
|
-
require 'capybara/
|
466
|
+
require 'capybara/queries/style_query'
|
467
|
+
require 'capybara/queries/active_element_query'
|
419
468
|
|
420
469
|
require 'capybara/node/finders'
|
421
470
|
require 'capybara/node/matchers'
|
@@ -433,25 +482,14 @@ module Capybara
|
|
433
482
|
require 'capybara/rack_test/node'
|
434
483
|
require 'capybara/rack_test/form'
|
435
484
|
require 'capybara/rack_test/browser'
|
436
|
-
require 'capybara/rack_test/css_handlers
|
485
|
+
require 'capybara/rack_test/css_handlers'
|
437
486
|
|
438
487
|
require 'capybara/selenium/node'
|
439
488
|
require 'capybara/selenium/driver'
|
440
489
|
end
|
441
490
|
|
442
|
-
|
443
|
-
|
444
|
-
end
|
445
|
-
|
446
|
-
Capybara.register_server :webrick do |app, port, host, options={}|
|
447
|
-
require 'rack/handler/webrick'
|
448
|
-
Rack::Handler::WEBrick.run(app, {Host: host, Port: port, AccessLog: [], Logger: WEBrick::Log::new(nil, 0)}.merge(options))
|
449
|
-
end
|
450
|
-
|
451
|
-
Capybara.register_server :puma do |app, port, host, options={}|
|
452
|
-
require 'rack/handler/puma'
|
453
|
-
Rack::Handler::Puma.run(app, {Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false}.merge(options))
|
454
|
-
end
|
491
|
+
require 'capybara/registrations/servers'
|
492
|
+
require 'capybara/registrations/drivers'
|
455
493
|
|
456
494
|
Capybara.configure do |config|
|
457
495
|
config.always_include_port = false
|
@@ -459,36 +497,24 @@ Capybara.configure do |config|
|
|
459
497
|
config.server = :default
|
460
498
|
config.default_selector = :css
|
461
499
|
config.default_max_wait_time = 2
|
500
|
+
config.default_retry_interval = 0.01
|
462
501
|
config.ignore_hidden_elements = true
|
463
|
-
config.default_host =
|
502
|
+
config.default_host = 'http://www.example.com'
|
464
503
|
config.automatic_reload = true
|
465
504
|
config.match = :smart
|
466
505
|
config.exact = false
|
467
506
|
config.exact_text = false
|
468
507
|
config.raise_server_errors = true
|
469
|
-
config.server_errors = [
|
508
|
+
config.server_errors = [Exception]
|
470
509
|
config.visible_text_only = false
|
471
|
-
config.wait_on_first_by_default = false
|
472
510
|
config.automatic_label_click = false
|
473
511
|
config.enable_aria_label = false
|
512
|
+
config.enable_aria_role = false
|
474
513
|
config.reuse_server = true
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
Capybara.register_driver :selenium do |app|
|
482
|
-
Capybara::Selenium::Driver.new(app)
|
483
|
-
end
|
484
|
-
|
485
|
-
Capybara.register_driver :selenium_chrome do |app|
|
486
|
-
Capybara::Selenium::Driver.new(app, :browser => :chrome)
|
487
|
-
end
|
488
|
-
|
489
|
-
Capybara.register_driver :selenium_chrome_headless do |app|
|
490
|
-
browser_options = ::Selenium::WebDriver::Chrome::Options.new()
|
491
|
-
browser_options.args << '--headless'
|
492
|
-
browser_options.args << '--disable-gpu'
|
493
|
-
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
|
514
|
+
config.default_set_options = {}
|
515
|
+
config.test_id = nil
|
516
|
+
config.predicates_wait = true
|
517
|
+
config.default_normalize_ws = false
|
518
|
+
config.use_html5_parsing = false
|
519
|
+
config.w3c_click_offset = true
|
494
520
|
end
|