capybara 2.7.0 → 3.35.3
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 +5 -5
- data/.yardopts +1 -0
- data/History.md +1147 -11
- data/License.txt +1 -1
- data/README.md +252 -131
- data/lib/capybara/config.rb +92 -0
- data/lib/capybara/cucumber.rb +3 -3
- data/lib/capybara/driver/base.rb +52 -21
- data/lib/capybara/driver/node.rb +48 -14
- data/lib/capybara/dsl.rb +16 -9
- data/lib/capybara/helpers.rb +72 -81
- data/lib/capybara/minitest/spec.rb +267 -0
- data/lib/capybara/minitest.rb +385 -0
- data/lib/capybara/node/actions.rb +337 -89
- data/lib/capybara/node/base.rb +50 -32
- data/lib/capybara/node/document.rb +19 -3
- data/lib/capybara/node/document_matchers.rb +22 -24
- data/lib/capybara/node/element.rb +388 -125
- data/lib/capybara/node/finders.rb +231 -121
- data/lib/capybara/node/matchers.rb +503 -217
- data/lib/capybara/node/simple.rb +64 -27
- data/lib/capybara/queries/ancestor_query.rb +27 -0
- data/lib/capybara/queries/base_query.rb +87 -11
- data/lib/capybara/queries/current_path_query.rb +24 -24
- data/lib/capybara/queries/match_query.rb +15 -10
- data/lib/capybara/queries/selector_query.rb +675 -81
- data/lib/capybara/queries/sibling_query.rb +26 -0
- data/lib/capybara/queries/style_query.rb +45 -0
- data/lib/capybara/queries/text_query.rb +88 -20
- data/lib/capybara/queries/title_query.rb +9 -11
- data/lib/capybara/rack_test/browser.rb +63 -39
- data/lib/capybara/rack_test/css_handlers.rb +6 -4
- data/lib/capybara/rack_test/driver.rb +26 -16
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +73 -58
- data/lib/capybara/rack_test/node.rb +187 -67
- data/lib/capybara/rails.rb +4 -8
- data/lib/capybara/registration_container.rb +44 -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 +45 -0
- data/lib/capybara/result.rb +142 -14
- data/lib/capybara/rspec/features.rb +17 -42
- data/lib/capybara/rspec/matcher_proxies.rb +82 -0
- 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 +143 -244
- data/lib/capybara/rspec.rb +10 -12
- 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 +102 -0
- data/lib/capybara/selector/definition/button.rb +63 -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 +278 -0
- data/lib/capybara/selector/filter.rb +3 -46
- data/lib/capybara/selector/filter_set.rb +124 -0
- data/lib/capybara/selector/filters/base.rb +77 -0
- data/lib/capybara/selector/filters/expression_filter.rb +22 -0
- data/lib/capybara/selector/filters/locator_filter.rb +29 -0
- data/lib/capybara/selector/filters/node_filter.rb +31 -0
- data/lib/capybara/selector/regexp_disassembler.rb +214 -0
- data/lib/capybara/selector/selector.rb +155 -0
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +232 -369
- 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 +380 -142
- 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 +228 -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 +40 -0
- data/lib/capybara/selenium/node.rb +528 -97
- 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 +63 -0
- data/lib/capybara/server/checker.rb +44 -0
- data/lib/capybara/server/middleware.rb +71 -0
- data/lib/capybara/server.rb +74 -71
- data/lib/capybara/session/config.rb +126 -0
- data/lib/capybara/session/matchers.rb +44 -27
- data/lib/capybara/session.rb +500 -297
- data/lib/capybara/spec/fixtures/no_extension +1 -0
- 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 +168 -14
- data/lib/capybara/spec/session/accept_alert_spec.rb +37 -14
- data/lib/capybara/spec/session/accept_confirm_spec.rb +7 -6
- data/lib/capybara/spec/session/accept_prompt_spec.rb +38 -10
- data/lib/capybara/spec/session/all_spec.rb +179 -59
- data/lib/capybara/spec/session/ancestor_spec.rb +88 -0
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +140 -0
- 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_spec.rb +93 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +154 -48
- data/lib/capybara/spec/session/body_spec.rb +12 -13
- data/lib/capybara/spec/session/check_spec.rb +168 -41
- data/lib/capybara/spec/session/choose_spec.rb +75 -23
- data/lib/capybara/spec/session/click_button_spec.rb +243 -175
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +57 -32
- data/lib/capybara/spec/session/click_link_spec.rb +100 -53
- data/lib/capybara/spec/session/current_scope_spec.rb +11 -10
- data/lib/capybara/spec/session/current_url_spec.rb +61 -35
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +7 -7
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +5 -4
- data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +13 -6
- data/lib/capybara/spec/session/element/match_css_spec.rb +21 -7
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +9 -7
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +91 -34
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +23 -0
- data/lib/capybara/spec/session/evaluate_script_spec.rb +45 -3
- data/lib/capybara/spec/session/execute_script_spec.rb +24 -4
- data/lib/capybara/spec/session/fill_in_spec.rb +166 -64
- data/lib/capybara/spec/session/find_button_spec.rb +37 -18
- data/lib/capybara/spec/session/find_by_id_spec.rb +10 -9
- data/lib/capybara/spec/session/find_field_spec.rb +57 -34
- data/lib/capybara/spec/session/find_link_spec.rb +47 -10
- data/lib/capybara/spec/session/find_spec.rb +290 -144
- data/lib/capybara/spec/session/first_spec.rb +91 -48
- 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 +116 -0
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +112 -0
- data/lib/capybara/spec/session/go_back_spec.rb +3 -2
- data/lib/capybara/spec/session/go_forward_spec.rb +3 -2
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
- data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +25 -0
- data/lib/capybara/spec/session/has_button_spec.rb +76 -19
- data/lib/capybara/spec/session/has_css_spec.rb +277 -131
- data/lib/capybara/spec/session/has_current_path_spec.rb +98 -26
- data/lib/capybara/spec/session/has_field_spec.rb +177 -107
- data/lib/capybara/spec/session/has_link_spec.rb +13 -12
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +78 -0
- data/lib/capybara/spec/session/has_select_spec.rb +191 -95
- data/lib/capybara/spec/session/has_selector_spec.rb +128 -64
- 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 +126 -60
- data/lib/capybara/spec/session/has_title_spec.rb +35 -12
- data/lib/capybara/spec/session/has_xpath_spec.rb +74 -53
- 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 +1028 -131
- data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
- data/lib/capybara/spec/session/refresh_spec.rb +34 -0
- data/lib/capybara/spec/session/reset_session_spec.rb +75 -34
- 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 +11 -15
- 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 +112 -85
- data/lib/capybara/spec/session/selectors_spec.rb +71 -8
- data/lib/capybara/spec/session/sibling_spec.rb +52 -0
- data/lib/capybara/spec/session/text_spec.rb +38 -23
- data/lib/capybara/spec/session/title_spec.rb +17 -5
- data/lib/capybara/spec/session/uncheck_spec.rb +71 -12
- data/lib/capybara/spec/session/unselect_spec.rb +44 -43
- data/lib/capybara/spec/session/visit_spec.rb +99 -32
- data/lib/capybara/spec/session/window/become_closed_spec.rb +33 -29
- 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 +39 -30
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +17 -10
- data/lib/capybara/spec/session/window/window_spec.rb +121 -73
- data/lib/capybara/spec/session/window/windows_spec.rb +12 -10
- data/lib/capybara/spec/session/window/within_window_spec.rb +52 -82
- data/lib/capybara/spec/session/within_spec.rb +76 -43
- data/lib/capybara/spec/spec_helper.rb +67 -33
- data/lib/capybara/spec/test_app.rb +85 -36
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/buttons.erb +1 -1
- data/lib/capybara/spec/views/fieldsets.erb +1 -1
- data/lib/capybara/spec/views/form.erb +227 -20
- data/lib/capybara/spec/views/frame_child.erb +10 -2
- data/lib/capybara/spec/views/frame_one.erb +2 -1
- data/lib/capybara/spec/views/frame_parent.erb +2 -2
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/header_links.erb +1 -1
- data/lib/capybara/spec/views/host_links.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +47 -0
- data/lib/capybara/spec/views/offset.erb +32 -0
- data/lib/capybara/spec/views/path.erb +1 -1
- 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/postback.erb +1 -1
- data/lib/capybara/spec/views/react.erb +45 -0
- data/lib/capybara/spec/views/scroll.erb +20 -0
- data/lib/capybara/spec/views/spatial.erb +31 -0
- data/lib/capybara/spec/views/tables.erb +69 -2
- data/lib/capybara/spec/views/with_animation.erb +82 -0
- data/lib/capybara/spec/views/with_base_tag.erb +1 -1
- data/lib/capybara/spec/views/with_count.erb +1 -1
- data/lib/capybara/spec/views/with_dragula.erb +24 -0
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
- data/lib/capybara/spec/views/with_hover.erb +7 -1
- data/lib/capybara/spec/views/with_hover1.erb +10 -0
- data/lib/capybara/spec/views/with_html.erb +100 -10
- data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
- data/lib/capybara/spec/views/with_html_entities.erb +1 -1
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +49 -3
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_namespace.erb +20 -0
- data/lib/capybara/spec/views/with_scope.erb +1 -1
- data/lib/capybara/spec/views/with_scope_other.erb +6 -0
- data/lib/capybara/spec/views/with_simple_html.erb +1 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
- data/lib/capybara/spec/views/with_title.erb +1 -1
- data/lib/capybara/spec/views/with_unload_alert.erb +3 -1
- data/lib/capybara/spec/views/with_windows.erb +7 -1
- data/lib/capybara/spec/views/within_frames.erb +6 -3
- data/lib/capybara/version.rb +2 -1
- data/lib/capybara/window.rb +39 -21
- data/lib/capybara.rb +208 -186
- data/spec/basic_node_spec.rb +52 -39
- data/spec/capybara_spec.rb +72 -50
- data/spec/css_builder_spec.rb +101 -0
- data/spec/css_splitter_spec.rb +38 -0
- data/spec/dsl_spec.rb +81 -61
- data/spec/filter_set_spec.rb +46 -0
- data/spec/fixtures/capybara.csv +1 -0
- data/spec/fixtures/certificate.pem +25 -0
- data/spec/fixtures/key.pem +27 -0
- data/spec/fixtures/selenium_driver_rspec_failure.rb +7 -3
- data/spec/fixtures/selenium_driver_rspec_success.rb +7 -3
- data/spec/minitest_spec.rb +164 -0
- data/spec/minitest_spec_spec.rb +162 -0
- data/spec/per_session_config_spec.rb +68 -0
- data/spec/rack_test_spec.rb +189 -96
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +143 -13
- data/spec/rspec/features_spec.rb +38 -32
- data/spec/rspec/scenarios_spec.rb +9 -7
- data/spec/rspec/shared_spec_matchers.rb +959 -0
- data/spec/rspec/views_spec.rb +9 -3
- data/spec/rspec_matchers_spec.rb +62 -0
- data/spec/rspec_spec.rb +127 -30
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +458 -37
- data/spec/selenium_spec_chrome.rb +196 -9
- data/spec/selenium_spec_chrome_remote.rb +100 -0
- data/spec/selenium_spec_edge.rb +47 -0
- data/spec/selenium_spec_firefox.rb +210 -0
- data/spec/selenium_spec_firefox_remote.rb +80 -0
- data/spec/selenium_spec_ie.rb +150 -0
- data/spec/selenium_spec_safari.rb +148 -0
- data/spec/server_spec.rb +200 -101
- data/spec/session_spec.rb +91 -0
- data/spec/shared_selenium_node.rb +83 -0
- data/spec/shared_selenium_session.rb +558 -0
- data/spec/spec_helper.rb +94 -2
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +420 -60
- data/lib/capybara/query.rb +0 -7
- data/lib/capybara/spec/session/assert_current_path.rb +0 -60
- data/lib/capybara/spec/session/assert_selector.rb +0 -148
- data/lib/capybara/spec/session/assert_text.rb +0 -196
- data/lib/capybara/spec/session/assert_title.rb +0 -70
- data/lib/capybara/spec/session/source_spec.rb +0 -0
- data/lib/capybara/spec/session/within_frame_spec.rb +0 -53
- data/spec/rspec/matchers_spec.rb +0 -827
- data/spec/selenium_spec.rb +0 -151
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
require 'capybara/session/config'
|
|
5
|
+
|
|
6
|
+
module Capybara
|
|
7
|
+
class Config
|
|
8
|
+
extend Forwardable
|
|
9
|
+
|
|
10
|
+
OPTIONS = %i[app reuse_server threadsafe server default_driver javascript_driver allow_gumbo].freeze
|
|
11
|
+
|
|
12
|
+
attr_accessor :app, :allow_gumbo
|
|
13
|
+
attr_reader :reuse_server, :threadsafe, :session_options
|
|
14
|
+
attr_writer :default_driver, :javascript_driver
|
|
15
|
+
|
|
16
|
+
SessionConfig::OPTIONS.each do |method|
|
|
17
|
+
def_delegators :session_options, method, "#{method}="
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def initialize
|
|
21
|
+
@session_options = Capybara::SessionConfig.new
|
|
22
|
+
@javascript_driver = nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
attr_writer :reuse_server
|
|
26
|
+
|
|
27
|
+
def threadsafe=(bool)
|
|
28
|
+
if (bool != threadsafe) && Session.instance_created?
|
|
29
|
+
raise 'Threadsafe setting cannot be changed once a session is created'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
@threadsafe = bool
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
#
|
|
37
|
+
# Return the proc that Capybara will call to run the Rack application.
|
|
38
|
+
# The block returned receives a rack app, port, and host/ip and should run a Rack handler
|
|
39
|
+
# By default, Capybara will try to use puma.
|
|
40
|
+
#
|
|
41
|
+
attr_reader :server
|
|
42
|
+
|
|
43
|
+
##
|
|
44
|
+
#
|
|
45
|
+
# Set the server to use.
|
|
46
|
+
#
|
|
47
|
+
# Capybara.server = :webrick
|
|
48
|
+
# Capybara.server = :puma, { Silent: true }
|
|
49
|
+
#
|
|
50
|
+
# @overload server=(name)
|
|
51
|
+
# @param [Symbol] name Name of the server type to use
|
|
52
|
+
# @overload server=([name, options])
|
|
53
|
+
# @param [Symbol] name Name of the server type to use
|
|
54
|
+
# @param [Hash] options Options to pass to the server block
|
|
55
|
+
# @see register_server
|
|
56
|
+
#
|
|
57
|
+
def server=(name)
|
|
58
|
+
name, options = *name if name.is_a? Array
|
|
59
|
+
@server = if name.respond_to? :call
|
|
60
|
+
name
|
|
61
|
+
elsif options
|
|
62
|
+
proc { |app, port, host| Capybara.servers[name.to_sym].call(app, port, host, **options) }
|
|
63
|
+
else
|
|
64
|
+
Capybara.servers[name.to_sym]
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
##
|
|
69
|
+
#
|
|
70
|
+
# @return [Symbol] The name of the driver to use by default
|
|
71
|
+
#
|
|
72
|
+
def default_driver
|
|
73
|
+
@default_driver || :rack_test
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
##
|
|
77
|
+
#
|
|
78
|
+
# @return [Symbol] The name of the driver used when JavaScript is needed
|
|
79
|
+
#
|
|
80
|
+
def javascript_driver
|
|
81
|
+
@javascript_driver || :selenium
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def deprecate(method, alternate_method, once: false)
|
|
85
|
+
@deprecation_notified ||= {}
|
|
86
|
+
unless once && @deprecation_notified[method]
|
|
87
|
+
Capybara::Helpers.warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead: #{Capybara::Helpers.filter_backtrace(caller)}"
|
|
88
|
+
end
|
|
89
|
+
@deprecation_notified[method] = true
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
data/lib/capybara/cucumber.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'capybara/dsl'
|
|
3
4
|
require 'capybara/rspec/matchers'
|
|
5
|
+
require 'capybara/rspec/matcher_proxies'
|
|
4
6
|
|
|
5
7
|
World(Capybara::DSL)
|
|
6
8
|
World(Capybara::RSpecMatchers)
|
|
@@ -20,8 +22,6 @@ end
|
|
|
20
22
|
Before do |scenario|
|
|
21
23
|
scenario.source_tag_names.each do |tag|
|
|
22
24
|
driver_name = tag.sub(/^@/, '').to_sym
|
|
23
|
-
if Capybara.drivers
|
|
24
|
-
Capybara.current_driver = driver_name
|
|
25
|
-
end
|
|
25
|
+
Capybara.current_driver = driver_name if Capybara.drivers[driver_name]
|
|
26
26
|
end
|
|
27
27
|
end
|
data/lib/capybara/driver/base.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
class Capybara::Driver::Base
|
|
4
|
+
attr_writer :session
|
|
5
|
+
|
|
3
6
|
def current_url
|
|
4
7
|
raise NotImplementedError
|
|
5
8
|
end
|
|
@@ -8,11 +11,15 @@ class Capybara::Driver::Base
|
|
|
8
11
|
raise NotImplementedError
|
|
9
12
|
end
|
|
10
13
|
|
|
11
|
-
def
|
|
14
|
+
def refresh
|
|
12
15
|
raise NotImplementedError
|
|
13
16
|
end
|
|
14
17
|
|
|
15
|
-
def
|
|
18
|
+
def find_xpath(query, **options)
|
|
19
|
+
raise NotImplementedError
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def find_css(query, **options)
|
|
16
23
|
raise NotImplementedError
|
|
17
24
|
end
|
|
18
25
|
|
|
@@ -28,15 +35,19 @@ class Capybara::Driver::Base
|
|
|
28
35
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#go_forward'
|
|
29
36
|
end
|
|
30
37
|
|
|
31
|
-
def execute_script(script)
|
|
38
|
+
def execute_script(script, *args)
|
|
32
39
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#execute_script'
|
|
33
40
|
end
|
|
34
41
|
|
|
35
|
-
def evaluate_script(script)
|
|
42
|
+
def evaluate_script(script, *args)
|
|
36
43
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#evaluate_script'
|
|
37
44
|
end
|
|
38
45
|
|
|
39
|
-
def
|
|
46
|
+
def evaluate_async_script(script, *args)
|
|
47
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#evaluate_script_asnyc'
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def save_screenshot(path, **options)
|
|
40
51
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#save_screenshot'
|
|
41
52
|
end
|
|
42
53
|
|
|
@@ -48,8 +59,26 @@ class Capybara::Driver::Base
|
|
|
48
59
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#status_code'
|
|
49
60
|
end
|
|
50
61
|
|
|
51
|
-
def
|
|
52
|
-
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#
|
|
62
|
+
def send_keys(*)
|
|
63
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#send_keys'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
##
|
|
67
|
+
#
|
|
68
|
+
# @param frame [Capybara::Node::Element, :parent, :top] The iframe element to switch to
|
|
69
|
+
#
|
|
70
|
+
def switch_to_frame(frame)
|
|
71
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#switch_to_frame'
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def frame_title
|
|
75
|
+
find_xpath('/html/head/title').map(&:all_text).first.to_s
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def frame_url
|
|
79
|
+
evaluate_script('document.location.href')
|
|
80
|
+
rescue Capybara::NotSupportedByDriverError
|
|
81
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#frame_title'
|
|
53
82
|
end
|
|
54
83
|
|
|
55
84
|
def current_window_handle
|
|
@@ -65,7 +94,11 @@ class Capybara::Driver::Base
|
|
|
65
94
|
end
|
|
66
95
|
|
|
67
96
|
def maximize_window(handle)
|
|
68
|
-
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#
|
|
97
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#maximize_window'
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def fullscreen_window(handle)
|
|
101
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#fullscreen_window'
|
|
69
102
|
end
|
|
70
103
|
|
|
71
104
|
def close_window(handle)
|
|
@@ -84,15 +117,10 @@ class Capybara::Driver::Base
|
|
|
84
117
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#switch_to_window'
|
|
85
118
|
end
|
|
86
119
|
|
|
87
|
-
def within_window(locator)
|
|
88
|
-
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#within_window'
|
|
89
|
-
end
|
|
90
|
-
|
|
91
120
|
def no_such_window_error
|
|
92
121
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#no_such_window_error'
|
|
93
122
|
end
|
|
94
123
|
|
|
95
|
-
|
|
96
124
|
##
|
|
97
125
|
#
|
|
98
126
|
# Execute the block, and then accept the modal opened.
|
|
@@ -103,7 +131,7 @@ class Capybara::Driver::Base
|
|
|
103
131
|
# @return [String] the message shown in the modal
|
|
104
132
|
# @raise [Capybara::ModalNotFound] if modal dialog hasn't been found
|
|
105
133
|
#
|
|
106
|
-
def accept_modal(type, options
|
|
134
|
+
def accept_modal(type, **options, &blk)
|
|
107
135
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#accept_modal'
|
|
108
136
|
end
|
|
109
137
|
|
|
@@ -116,7 +144,7 @@ class Capybara::Driver::Base
|
|
|
116
144
|
# @return [String] the message shown in the modal
|
|
117
145
|
# @raise [Capybara::ModalNotFound] if modal dialog hasn't been found
|
|
118
146
|
#
|
|
119
|
-
def dismiss_modal(type, options
|
|
147
|
+
def dismiss_modal(type, **options, &blk)
|
|
120
148
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#dismiss_modal'
|
|
121
149
|
end
|
|
122
150
|
|
|
@@ -128,16 +156,19 @@ class Capybara::Driver::Base
|
|
|
128
156
|
false
|
|
129
157
|
end
|
|
130
158
|
|
|
131
|
-
def reset
|
|
132
|
-
end
|
|
159
|
+
def reset!; end
|
|
133
160
|
|
|
134
161
|
def needs_server?
|
|
135
162
|
false
|
|
136
163
|
end
|
|
137
164
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
165
|
+
def session_options
|
|
166
|
+
session&.config || Capybara.session_options
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
private
|
|
170
|
+
|
|
171
|
+
def session
|
|
172
|
+
@session ||= nil
|
|
142
173
|
end
|
|
143
174
|
end
|
data/lib/capybara/driver/node.rb
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
module Capybara
|
|
3
4
|
module Driver
|
|
4
5
|
class Node
|
|
5
|
-
attr_reader :driver, :native
|
|
6
|
+
attr_reader :driver, :native, :initial_cache
|
|
6
7
|
|
|
7
|
-
def initialize(driver, native)
|
|
8
|
+
def initialize(driver, native, initial_cache = {})
|
|
8
9
|
@driver = driver
|
|
9
10
|
@native = native
|
|
11
|
+
@initial_cache = initial_cache
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def all_text
|
|
@@ -25,9 +27,13 @@ module Capybara
|
|
|
25
27
|
raise NotImplementedError
|
|
26
28
|
end
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
def style(styles)
|
|
31
|
+
raise NotImplementedError
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @param value [String, Array] Array is only allowed if node has 'multiple' attribute
|
|
35
|
+
# @param options [Hash] Driver specific options for how to set a value on a node
|
|
36
|
+
def set(value, **options)
|
|
31
37
|
raise NotImplementedError
|
|
32
38
|
end
|
|
33
39
|
|
|
@@ -39,27 +45,39 @@ module Capybara
|
|
|
39
45
|
raise NotImplementedError
|
|
40
46
|
end
|
|
41
47
|
|
|
42
|
-
def click
|
|
48
|
+
def click(keys = [], **options)
|
|
43
49
|
raise NotImplementedError
|
|
44
50
|
end
|
|
45
|
-
|
|
46
|
-
def right_click
|
|
51
|
+
|
|
52
|
+
def right_click(keys = [], **options)
|
|
47
53
|
raise NotImplementedError
|
|
48
54
|
end
|
|
49
|
-
|
|
50
|
-
def double_click
|
|
55
|
+
|
|
56
|
+
def double_click(keys = [], **options)
|
|
51
57
|
raise NotImplementedError
|
|
52
58
|
end
|
|
53
|
-
|
|
59
|
+
|
|
54
60
|
def send_keys(*args)
|
|
55
61
|
raise NotImplementedError
|
|
56
62
|
end
|
|
57
|
-
|
|
63
|
+
|
|
58
64
|
def hover
|
|
59
65
|
raise NotImplementedError
|
|
60
66
|
end
|
|
61
|
-
|
|
62
|
-
def drag_to(element)
|
|
67
|
+
|
|
68
|
+
def drag_to(element, **options)
|
|
69
|
+
raise NotImplementedError
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def drop(*args)
|
|
73
|
+
raise NotImplementedError
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def scroll_by(x, y)
|
|
77
|
+
raise NotImplementedError
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def scroll_to(element, alignment, position = nil)
|
|
63
81
|
raise NotImplementedError
|
|
64
82
|
end
|
|
65
83
|
|
|
@@ -71,6 +89,10 @@ module Capybara
|
|
|
71
89
|
raise NotImplementedError
|
|
72
90
|
end
|
|
73
91
|
|
|
92
|
+
def obscured?
|
|
93
|
+
raise NotImplementedError
|
|
94
|
+
end
|
|
95
|
+
|
|
74
96
|
def checked?
|
|
75
97
|
raise NotImplementedError
|
|
76
98
|
end
|
|
@@ -83,6 +105,18 @@ module Capybara
|
|
|
83
105
|
raise NotImplementedError
|
|
84
106
|
end
|
|
85
107
|
|
|
108
|
+
def readonly?
|
|
109
|
+
!!self[:readonly]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def multiple?
|
|
113
|
+
!!self[:multiple]
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def rect
|
|
117
|
+
raise NotSupportedByDriverError, 'Capybara::Driver::Node#rect'
|
|
118
|
+
end
|
|
119
|
+
|
|
86
120
|
def path
|
|
87
121
|
raise NotSupportedByDriverError, 'Capybara::Driver::Node#path'
|
|
88
122
|
end
|
data/lib/capybara/dsl.rb
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'capybara'
|
|
3
4
|
|
|
4
5
|
module Capybara
|
|
5
6
|
module DSL
|
|
6
7
|
def self.included(base)
|
|
7
|
-
warn
|
|
8
|
+
warn 'including Capybara::DSL in the global scope is not recommended!' if base == Object
|
|
8
9
|
super
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
def self.extended(base)
|
|
12
|
-
warn
|
|
13
|
+
warn 'extending the main object with Capybara::DSL is not recommended!' if base == TOPLEVEL_BINDING.eval('self')
|
|
13
14
|
super
|
|
14
15
|
end
|
|
15
16
|
|
|
@@ -17,16 +18,14 @@ module Capybara
|
|
|
17
18
|
#
|
|
18
19
|
# Shortcut to working in a different session.
|
|
19
20
|
#
|
|
20
|
-
def using_session(
|
|
21
|
-
Capybara.using_session(
|
|
21
|
+
def using_session(name_or_session, &block)
|
|
22
|
+
Capybara.using_session(name_or_session, &block)
|
|
22
23
|
end
|
|
23
24
|
|
|
24
|
-
##
|
|
25
|
-
#
|
|
26
25
|
# Shortcut to using a different wait time.
|
|
27
26
|
#
|
|
28
27
|
def using_wait_time(seconds, &block)
|
|
29
|
-
|
|
28
|
+
page.using_wait_time(seconds, &block)
|
|
30
29
|
end
|
|
31
30
|
|
|
32
31
|
##
|
|
@@ -48,8 +47,16 @@ module Capybara
|
|
|
48
47
|
end
|
|
49
48
|
|
|
50
49
|
Session::DSL_METHODS.each do |method|
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
if RUBY_VERSION >= '2.7'
|
|
51
|
+
class_eval <<~METHOD, __FILE__, __LINE__ + 1
|
|
52
|
+
def #{method}(...)
|
|
53
|
+
page.method("#{method}").call(...)
|
|
54
|
+
end
|
|
55
|
+
METHOD
|
|
56
|
+
else
|
|
57
|
+
define_method method do |*args, &block|
|
|
58
|
+
page.send method, *args, &block
|
|
59
|
+
end
|
|
53
60
|
end
|
|
54
61
|
end
|
|
55
62
|
end
|
data/lib/capybara/helpers.rb
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
1
|
# frozen_string_literal: true
|
|
3
2
|
|
|
4
3
|
module Capybara
|
|
5
|
-
|
|
6
4
|
# @api private
|
|
7
5
|
module Helpers
|
|
8
|
-
|
|
6
|
+
module_function
|
|
9
7
|
|
|
10
8
|
##
|
|
11
|
-
#
|
|
9
|
+
# @deprecated
|
|
12
10
|
# Normalizes whitespace space by stripping leading and trailing
|
|
13
11
|
# whitespace and replacing sequences of whitespace characters
|
|
14
12
|
# with a single space.
|
|
@@ -17,6 +15,7 @@ module Capybara
|
|
|
17
15
|
# @return [String] Normalized text
|
|
18
16
|
#
|
|
19
17
|
def normalize_whitespace(text)
|
|
18
|
+
Capybara::Helpers.warn 'DEPRECATED: Capybara::Helpers::normalize_whitespace is deprecated, please update your driver'
|
|
20
19
|
text.to_s.gsub(/[[:space:]]+/, ' ').strip
|
|
21
20
|
end
|
|
22
21
|
|
|
@@ -26,90 +25,37 @@ module Capybara
|
|
|
26
25
|
# if text is not a regexp
|
|
27
26
|
#
|
|
28
27
|
# @param [String] text Text to escape
|
|
29
|
-
# @
|
|
28
|
+
# @param [Boolean] exact (false) Whether or not this should be an exact text match
|
|
29
|
+
# @param [Fixnum, Boolean, nil] options Options passed to Regexp.new when creating the Regexp
|
|
30
|
+
# @return [Regexp] Regexp to match the passed in text and options
|
|
30
31
|
#
|
|
31
|
-
def to_regexp(text)
|
|
32
|
-
text
|
|
32
|
+
def to_regexp(text, exact: false, all_whitespace: false, options: nil)
|
|
33
|
+
return text if text.is_a?(Regexp)
|
|
34
|
+
|
|
35
|
+
escaped = Regexp.escape(text)
|
|
36
|
+
escaped = escaped.gsub('\\ ', '[[:blank:]]') if all_whitespace
|
|
37
|
+
escaped = "\\A#{escaped}\\z" if exact
|
|
38
|
+
Regexp.new(escaped, options)
|
|
33
39
|
end
|
|
34
40
|
|
|
35
41
|
##
|
|
36
42
|
#
|
|
37
43
|
# Injects a `<base>` tag into the given HTML code, pointing to
|
|
38
|
-
#
|
|
44
|
+
# {Capybara.configure asset_host}.
|
|
39
45
|
#
|
|
40
46
|
# @param [String] html HTML code to inject into
|
|
47
|
+
# @param [URL] host (Capybara.asset_host) The host from which assets should be loaded
|
|
41
48
|
# @return [String] The modified HTML code
|
|
42
49
|
#
|
|
43
|
-
def inject_asset_host(html)
|
|
44
|
-
if
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return html.clone.insert match.end(0), "<base href='#{Capybara.asset_host}' />"
|
|
50
|
+
def inject_asset_host(html, host: Capybara.asset_host)
|
|
51
|
+
if host && Nokogiri::HTML(html).css('base').empty?
|
|
52
|
+
html.match(/<head[^<]*?>/) do |m|
|
|
53
|
+
return html.clone.insert m.end(0), "<base href='#{host}' />"
|
|
48
54
|
end
|
|
49
55
|
end
|
|
50
|
-
|
|
51
56
|
html
|
|
52
57
|
end
|
|
53
58
|
|
|
54
|
-
##
|
|
55
|
-
#
|
|
56
|
-
# Checks if the given count matches the given count options.
|
|
57
|
-
# Defaults to true if no options are specified. If multiple
|
|
58
|
-
# options are provided, it tests that all conditions are met;
|
|
59
|
-
# however, if :count is supplied, all other options are ignored.
|
|
60
|
-
#
|
|
61
|
-
# @param [Integer] count The actual number. Should be coercible via Integer()
|
|
62
|
-
# @option [Range] between Count must be within the given range
|
|
63
|
-
# @option [Integer] count Count must be exactly this
|
|
64
|
-
# @option [Integer] maximum Count must be smaller than or equal to this value
|
|
65
|
-
# @option [Integer] minimum Count must be larger than or equal to this value
|
|
66
|
-
#
|
|
67
|
-
def matches_count?(count, options={})
|
|
68
|
-
return (Integer(options[:count]) == count) if options[:count]
|
|
69
|
-
return false if options[:maximum] && (Integer(options[:maximum]) < count)
|
|
70
|
-
return false if options[:minimum] && (Integer(options[:minimum]) > count)
|
|
71
|
-
return false if options[:between] && !(options[:between] === count)
|
|
72
|
-
return true
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
##
|
|
76
|
-
#
|
|
77
|
-
# Checks if a count of 0 is valid for the given options hash.
|
|
78
|
-
# Returns false if options hash does not specify any count options.
|
|
79
|
-
#
|
|
80
|
-
def expects_none?(options={})
|
|
81
|
-
if [:count, :maximum, :minimum, :between].any? { |k| options.has_key? k }
|
|
82
|
-
matches_count?(0,options)
|
|
83
|
-
else
|
|
84
|
-
false
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
##
|
|
89
|
-
#
|
|
90
|
-
# Generates a failure message given a description of the query and count
|
|
91
|
-
# options.
|
|
92
|
-
#
|
|
93
|
-
# @param [String] description Description of a query
|
|
94
|
-
# @option [Range] between Count should have been within the given range
|
|
95
|
-
# @option [Integer] count Count should have been exactly this
|
|
96
|
-
# @option [Integer] maximum Count should have been smaller than or equal to this value
|
|
97
|
-
# @option [Integer] minimum Count should have been larger than or equal to this value
|
|
98
|
-
#
|
|
99
|
-
def failure_message(description, options={})
|
|
100
|
-
message = String.new("expected to find #{description}")
|
|
101
|
-
if options[:count]
|
|
102
|
-
message << " #{options[:count]} #{declension('time', 'times', options[:count])}"
|
|
103
|
-
elsif options[:between]
|
|
104
|
-
message << " between #{options[:between].first} and #{options[:between].last} times"
|
|
105
|
-
elsif options[:maximum]
|
|
106
|
-
message << " at most #{options[:maximum]} #{declension('time', 'times', options[:maximum])}"
|
|
107
|
-
elsif options[:minimum]
|
|
108
|
-
message << " at least #{options[:minimum]} #{declension('time', 'times', options[:minimum])}"
|
|
109
|
-
end
|
|
110
|
-
message
|
|
111
|
-
end
|
|
112
|
-
|
|
113
59
|
##
|
|
114
60
|
#
|
|
115
61
|
# A poor man's `pluralize`. Given two declensions, one singular and one
|
|
@@ -121,20 +67,65 @@ module Capybara
|
|
|
121
67
|
# @param [Integer] count The number of items
|
|
122
68
|
#
|
|
123
69
|
def declension(singular, plural, count)
|
|
124
|
-
|
|
125
|
-
|
|
70
|
+
count == 1 ? singular : plural
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def filter_backtrace(trace)
|
|
74
|
+
return 'No backtrace' unless trace
|
|
75
|
+
|
|
76
|
+
filter = %r{lib/capybara/|lib/rspec/|lib/minitest/}
|
|
77
|
+
new_trace = trace.take_while { |line| line !~ filter }
|
|
78
|
+
new_trace = trace.reject { |line| line =~ filter } if new_trace.empty?
|
|
79
|
+
new_trace = trace.dup if new_trace.empty?
|
|
80
|
+
|
|
81
|
+
new_trace.first.split(/:in /, 2).first
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def warn(message, uplevel: 1)
|
|
85
|
+
return Kernel.warn(message, uplevel: uplevel) if RUBY_VERSION >= '2.6'
|
|
86
|
+
|
|
87
|
+
# TODO: Remove when we drop support for Ruby 2.5
|
|
88
|
+
# Workaround for emulating `warn '...', uplevel: n` in Ruby 2.5 or lower.
|
|
89
|
+
if (match = /^(?<file>.+?):(?<line>\d+)(?::in `.*')?/.match(caller[uplevel]))
|
|
90
|
+
location = [match[:file], match[:line]].join(':')
|
|
91
|
+
Kernel.warn "#{location}: #{message}"
|
|
126
92
|
else
|
|
127
|
-
|
|
93
|
+
Kernel.warn message
|
|
128
94
|
end
|
|
129
95
|
end
|
|
130
96
|
|
|
131
97
|
if defined?(Process::CLOCK_MONOTONIC)
|
|
132
|
-
def monotonic_time
|
|
133
|
-
Process.clock_gettime Process::CLOCK_MONOTONIC
|
|
134
|
-
end
|
|
98
|
+
def monotonic_time; Process.clock_gettime Process::CLOCK_MONOTONIC; end
|
|
135
99
|
else
|
|
136
|
-
def monotonic_time
|
|
137
|
-
|
|
100
|
+
def monotonic_time; Time.now.to_f; end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def timer(expire_in:)
|
|
104
|
+
Timer.new(expire_in)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
class Timer
|
|
108
|
+
def initialize(expire_in)
|
|
109
|
+
@start = current
|
|
110
|
+
@expire_in = expire_in
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def expired?
|
|
114
|
+
if stalled?
|
|
115
|
+
raise Capybara::FrozenInTime, 'Time appears to be frozen. Capybara does not work with libraries which freeze time, consider using time travelling instead'
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
current - @start >= @expire_in
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def stalled?
|
|
122
|
+
@start == current
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
private
|
|
126
|
+
|
|
127
|
+
def current
|
|
128
|
+
Capybara::Helpers.monotonic_time
|
|
138
129
|
end
|
|
139
130
|
end
|
|
140
131
|
end
|