capybara 3.0.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 +891 -12
- data/License.txt +1 -1
- data/README.md +257 -84
- data/lib/capybara/config.rb +29 -10
- data/lib/capybara/cucumber.rb +1 -1
- data/lib/capybara/driver/base.rb +22 -4
- data/lib/capybara/driver/node.rb +38 -9
- data/lib/capybara/dsl.rb +9 -7
- data/lib/capybara/helpers.rb +57 -8
- data/lib/capybara/minitest/spec.rb +185 -84
- data/lib/capybara/minitest.rb +264 -145
- data/lib/capybara/node/actions.rb +248 -124
- data/lib/capybara/node/base.rb +35 -20
- data/lib/capybara/node/document.rb +14 -2
- data/lib/capybara/node/document_matchers.rb +13 -15
- data/lib/capybara/node/element.rb +350 -113
- data/lib/capybara/node/finders.rb +104 -82
- data/lib/capybara/node/matchers.rb +363 -157
- data/lib/capybara/node/simple.rb +54 -15
- 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 +9 -10
- data/lib/capybara/queries/base_query.rb +25 -18
- data/lib/capybara/queries/current_path_query.rb +16 -6
- data/lib/capybara/queries/match_query.rb +11 -0
- data/lib/capybara/queries/selector_query.rb +617 -104
- data/lib/capybara/queries/sibling_query.rb +9 -7
- data/lib/capybara/queries/style_query.rb +45 -0
- data/lib/capybara/queries/text_query.rb +40 -22
- data/lib/capybara/queries/title_query.rb +2 -2
- data/lib/capybara/rack_test/browser.rb +106 -31
- data/lib/capybara/rack_test/driver.rb +16 -7
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +74 -49
- data/lib/capybara/rack_test/node.rb +120 -47
- data/lib/capybara/rails.rb +1 -1
- 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 +87 -53
- data/lib/capybara/rspec/features.rb +8 -10
- data/lib/capybara/rspec/matcher_proxies.rb +39 -18
- 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 +142 -315
- data/lib/capybara/rspec.rb +3 -2
- 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 -8
- 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 +1 -0
- data/lib/capybara/selector/filter_set.rb +72 -28
- data/lib/capybara/selector/filters/base.rb +45 -2
- data/lib/capybara/selector/filters/expression_filter.rb +5 -6
- data/lib/capybara/selector/filters/locator_filter.rb +29 -0
- data/lib/capybara/selector/filters/node_filter.rb +18 -4
- data/lib/capybara/selector/regexp_disassembler.rb +211 -0
- data/lib/capybara/selector/selector.rb +89 -200
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +474 -534
- 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 +270 -245
- 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 +460 -170
- 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 +58 -67
- data/lib/capybara/session/config.rb +40 -6
- data/lib/capybara/session/matchers.rb +26 -19
- data/lib/capybara/session.rb +252 -194
- 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 +126 -8
- data/lib/capybara/spec/session/accept_alert_spec.rb +11 -11
- data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -3
- data/lib/capybara/spec/session/accept_prompt_spec.rb +9 -10
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +135 -44
- data/lib/capybara/spec/session/ancestor_spec.rb +24 -19
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +67 -38
- data/lib/capybara/spec/session/{assert_current_path.rb → assert_current_path_spec.rb} +20 -18
- 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.rb → assert_text_spec.rb} +76 -52
- data/lib/capybara/spec/session/{assert_title.rb → assert_title_spec.rb} +12 -12
- data/lib/capybara/spec/session/attach_file_spec.rb +126 -72
- data/lib/capybara/spec/session/body_spec.rb +11 -13
- data/lib/capybara/spec/session/check_spec.rb +112 -51
- data/lib/capybara/spec/session/choose_spec.rb +62 -30
- data/lib/capybara/spec/session/click_button_spec.rb +227 -161
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +49 -30
- data/lib/capybara/spec/session/click_link_spec.rb +89 -55
- data/lib/capybara/spec/session/current_scope_spec.rb +8 -8
- data/lib/capybara/spec/session/current_url_spec.rb +44 -37
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +2 -2
- data/lib/capybara/spec/session/element/{assert_match_selector.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 +8 -6
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +70 -56
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +7 -7
- data/lib/capybara/spec/session/evaluate_script_spec.rb +28 -8
- data/lib/capybara/spec/session/execute_script_spec.rb +8 -7
- data/lib/capybara/spec/session/fill_in_spec.rb +110 -44
- data/lib/capybara/spec/session/find_button_spec.rb +23 -23
- data/lib/capybara/spec/session/find_by_id_spec.rb +8 -8
- data/lib/capybara/spec/session/find_field_spec.rb +33 -31
- data/lib/capybara/spec/session/find_link_spec.rb +42 -14
- data/lib/capybara/spec/session/find_spec.rb +251 -142
- data/lib/capybara/spec/session/first_spec.rb +45 -44
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +6 -6
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +6 -6
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +32 -20
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +46 -19
- data/lib/capybara/spec/session/go_back_spec.rb +1 -1
- data/lib/capybara/spec/session/go_forward_spec.rb +1 -1
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +23 -23
- 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 +98 -12
- data/lib/capybara/spec/session/has_css_spec.rb +271 -137
- data/lib/capybara/spec/session/has_current_path_spec.rb +50 -35
- data/lib/capybara/spec/session/has_element_spec.rb +47 -0
- data/lib/capybara/spec/session/has_field_spec.rb +137 -58
- data/lib/capybara/spec/session/has_link_spec.rb +46 -6
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +33 -31
- data/lib/capybara/spec/session/has_select_spec.rb +84 -50
- data/lib/capybara/spec/session/has_selector_spec.rb +117 -69
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +181 -4
- data/lib/capybara/spec/session/has_text_spec.rb +101 -53
- data/lib/capybara/spec/session/has_title_spec.rb +19 -14
- data/lib/capybara/spec/session/has_xpath_spec.rb +56 -38
- data/lib/capybara/spec/session/{headers.rb → headers_spec.rb} +1 -1
- data/lib/capybara/spec/session/html_spec.rb +13 -6
- data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
- data/lib/capybara/spec/session/node_spec.rb +958 -122
- data/lib/capybara/spec/session/node_wrapper_spec.rb +15 -12
- data/lib/capybara/spec/session/refresh_spec.rb +9 -7
- data/lib/capybara/spec/session/reset_session_spec.rb +65 -37
- data/lib/capybara/spec/session/{response_code.rb → response_code_spec.rb} +1 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +2 -2
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +5 -4
- data/lib/capybara/spec/session/save_page_spec.rb +41 -38
- data/lib/capybara/spec/session/save_screenshot_spec.rb +13 -11
- 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 +102 -76
- data/lib/capybara/spec/session/selectors_spec.rb +51 -18
- data/lib/capybara/spec/session/sibling_spec.rb +9 -9
- data/lib/capybara/spec/session/text_spec.rb +26 -24
- data/lib/capybara/spec/session/title_spec.rb +8 -6
- data/lib/capybara/spec/session/uncheck_spec.rb +41 -22
- data/lib/capybara/spec/session/unselect_spec.rb +37 -37
- data/lib/capybara/spec/session/visit_spec.rb +79 -53
- data/lib/capybara/spec/session/window/become_closed_spec.rb +22 -19
- data/lib/capybara/spec/session/window/current_window_spec.rb +4 -3
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +4 -3
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +25 -21
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +10 -5
- data/lib/capybara/spec/session/window/window_spec.rb +88 -54
- data/lib/capybara/spec/session/window/windows_spec.rb +11 -8
- data/lib/capybara/spec/session/window/within_window_spec.rb +17 -16
- data/lib/capybara/spec/session/within_spec.rb +82 -44
- data/lib/capybara/spec/spec_helper.rb +46 -52
- data/lib/capybara/spec/test_app.rb +148 -41
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/form.erb +156 -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 +46 -11
- 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 +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +32 -26
- data/lib/capybara.rb +128 -104
- data/spec/basic_node_spec.rb +59 -34
- data/spec/capybara_spec.rb +65 -51
- 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 +84 -55
- data/spec/filter_set_spec.rb +24 -7
- data/spec/fixtures/certificate.pem +25 -0
- data/spec/fixtures/key.pem +27 -0
- data/spec/fixtures/selenium_driver_rspec_failure.rb +5 -5
- data/spec/fixtures/selenium_driver_rspec_success.rb +5 -5
- data/spec/minitest_spec.rb +49 -5
- data/spec/minitest_spec_spec.rb +92 -62
- data/spec/per_session_config_spec.rb +6 -6
- data/spec/rack_test_spec.rb +183 -115
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +99 -39
- data/spec/rspec/features_spec.rb +28 -25
- data/spec/rspec/scenarios_spec.rb +10 -6
- data/spec/rspec/shared_spec_matchers.rb +418 -364
- data/spec/rspec/views_spec.rb +4 -3
- data/spec/rspec_matchers_spec.rb +35 -10
- data/spec/rspec_spec.rb +109 -85
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +392 -62
- data/spec/selenium_spec_chrome.rb +183 -41
- data/spec/selenium_spec_chrome_remote.rb +96 -0
- data/spec/selenium_spec_edge.rb +41 -8
- data/spec/selenium_spec_firefox.rb +228 -0
- data/spec/selenium_spec_firefox_remote.rb +94 -0
- data/spec/selenium_spec_ie.rb +129 -11
- data/spec/selenium_spec_safari.rb +162 -0
- data/spec/server_spec.rb +192 -81
- data/spec/session_spec.rb +52 -16
- data/spec/shared_selenium_node.rb +79 -0
- data/spec/shared_selenium_session.rb +460 -123
- data/spec/spec_helper.rb +124 -2
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +344 -45
- 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/rspec/compound.rb +0 -90
- data/lib/capybara/spec/session/assert_selector.rb +0 -149
- 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 -143
data/lib/capybara/window.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module Capybara
|
4
4
|
##
|
5
|
-
# The Window class represents a browser window.
|
5
|
+
# The {Window} class represents a browser window.
|
6
6
|
#
|
7
|
-
# You can get an instance of the class by calling
|
7
|
+
# You can get an instance of the class by calling any of:
|
8
8
|
#
|
9
9
|
# * {Capybara::Session#windows}
|
10
10
|
# * {Capybara::Session#current_window}
|
@@ -12,12 +12,12 @@ module Capybara
|
|
12
12
|
# * {Capybara::Session#switch_to_window}
|
13
13
|
#
|
14
14
|
# Note that some drivers (e.g. Selenium) support getting size of/resizing/closing only
|
15
|
-
#
|
15
|
+
# current window. So if you invoke such method for:
|
16
16
|
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
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)
|
21
21
|
#
|
22
22
|
class Window
|
23
23
|
# @return [String] a string that uniquely identifies window within session
|
@@ -57,12 +57,12 @@ module Capybara
|
|
57
57
|
# Close window.
|
58
58
|
#
|
59
59
|
# If this method was called for window that is current, then after calling this method
|
60
|
-
#
|
61
|
-
#
|
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.
|
62
62
|
#
|
63
63
|
# @!macro about_current
|
64
64
|
# If this method was called for window that is not current, then after calling this method
|
65
|
-
# current window
|
65
|
+
# current window should remain the same as it was before calling this method.
|
66
66
|
#
|
67
67
|
def close
|
68
68
|
@driver.close_window(handle)
|
@@ -82,8 +82,8 @@ module Capybara
|
|
82
82
|
# Resize window.
|
83
83
|
#
|
84
84
|
# @macro about_current
|
85
|
-
# @param width [
|
86
|
-
# @param height [
|
85
|
+
# @param width [Integer] the new window width in pixels
|
86
|
+
# @param height [Integer] the new window height in pixels
|
87
87
|
#
|
88
88
|
def resize_to(width, height)
|
89
89
|
wait_for_stable_size { @driver.resize_window_to(handle, width, height) }
|
@@ -93,7 +93,7 @@ module Capybara
|
|
93
93
|
# Maximize window.
|
94
94
|
#
|
95
95
|
# If a particular driver (e.g. headless driver) doesn't have concept of maximizing it
|
96
|
-
#
|
96
|
+
# may not support this method.
|
97
97
|
#
|
98
98
|
# @macro about_current
|
99
99
|
#
|
@@ -101,13 +101,24 @@ module Capybara
|
|
101
101
|
wait_for_stable_size { @driver.maximize_window(handle) }
|
102
102
|
end
|
103
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
|
+
|
104
115
|
def eql?(other)
|
105
116
|
other.is_a?(self.class) && @session == other.session && @handle == other.handle
|
106
117
|
end
|
107
118
|
alias_method :==, :eql?
|
108
119
|
|
109
120
|
def hash
|
110
|
-
@session
|
121
|
+
[@session, @handle].hash
|
111
122
|
end
|
112
123
|
|
113
124
|
def inspect
|
@@ -118,19 +129,14 @@ module Capybara
|
|
118
129
|
|
119
130
|
def wait_for_stable_size(seconds = session.config.default_max_wait_time)
|
120
131
|
res = yield if block_given?
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
sleep 0.
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
end while (Capybara::Helpers.monotonic_time - start_time) < seconds
|
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?
|
138
|
+
end
|
129
139
|
raise Capybara::WindowError, "Window size not stable within #{seconds} seconds."
|
130
140
|
end
|
131
|
-
|
132
|
-
def raise_unless_current(what)
|
133
|
-
raise Capybara::WindowError, "#{what} not current window is not possible." unless current?
|
134
|
-
end
|
135
141
|
end
|
136
142
|
end
|
data/lib/capybara.rb
CHANGED
@@ -5,6 +5,7 @@ require 'nokogiri'
|
|
5
5
|
require 'xpath'
|
6
6
|
require 'forwardable'
|
7
7
|
require 'capybara/config'
|
8
|
+
require 'capybara/registration_container'
|
8
9
|
|
9
10
|
module Capybara
|
10
11
|
class CapybaraError < StandardError; end
|
@@ -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
|
@@ -64,31 +67,49 @@ module Capybara
|
|
64
67
|
# config.app_host = 'http://www.google.com'
|
65
68
|
# end
|
66
69
|
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
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.
|
92
113
|
#
|
93
114
|
def configure
|
94
115
|
yield config
|
@@ -108,7 +129,7 @@ module Capybara
|
|
108
129
|
# @yieldreturn [Capybara::Driver::Base] A Capybara driver instance
|
109
130
|
#
|
110
131
|
def register_driver(name, &block)
|
111
|
-
drivers
|
132
|
+
drivers.send(:register, name, block)
|
112
133
|
end
|
113
134
|
|
114
135
|
##
|
@@ -127,7 +148,7 @@ module Capybara
|
|
127
148
|
# @yieldparam host The host/ip to bind to
|
128
149
|
#
|
129
150
|
def register_server(name, &block)
|
130
|
-
servers
|
151
|
+
servers.send(:register, name.to_sym, block)
|
131
152
|
end
|
132
153
|
|
133
154
|
##
|
@@ -158,8 +179,8 @@ module Capybara
|
|
158
179
|
# @param [Symbol] name The name of the selector to add
|
159
180
|
# @yield A block executed in the context of the new {Capybara::Selector}
|
160
181
|
#
|
161
|
-
def add_selector(name, &block)
|
162
|
-
Capybara::Selector.add(name, &block)
|
182
|
+
def add_selector(name, **options, &block)
|
183
|
+
Capybara::Selector.add(name, **options, &block)
|
163
184
|
end
|
164
185
|
|
165
186
|
##
|
@@ -169,7 +190,7 @@ module Capybara
|
|
169
190
|
# button style (a class) might look like this
|
170
191
|
#
|
171
192
|
# Capybara.modify_selector(:button) do
|
172
|
-
# filter (:
|
193
|
+
# filter (:btn_style, valid_values: [:primary, :secondary]) { |node, style| node[:class].split.include? "btn-#{style}" }
|
173
194
|
# end
|
174
195
|
#
|
175
196
|
#
|
@@ -181,11 +202,11 @@ module Capybara
|
|
181
202
|
end
|
182
203
|
|
183
204
|
def drivers
|
184
|
-
@drivers ||=
|
205
|
+
@drivers ||= RegistrationContainer.new
|
185
206
|
end
|
186
207
|
|
187
208
|
def servers
|
188
|
-
@servers ||=
|
209
|
+
@servers ||= RegistrationContainer.new
|
189
210
|
end
|
190
211
|
|
191
212
|
# Wraps the given string, which should contain an HTML document or fragment
|
@@ -194,15 +215,13 @@ module Capybara
|
|
194
215
|
# any string containing HTML in the exact same way you would query the current document in a Capybara
|
195
216
|
# session.
|
196
217
|
#
|
197
|
-
#
|
198
|
-
#
|
218
|
+
# @example A single element
|
199
219
|
# node = Capybara.string('<a href="foo">bar</a>')
|
200
220
|
# anchor = node.first('a')
|
201
221
|
# anchor[:href] #=> 'foo'
|
202
222
|
# anchor.text #=> 'bar'
|
203
223
|
#
|
204
|
-
#
|
205
|
-
#
|
224
|
+
# @example Multiple elements
|
206
225
|
# node = Capybara.string <<-HTML
|
207
226
|
# <ul>
|
208
227
|
# <li id="home">Home</li>
|
@@ -241,7 +260,7 @@ module Capybara
|
|
241
260
|
#
|
242
261
|
def current_driver
|
243
262
|
if threadsafe
|
244
|
-
Thread.current
|
263
|
+
Thread.current.thread_variable_get :capybara_current_driver
|
245
264
|
else
|
246
265
|
@current_driver
|
247
266
|
end || default_driver
|
@@ -250,7 +269,7 @@ module Capybara
|
|
250
269
|
|
251
270
|
def current_driver=(name)
|
252
271
|
if threadsafe
|
253
|
-
Thread.current
|
272
|
+
Thread.current.thread_variable_set :capybara_current_driver, name
|
254
273
|
else
|
255
274
|
@current_driver = name
|
256
275
|
end
|
@@ -290,12 +309,12 @@ module Capybara
|
|
290
309
|
|
291
310
|
##
|
292
311
|
#
|
293
|
-
# 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}.
|
294
313
|
#
|
295
314
|
# @return [Capybara::Session] The currently used session
|
296
315
|
#
|
297
316
|
def current_session
|
298
|
-
session_pool["#{current_driver}:#{session_name}:#{app.object_id}"]
|
317
|
+
specified_session || session_pool["#{current_driver}:#{session_name}:#{app.object_id}"]
|
299
318
|
end
|
300
319
|
|
301
320
|
##
|
@@ -317,7 +336,8 @@ module Capybara
|
|
317
336
|
#
|
318
337
|
def session_name
|
319
338
|
if threadsafe
|
320
|
-
Thread.current
|
339
|
+
Thread.current.thread_variable_get(:capybara_session_name) ||
|
340
|
+
Thread.current.thread_variable_set(:capybara_session_name, :default)
|
321
341
|
else
|
322
342
|
@session_name ||= :default
|
323
343
|
end
|
@@ -325,7 +345,7 @@ module Capybara
|
|
325
345
|
|
326
346
|
def session_name=(name)
|
327
347
|
if threadsafe
|
328
|
-
Thread.current
|
348
|
+
Thread.current.thread_variable_set :capybara_session_name, name
|
329
349
|
else
|
330
350
|
@session_name = name
|
331
351
|
end
|
@@ -333,22 +353,31 @@ module Capybara
|
|
333
353
|
|
334
354
|
##
|
335
355
|
#
|
336
|
-
# Yield a block using a specific session name.
|
356
|
+
# Yield a block using a specific session name or {Capybara::Session} instance.
|
337
357
|
#
|
338
|
-
def using_session(
|
358
|
+
def using_session(name_or_session, &block)
|
359
|
+
previous_session = current_session
|
339
360
|
previous_session_info = {
|
361
|
+
specified_session: specified_session,
|
340
362
|
session_name: session_name,
|
341
363
|
current_driver: current_driver,
|
342
364
|
app: app
|
343
365
|
}
|
344
|
-
self.session_name =
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
self.current_driver = previous_session_info[:current_driver]
|
350
|
-
self.app = previous_session_info[:app]
|
366
|
+
self.specified_session = self.session_name = nil
|
367
|
+
if name_or_session.is_a? Capybara::Session
|
368
|
+
self.specified_session = name_or_session
|
369
|
+
else
|
370
|
+
self.session_name = name_or_session
|
351
371
|
end
|
372
|
+
|
373
|
+
if block.arity.zero?
|
374
|
+
yield
|
375
|
+
else
|
376
|
+
yield current_session, previous_session
|
377
|
+
end
|
378
|
+
ensure
|
379
|
+
self.session_name, self.specified_session = previous_session_info.values_at(:session_name, :specified_session)
|
380
|
+
self.current_driver, self.app = previous_session_info.values_at(:current_driver, :app) if threadsafe
|
352
381
|
end
|
353
382
|
|
354
383
|
##
|
@@ -359,9 +388,21 @@ module Capybara
|
|
359
388
|
# @return [Nokogiri::HTML::Document] HTML document
|
360
389
|
#
|
361
390
|
def HTML(html) # rubocop:disable Naming/MethodName
|
362
|
-
Nokogiri
|
391
|
+
# Nokogiri >= 1.12.0 or Nokogumbo installed and allowed for use
|
392
|
+
html_parser, using_html5 = if defined?(Nokogiri::HTML5) && Capybara.use_html5_parsing
|
393
|
+
[Nokogiri::HTML5, true]
|
394
|
+
else
|
395
|
+
[defined?(Nokogiri::HTML4) ? Nokogiri::HTML4 : Nokogiri::HTML, false]
|
396
|
+
end
|
397
|
+
|
398
|
+
html_parser.parse(html).tap do |document|
|
399
|
+
document.xpath('//template').each do |template|
|
400
|
+
# template elements content is not part of the document
|
401
|
+
template.inner_html = ''
|
402
|
+
end
|
363
403
|
document.xpath('//textarea').each do |textarea|
|
364
|
-
|
404
|
+
# The Nokogiri HTML5 parser already returns spec compliant contents
|
405
|
+
textarea['_capybara_raw_value'] = using_html5 ? textarea.content : textarea.content.delete_prefix("\n")
|
365
406
|
end
|
366
407
|
end
|
367
408
|
end
|
@@ -377,7 +418,25 @@ module Capybara
|
|
377
418
|
end
|
378
419
|
|
379
420
|
def session_pool
|
380
|
-
@session_pool ||=
|
421
|
+
@session_pool ||= Hash.new do |hash, name|
|
422
|
+
hash[name] = Capybara::Session.new(current_driver, app)
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
def specified_session
|
427
|
+
if threadsafe
|
428
|
+
Thread.current.thread_variable_get :capybara_specified_session
|
429
|
+
else
|
430
|
+
@specified_session ||= nil
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
def specified_session=(session)
|
435
|
+
if threadsafe
|
436
|
+
Thread.current.thread_variable_set :capybara_specified_session, session
|
437
|
+
else
|
438
|
+
@specified_session = session
|
439
|
+
end
|
381
440
|
end
|
382
441
|
end
|
383
442
|
|
@@ -405,6 +464,8 @@ module Capybara
|
|
405
464
|
require 'capybara/queries/match_query'
|
406
465
|
require 'capybara/queries/ancestor_query'
|
407
466
|
require 'capybara/queries/sibling_query'
|
467
|
+
require 'capybara/queries/style_query'
|
468
|
+
require 'capybara/queries/active_element_query'
|
408
469
|
|
409
470
|
require 'capybara/node/finders'
|
410
471
|
require 'capybara/node/matchers'
|
@@ -422,40 +483,14 @@ module Capybara
|
|
422
483
|
require 'capybara/rack_test/node'
|
423
484
|
require 'capybara/rack_test/form'
|
424
485
|
require 'capybara/rack_test/browser'
|
425
|
-
require 'capybara/rack_test/css_handlers
|
486
|
+
require 'capybara/rack_test/css_handlers'
|
426
487
|
|
427
488
|
require 'capybara/selenium/node'
|
428
489
|
require 'capybara/selenium/driver'
|
429
490
|
end
|
430
491
|
|
431
|
-
|
432
|
-
|
433
|
-
end
|
434
|
-
|
435
|
-
Capybara.register_server :webrick do |app, port, host, **options|
|
436
|
-
require 'rack/handler/webrick'
|
437
|
-
Rack::Handler::WEBrick.run(app, { Host: host, Port: port, AccessLog: [], Logger: WEBrick::Log.new(nil, 0) }.merge(options))
|
438
|
-
end
|
439
|
-
|
440
|
-
Capybara.register_server :puma do |app, port, host, **options|
|
441
|
-
require 'rack/handler/puma'
|
442
|
-
# If we just run the Puma Rack handler it installs signal handlers which prevent us from being able to interrupt tests.
|
443
|
-
# Therefore construct and run the Server instance ourselves.
|
444
|
-
# Rack::Handler::Puma.run(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options))
|
445
|
-
|
446
|
-
conf = Rack::Handler::Puma.config(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options))
|
447
|
-
events = conf.options[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
|
448
|
-
|
449
|
-
events.log "Capybara starting Puma..."
|
450
|
-
events.log "* Version #{Puma::Const::PUMA_VERSION} , codename: #{Puma::Const::CODE_NAME}"
|
451
|
-
events.log "* Min threads: #{conf.options[:min_threads]}, max threads: #{conf.options[:max_threads]}"
|
452
|
-
|
453
|
-
Puma::Server.new(conf.app, events, conf.options).tap do |s|
|
454
|
-
s.binder.parse conf.options[:binds], s.events
|
455
|
-
s.min_threads = conf.options[:min_threads]
|
456
|
-
s.max_threads = conf.options[:max_threads]
|
457
|
-
end.run.join
|
458
|
-
end
|
492
|
+
require 'capybara/registrations/servers'
|
493
|
+
require 'capybara/registrations/drivers'
|
459
494
|
|
460
495
|
Capybara.configure do |config|
|
461
496
|
config.always_include_port = false
|
@@ -463,35 +498,24 @@ Capybara.configure do |config|
|
|
463
498
|
config.server = :default
|
464
499
|
config.default_selector = :css
|
465
500
|
config.default_max_wait_time = 2
|
501
|
+
config.default_retry_interval = 0.01
|
466
502
|
config.ignore_hidden_elements = true
|
467
|
-
config.default_host =
|
503
|
+
config.default_host = 'http://www.example.com'
|
468
504
|
config.automatic_reload = true
|
469
505
|
config.match = :smart
|
470
506
|
config.exact = false
|
471
507
|
config.exact_text = false
|
472
508
|
config.raise_server_errors = true
|
473
|
-
config.server_errors = [
|
509
|
+
config.server_errors = [Exception]
|
474
510
|
config.visible_text_only = false
|
475
511
|
config.automatic_label_click = false
|
476
512
|
config.enable_aria_label = false
|
513
|
+
config.enable_aria_role = false
|
477
514
|
config.reuse_server = true
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
Capybara.register_driver :selenium do |app|
|
485
|
-
Capybara::Selenium::Driver.new(app)
|
486
|
-
end
|
487
|
-
|
488
|
-
Capybara.register_driver :selenium_chrome do |app|
|
489
|
-
Capybara::Selenium::Driver.new(app, browser: :chrome)
|
490
|
-
end
|
491
|
-
|
492
|
-
Capybara.register_driver :selenium_chrome_headless do |app|
|
493
|
-
browser_options = ::Selenium::WebDriver::Chrome::Options.new
|
494
|
-
browser_options.args << '--headless'
|
495
|
-
browser_options.args << '--disable-gpu'
|
496
|
-
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
|
515
|
+
config.default_set_options = {}
|
516
|
+
config.test_id = nil
|
517
|
+
config.predicates_wait = true
|
518
|
+
config.default_normalize_ws = false
|
519
|
+
config.use_html5_parsing = false
|
520
|
+
config.w3c_click_offset = true
|
497
521
|
end
|