capybara 2.18.0 → 3.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +1 -1
- data/History.md +945 -12
- data/License.txt +1 -1
- data/README.md +264 -90
- data/lib/capybara/config.rb +29 -57
- data/lib/capybara/cucumber.rb +2 -3
- data/lib/capybara/driver/base.rb +35 -18
- data/lib/capybara/driver/node.rb +40 -10
- data/lib/capybara/dsl.rb +10 -7
- data/lib/capybara/helpers.rb +70 -31
- data/lib/capybara/minitest/spec.rb +185 -83
- data/lib/capybara/minitest.rb +232 -112
- data/lib/capybara/node/actions.rb +274 -171
- data/lib/capybara/node/base.rb +42 -34
- data/lib/capybara/node/document.rb +15 -3
- data/lib/capybara/node/document_matchers.rb +19 -21
- data/lib/capybara/node/element.rb +362 -135
- data/lib/capybara/node/finders.rb +151 -137
- data/lib/capybara/node/matchers.rb +394 -209
- data/lib/capybara/node/simple.rb +59 -26
- data/lib/capybara/node/whitespace_normalizer.rb +81 -0
- data/lib/capybara/queries/active_element_query.rb +18 -0
- data/lib/capybara/queries/ancestor_query.rb +12 -9
- data/lib/capybara/queries/base_query.rb +39 -28
- data/lib/capybara/queries/current_path_query.rb +21 -27
- data/lib/capybara/queries/match_query.rb +14 -7
- data/lib/capybara/queries/selector_query.rb +659 -149
- data/lib/capybara/queries/sibling_query.rb +11 -9
- data/lib/capybara/queries/style_query.rb +45 -0
- data/lib/capybara/queries/text_query.rb +56 -38
- data/lib/capybara/queries/title_query.rb +8 -11
- data/lib/capybara/rack_test/browser.rb +114 -42
- data/lib/capybara/rack_test/css_handlers.rb +6 -4
- data/lib/capybara/rack_test/driver.rb +22 -17
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +93 -58
- data/lib/capybara/rack_test/node.rb +184 -81
- data/lib/capybara/rails.rb +3 -7
- data/lib/capybara/registration_container.rb +41 -0
- data/lib/capybara/registrations/drivers.rb +42 -0
- data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
- data/lib/capybara/registrations/servers.rb +66 -0
- data/lib/capybara/result.rb +97 -63
- data/lib/capybara/rspec/features.rb +17 -50
- data/lib/capybara/rspec/matcher_proxies.rb +52 -15
- data/lib/capybara/rspec/matchers/base.rb +113 -0
- data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
- data/lib/capybara/rspec/matchers/compound.rb +88 -0
- data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
- data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
- data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
- data/lib/capybara/rspec/matchers/have_selector.rb +69 -0
- data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
- data/lib/capybara/rspec/matchers/have_text.rb +33 -0
- data/lib/capybara/rspec/matchers/have_title.rb +29 -0
- data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
- data/lib/capybara/rspec/matchers/match_style.rb +43 -0
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
- data/lib/capybara/rspec/matchers.rb +146 -310
- data/lib/capybara/rspec.rb +7 -11
- data/lib/capybara/selector/builders/css_builder.rb +84 -0
- data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
- data/lib/capybara/selector/css.rb +85 -13
- data/lib/capybara/selector/definition/button.rb +68 -0
- data/lib/capybara/selector/definition/checkbox.rb +26 -0
- data/lib/capybara/selector/definition/css.rb +10 -0
- data/lib/capybara/selector/definition/datalist_input.rb +35 -0
- data/lib/capybara/selector/definition/datalist_option.rb +25 -0
- data/lib/capybara/selector/definition/element.rb +28 -0
- data/lib/capybara/selector/definition/field.rb +40 -0
- data/lib/capybara/selector/definition/fieldset.rb +14 -0
- data/lib/capybara/selector/definition/file_field.rb +13 -0
- data/lib/capybara/selector/definition/fillable_field.rb +33 -0
- data/lib/capybara/selector/definition/frame.rb +17 -0
- data/lib/capybara/selector/definition/id.rb +6 -0
- data/lib/capybara/selector/definition/label.rb +62 -0
- data/lib/capybara/selector/definition/link.rb +55 -0
- data/lib/capybara/selector/definition/link_or_button.rb +16 -0
- data/lib/capybara/selector/definition/option.rb +27 -0
- data/lib/capybara/selector/definition/radio_button.rb +27 -0
- data/lib/capybara/selector/definition/select.rb +81 -0
- data/lib/capybara/selector/definition/table.rb +109 -0
- data/lib/capybara/selector/definition/table_row.rb +21 -0
- data/lib/capybara/selector/definition/xpath.rb +5 -0
- data/lib/capybara/selector/definition.rb +280 -0
- data/lib/capybara/selector/filter.rb +2 -17
- data/lib/capybara/selector/filter_set.rb +80 -33
- data/lib/capybara/selector/filters/base.rb +50 -6
- data/lib/capybara/selector/filters/expression_filter.rb +8 -26
- data/lib/capybara/selector/filters/locator_filter.rb +29 -0
- data/lib/capybara/selector/filters/node_filter.rb +16 -12
- data/lib/capybara/selector/regexp_disassembler.rb +211 -0
- data/lib/capybara/selector/selector.rb +93 -210
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +475 -523
- data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
- data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
- data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
- data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
- data/lib/capybara/selenium/driver.rb +298 -267
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +84 -0
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
- data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
- data/lib/capybara/selenium/extensions/find.rb +110 -0
- data/lib/capybara/selenium/extensions/html5_drag.rb +229 -0
- data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
- data/lib/capybara/selenium/extensions/scroll.rb +76 -0
- data/lib/capybara/selenium/node.rb +517 -145
- data/lib/capybara/selenium/nodes/chrome_node.rb +125 -0
- data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +136 -0
- data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
- data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
- data/lib/capybara/selenium/patches/atoms.rb +18 -0
- data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
- data/lib/capybara/selenium/patches/logs.rb +45 -0
- data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
- data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
- data/lib/capybara/server/animation_disabler.rb +80 -0
- data/lib/capybara/server/checker.rb +44 -0
- data/lib/capybara/server/middleware.rb +71 -0
- data/lib/capybara/server.rb +59 -67
- data/lib/capybara/session/config.rb +81 -67
- data/lib/capybara/session/matchers.rb +28 -20
- data/lib/capybara/session.rb +337 -365
- data/lib/capybara/spec/public/jquery.js +5 -5
- data/lib/capybara/spec/public/offset.js +6 -0
- data/lib/capybara/spec/public/test.js +151 -12
- data/lib/capybara/spec/session/accept_alert_spec.rb +12 -11
- data/lib/capybara/spec/session/accept_confirm_spec.rb +6 -5
- data/lib/capybara/spec/session/accept_prompt_spec.rb +10 -10
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +161 -57
- data/lib/capybara/spec/session/ancestor_spec.rb +27 -24
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +68 -38
- data/lib/capybara/spec/session/assert_current_path_spec.rb +75 -0
- data/lib/capybara/spec/session/assert_selector_spec.rb +143 -0
- data/lib/capybara/spec/session/assert_style_spec.rb +26 -0
- data/lib/capybara/spec/session/assert_text_spec.rb +258 -0
- data/lib/capybara/spec/session/{assert_title.rb → assert_title_spec.rb} +22 -12
- data/lib/capybara/spec/session/attach_file_spec.rb +144 -69
- data/lib/capybara/spec/session/body_spec.rb +12 -13
- data/lib/capybara/spec/session/check_spec.rb +117 -55
- data/lib/capybara/spec/session/choose_spec.rb +64 -31
- data/lib/capybara/spec/session/click_button_spec.rb +231 -173
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +55 -35
- data/lib/capybara/spec/session/click_link_spec.rb +93 -58
- data/lib/capybara/spec/session/current_scope_spec.rb +12 -11
- data/lib/capybara/spec/session/current_url_spec.rb +57 -39
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +4 -4
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +3 -2
- data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +11 -9
- data/lib/capybara/spec/session/element/match_css_spec.rb +18 -10
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +9 -7
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +71 -57
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +8 -7
- data/lib/capybara/spec/session/evaluate_script_spec.rb +29 -8
- data/lib/capybara/spec/session/execute_script_spec.rb +10 -8
- data/lib/capybara/spec/session/fill_in_spec.rb +134 -43
- data/lib/capybara/spec/session/find_button_spec.rb +25 -24
- data/lib/capybara/spec/session/find_by_id_spec.rb +10 -9
- data/lib/capybara/spec/session/find_field_spec.rb +37 -41
- data/lib/capybara/spec/session/find_link_spec.rb +46 -17
- data/lib/capybara/spec/session/find_spec.rb +260 -145
- data/lib/capybara/spec/session/first_spec.rb +80 -52
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +33 -20
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +52 -32
- data/lib/capybara/spec/session/go_back_spec.rb +2 -1
- data/lib/capybara/spec/session/go_forward_spec.rb +2 -1
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +31 -31
- data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +29 -0
- data/lib/capybara/spec/session/has_button_spec.rb +100 -13
- data/lib/capybara/spec/session/has_css_spec.rb +272 -137
- data/lib/capybara/spec/session/has_current_path_spec.rb +60 -61
- data/lib/capybara/spec/session/has_element_spec.rb +47 -0
- data/lib/capybara/spec/session/has_field_spec.rb +139 -59
- data/lib/capybara/spec/session/has_link_spec.rb +47 -6
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +42 -40
- data/lib/capybara/spec/session/has_select_spec.rb +107 -72
- data/lib/capybara/spec/session/has_selector_spec.rb +120 -71
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +183 -5
- data/lib/capybara/spec/session/has_text_spec.rb +106 -62
- data/lib/capybara/spec/session/has_title_spec.rb +20 -14
- data/lib/capybara/spec/session/has_xpath_spec.rb +57 -38
- data/lib/capybara/spec/session/{headers.rb → headers_spec.rb} +3 -2
- data/lib/capybara/spec/session/html_spec.rb +14 -6
- data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
- data/lib/capybara/spec/session/node_spec.rb +1024 -153
- data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
- data/lib/capybara/spec/session/refresh_spec.rb +12 -6
- data/lib/capybara/spec/session/reset_session_spec.rb +82 -35
- data/lib/capybara/spec/session/{response_code.rb → response_code_spec.rb} +2 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +3 -2
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +8 -12
- data/lib/capybara/spec/session/save_page_spec.rb +42 -55
- data/lib/capybara/spec/session/save_screenshot_spec.rb +16 -14
- data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/scroll_spec.rb +119 -0
- data/lib/capybara/spec/session/select_spec.rb +107 -81
- data/lib/capybara/spec/session/selectors_spec.rb +52 -19
- data/lib/capybara/spec/session/sibling_spec.rb +10 -10
- data/lib/capybara/spec/session/text_spec.rb +37 -21
- data/lib/capybara/spec/session/title_spec.rb +17 -5
- data/lib/capybara/spec/session/uncheck_spec.rb +43 -23
- data/lib/capybara/spec/session/unselect_spec.rb +39 -38
- data/lib/capybara/spec/session/visit_spec.rb +85 -53
- data/lib/capybara/spec/session/window/become_closed_spec.rb +24 -20
- data/lib/capybara/spec/session/window/current_window_spec.rb +5 -3
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +5 -3
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +27 -22
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +12 -6
- data/lib/capybara/spec/session/window/window_spec.rb +97 -63
- data/lib/capybara/spec/session/window/windows_spec.rb +12 -10
- data/lib/capybara/spec/session/window/within_window_spec.rb +31 -86
- data/lib/capybara/spec/session/within_spec.rb +83 -44
- data/lib/capybara/spec/spec_helper.rb +54 -44
- data/lib/capybara/spec/test_app.rb +158 -43
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/form.erb +163 -42
- data/lib/capybara/spec/views/frame_child.erb +4 -3
- data/lib/capybara/spec/views/frame_one.erb +2 -1
- data/lib/capybara/spec/views/frame_parent.erb +1 -1
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +2 -1
- data/lib/capybara/spec/views/layout.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +47 -0
- data/lib/capybara/spec/views/offset.erb +33 -0
- data/lib/capybara/spec/views/path.erb +2 -2
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/react.erb +45 -0
- data/lib/capybara/spec/views/scroll.erb +21 -0
- data/lib/capybara/spec/views/spatial.erb +31 -0
- data/lib/capybara/spec/views/tables.erb +68 -1
- data/lib/capybara/spec/views/with_animation.erb +81 -0
- data/lib/capybara/spec/views/with_base_tag.erb +2 -2
- data/lib/capybara/spec/views/with_dragula.erb +24 -0
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
- data/lib/capybara/spec/views/with_hover.erb +3 -2
- data/lib/capybara/spec/views/with_hover1.erb +10 -0
- data/lib/capybara/spec/views/with_html.erb +69 -12
- data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +30 -5
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_namespace.erb +21 -0
- data/lib/capybara/spec/views/with_scope.erb +2 -2
- data/lib/capybara/spec/views/with_scope_other.erb +6 -0
- data/lib/capybara/spec/views/with_shadow.erb +31 -0
- data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
- data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
- data/lib/capybara/spec/views/with_windows.erb +1 -1
- data/lib/capybara/spec/views/within_frames.erb +5 -2
- data/lib/capybara/version.rb +2 -1
- data/lib/capybara/window.rb +36 -34
- data/lib/capybara.rb +134 -107
- data/spec/basic_node_spec.rb +60 -34
- data/spec/capybara_spec.rb +63 -88
- data/spec/counter_spec.rb +35 -0
- data/spec/css_builder_spec.rb +101 -0
- data/spec/css_splitter_spec.rb +38 -0
- data/spec/dsl_spec.rb +85 -64
- data/spec/filter_set_spec.rb +27 -9
- data/spec/fixtures/certificate.pem +25 -0
- data/spec/fixtures/key.pem +27 -0
- data/spec/fixtures/selenium_driver_rspec_failure.rb +6 -5
- data/spec/fixtures/selenium_driver_rspec_success.rb +6 -5
- data/spec/minitest_spec.rb +52 -7
- data/spec/minitest_spec_spec.rb +94 -63
- data/spec/per_session_config_spec.rb +14 -13
- data/spec/rack_test_spec.rb +194 -125
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +111 -50
- data/spec/rspec/features_spec.rb +37 -31
- data/spec/rspec/scenarios_spec.rb +10 -8
- data/spec/rspec/shared_spec_matchers.rb +473 -422
- data/spec/rspec/views_spec.rb +5 -3
- data/spec/rspec_matchers_spec.rb +52 -11
- data/spec/rspec_spec.rb +109 -89
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +397 -68
- data/spec/selenium_spec_chrome.rb +187 -40
- data/spec/selenium_spec_chrome_remote.rb +96 -0
- data/spec/selenium_spec_edge.rb +60 -0
- data/spec/selenium_spec_firefox.rb +201 -41
- data/spec/selenium_spec_firefox_remote.rb +94 -0
- data/spec/selenium_spec_ie.rb +149 -0
- data/spec/selenium_spec_safari.rb +162 -0
- data/spec/server_spec.rb +213 -102
- data/spec/session_spec.rb +53 -16
- data/spec/shared_selenium_node.rb +79 -0
- data/spec/shared_selenium_session.rb +473 -122
- data/spec/spec_helper.rb +126 -7
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +355 -73
- data/.yard/templates_custom/default/class/html/selectors.erb +0 -38
- data/.yard/templates_custom/default/class/html/setup.rb +0 -17
- data/.yard/yard_extensions.rb +0 -78
- data/lib/capybara/query.rb +0 -7
- data/lib/capybara/rspec/compound.rb +0 -95
- data/lib/capybara/spec/session/assert_current_path.rb +0 -72
- data/lib/capybara/spec/session/assert_selector.rb +0 -148
- data/lib/capybara/spec/session/assert_text.rb +0 -234
- data/lib/capybara/spec/session/source_spec.rb +0 -0
- data/lib/capybara/spec/views/with_title.erb +0 -5
- data/spec/selenium_spec_marionette.rb +0 -127
|
@@ -1,215 +1,566 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'spec_helper'
|
|
3
|
-
require
|
|
4
|
+
require 'selenium-webdriver'
|
|
4
5
|
|
|
5
|
-
RSpec.shared_examples
|
|
6
|
-
let(:session) {session}
|
|
6
|
+
RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
7
|
+
let(:session) { session }
|
|
7
8
|
|
|
8
9
|
context 'with selenium driver' do
|
|
9
|
-
before do
|
|
10
|
-
@session = session
|
|
11
|
-
end
|
|
12
|
-
|
|
13
10
|
describe '#driver' do
|
|
14
|
-
it
|
|
15
|
-
expect(
|
|
11
|
+
it 'should be a selenium driver' do
|
|
12
|
+
expect(session.driver).to be_an_instance_of(Capybara::Selenium::Driver)
|
|
16
13
|
end
|
|
17
14
|
end
|
|
18
15
|
|
|
19
16
|
describe '#mode' do
|
|
20
|
-
it
|
|
21
|
-
expect(
|
|
17
|
+
it 'should remember the mode' do
|
|
18
|
+
expect(session.mode).to eq(mode)
|
|
22
19
|
end
|
|
23
20
|
end
|
|
24
21
|
|
|
25
|
-
describe
|
|
26
|
-
it
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
expect(
|
|
22
|
+
describe '#reset!' do
|
|
23
|
+
it 'freshly reset session should not be touched' do
|
|
24
|
+
session.instance_variable_set(:@touched, true)
|
|
25
|
+
session.reset!
|
|
26
|
+
expect(session.instance_variable_get(:@touched)).to be false
|
|
30
27
|
end
|
|
31
28
|
end
|
|
32
29
|
|
|
33
|
-
describe
|
|
30
|
+
describe 'exit codes' do
|
|
31
|
+
let(:env) { { 'SELENIUM_BROWSER' => session.driver.options[:browser].to_s } }
|
|
32
|
+
let!(:orig_dir) { Dir.getwd }
|
|
33
|
+
|
|
34
34
|
before do
|
|
35
|
-
@current_dir = Dir.getwd
|
|
36
35
|
Dir.chdir(File.join(File.dirname(__FILE__), '..'))
|
|
37
|
-
@env = { 'SELENIUM_BROWSER' => @session.driver.options[:browser].to_s }
|
|
38
|
-
@env['LEGACY_FIREFOX'] = 'TRUE' if mode == :selenium_firefox
|
|
39
36
|
end
|
|
40
37
|
|
|
41
38
|
after do
|
|
42
|
-
Dir.chdir(
|
|
39
|
+
Dir.chdir(orig_dir)
|
|
43
40
|
end
|
|
44
41
|
|
|
45
|
-
it
|
|
46
|
-
skip if
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
it 'should have return code 1 when running selenium_driver_rspec_failure.rb' do
|
|
43
|
+
skip 'only setup for local non-headless' if headless_or_remote?
|
|
44
|
+
skip 'Not setup for edge' if edge?(session)
|
|
45
|
+
|
|
46
|
+
system(env, 'rspec spec/fixtures/selenium_driver_rspec_failure.rb', out: File::NULL, err: File::NULL)
|
|
47
|
+
expect($CHILD_STATUS.exitstatus).to eq(1)
|
|
49
48
|
end
|
|
50
49
|
|
|
51
|
-
it
|
|
52
|
-
skip if
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
it 'should have return code 0 when running selenium_driver_rspec_success.rb' do
|
|
51
|
+
skip 'only setup for local non-headless' if headless_or_remote?
|
|
52
|
+
skip 'Not setup for edge' if edge?(session)
|
|
53
|
+
|
|
54
|
+
system(env, 'rspec spec/fixtures/selenium_driver_rspec_success.rb', out: File::NULL, err: File::NULL)
|
|
55
|
+
expect($CHILD_STATUS.exitstatus).to eq(0)
|
|
55
56
|
end
|
|
56
57
|
end
|
|
57
58
|
|
|
58
|
-
describe
|
|
59
|
-
it
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
expect{
|
|
59
|
+
describe '#accept_alert', requires: [:modals] do
|
|
60
|
+
it 'supports a blockless mode' do
|
|
61
|
+
session.visit('/with_js')
|
|
62
|
+
session.click_link('Open alert')
|
|
63
|
+
session.accept_alert
|
|
64
|
+
expect { session.driver.browser.switch_to.alert }.to raise_error(session.driver.send(:modal_error))
|
|
64
65
|
end
|
|
65
66
|
|
|
66
|
-
it
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
it 'can be called before visiting' do
|
|
68
|
+
session.accept_alert 'Initial alert' do
|
|
69
|
+
session.visit('/initial_alert')
|
|
69
70
|
end
|
|
70
|
-
expect(
|
|
71
|
+
expect(session).to have_text('Initial alert page')
|
|
71
72
|
end
|
|
72
73
|
end
|
|
73
74
|
|
|
74
|
-
|
|
75
|
+
describe '#fill_in_with empty string and no options' do
|
|
75
76
|
it 'should trigger change when clearing a field' do
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
session.visit('/with_js')
|
|
78
|
+
session.fill_in('with_change_event', with: '')
|
|
78
79
|
# click outside the field to trigger the change event
|
|
79
|
-
|
|
80
|
-
expect(
|
|
80
|
+
session.find(:css, 'body').click
|
|
81
|
+
expect(session).to have_selector(:css, '.change_event_triggered', match: :one)
|
|
81
82
|
end
|
|
82
83
|
end
|
|
83
84
|
|
|
84
|
-
|
|
85
|
+
describe '#fill_in with { :clear => :backspace } fill_option', requires: [:js] do
|
|
86
|
+
before do
|
|
87
|
+
# Firefox has an issue with change events if the main window doesn't think it's focused
|
|
88
|
+
session.execute_script('window.focus()')
|
|
89
|
+
end
|
|
90
|
+
|
|
85
91
|
it 'should fill in a field, replacing an existing value' do
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
92
|
+
session.visit('/form')
|
|
93
|
+
session.fill_in('form_first_name',
|
|
94
|
+
with: 'Harry',
|
|
95
|
+
fill_options: { clear: :backspace })
|
|
96
|
+
expect(session.find(:fillable_field, 'form_first_name').value).to eq('Harry')
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'should fill in a field, replacing an existing value, even with caret position' do
|
|
100
|
+
session.visit('/form')
|
|
101
|
+
session.find(:css, '#form_first_name').execute_script <<-JS
|
|
102
|
+
this.focus();
|
|
103
|
+
this.setSelectionRange(0, 0);
|
|
104
|
+
JS
|
|
105
|
+
|
|
106
|
+
session.fill_in('form_first_name',
|
|
107
|
+
with: 'Harry',
|
|
108
|
+
fill_options: { clear: :backspace })
|
|
109
|
+
expect(session.find(:fillable_field, 'form_first_name').value).to eq('Harry')
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it 'should fill in if the option is set via global option' do
|
|
113
|
+
Capybara.default_set_options = { clear: :backspace }
|
|
114
|
+
session.visit('/form')
|
|
115
|
+
session.fill_in('form_first_name', with: 'Thomas')
|
|
116
|
+
expect(session.find(:fillable_field, 'form_first_name').value).to eq('Thomas')
|
|
90
117
|
end
|
|
91
118
|
|
|
92
119
|
it 'should only trigger onchange once' do
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
120
|
+
session.visit('/with_js')
|
|
121
|
+
sleep 2 if safari?(session) # Safari needs a delay (to load event handlers maybe ???)
|
|
122
|
+
session.fill_in('with_change_event',
|
|
123
|
+
with: 'some value',
|
|
124
|
+
fill_options: { clear: :backspace })
|
|
96
125
|
# click outside the field to trigger the change event
|
|
97
|
-
|
|
98
|
-
expect(
|
|
126
|
+
session.find(:css, '#with_focus_event').click
|
|
127
|
+
expect(session.find(:css, '.change_event_triggered', match: :one, wait: 5)).to have_text 'some value'
|
|
99
128
|
end
|
|
100
129
|
|
|
101
130
|
it 'should trigger change when clearing field' do
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
131
|
+
session.visit('/with_js')
|
|
132
|
+
session.fill_in('with_change_event',
|
|
133
|
+
with: '',
|
|
134
|
+
fill_options: { clear: :backspace })
|
|
105
135
|
# click outside the field to trigger the change event
|
|
106
|
-
|
|
107
|
-
expect(
|
|
136
|
+
session.find(:css, '#with_focus_event').click
|
|
137
|
+
expect(session).to have_selector(:css, '.change_event_triggered', match: :one, wait: 5)
|
|
108
138
|
end
|
|
109
139
|
|
|
110
140
|
it 'should trigger input event field_value.length times' do
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
141
|
+
session.visit('/with_js')
|
|
142
|
+
session.fill_in('with_change_event',
|
|
143
|
+
with: '',
|
|
144
|
+
fill_options: { clear: :backspace })
|
|
114
145
|
# click outside the field to trigger the change event
|
|
115
|
-
|
|
116
|
-
|
|
146
|
+
# session.find(:css, 'body').click
|
|
147
|
+
session.find(:css, 'h1', text: 'FooBar').click
|
|
148
|
+
expect(session).to have_xpath('//p[@class="input_event_triggered"]', count: 13)
|
|
117
149
|
end
|
|
118
150
|
end
|
|
119
151
|
|
|
120
|
-
|
|
152
|
+
describe '#fill_in with { clear: :none } fill_options' do
|
|
121
153
|
it 'should append to content in a field' do
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
154
|
+
pending 'Safari overwrites by default - need to figure out a workaround' if safari?(session)
|
|
155
|
+
|
|
156
|
+
session.visit('/form')
|
|
157
|
+
session.fill_in('form_first_name',
|
|
158
|
+
with: 'Harry',
|
|
159
|
+
fill_options: { clear: :none })
|
|
160
|
+
expect(session.find(:fillable_field, 'form_first_name').value).to eq('JohnHarry')
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it 'works with rapid fill' do
|
|
164
|
+
pending 'Safari overwrites by default - need to figure out a workaround' if safari?(session)
|
|
165
|
+
|
|
166
|
+
long_string = (0...60).map { |i| ((i % 26) + 65).chr }.join
|
|
167
|
+
session.visit('/form')
|
|
168
|
+
session.fill_in('form_first_name', with: long_string, fill_options: { clear: :none })
|
|
169
|
+
expect(session.find(:fillable_field, 'form_first_name').value).to eq("John#{long_string}")
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
describe '#fill_in with Date' do
|
|
174
|
+
before do
|
|
175
|
+
session.visit('/form')
|
|
176
|
+
session.find(:css, '#form_date').execute_script <<-JS
|
|
177
|
+
window.capybara_formDateFiredEvents = [];
|
|
178
|
+
var fd = this;
|
|
179
|
+
['focus', 'input', 'change'].forEach(function(eventType) {
|
|
180
|
+
fd.addEventListener(eventType, function() { window.capybara_formDateFiredEvents.push(eventType); });
|
|
181
|
+
});
|
|
182
|
+
JS
|
|
183
|
+
# work around weird FF issue where it would create an extra focus issue in some cases
|
|
184
|
+
session.find(:css, 'h1', text: 'Form').click
|
|
185
|
+
# session.find(:css, 'body').click
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it 'should generate standard events on changing value' do
|
|
189
|
+
pending "IE 11 doesn't support date input type" if ie?(session)
|
|
190
|
+
session.fill_in('form_date', with: Date.today)
|
|
191
|
+
expect(session.evaluate_script('window.capybara_formDateFiredEvents')).to eq %w[focus input change]
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it 'should not generate input and change events if the value is not changed' do
|
|
195
|
+
pending "IE 11 doesn't support date input type" if ie?(session)
|
|
196
|
+
session.fill_in('form_date', with: Date.today)
|
|
197
|
+
session.fill_in('form_date', with: Date.today)
|
|
198
|
+
# Chrome adds an extra focus for some reason - ok for now
|
|
199
|
+
expect(session.evaluate_script('window.capybara_formDateFiredEvents')).to eq(%w[focus input change])
|
|
126
200
|
end
|
|
127
201
|
end
|
|
128
202
|
|
|
129
|
-
|
|
203
|
+
describe '#fill_in with { clear: Array } fill_options' do
|
|
130
204
|
it 'should pass the array through to the element' do
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
expect(
|
|
205
|
+
# this is mainly for use with [[:control, 'a'], :backspace] - however since that is platform dependant I'm testing with something less useful
|
|
206
|
+
session.visit('/form')
|
|
207
|
+
session.fill_in('form_first_name',
|
|
208
|
+
with: 'Harry',
|
|
209
|
+
fill_options: { clear: [[:shift, 'abc'], :backspace] })
|
|
210
|
+
expect(session.find(:fillable_field, 'form_first_name').value).to eq('JohnABHarry')
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
describe '#fill_in with Emoji' do
|
|
215
|
+
it 'sends emojis' do
|
|
216
|
+
session.visit('/form')
|
|
217
|
+
session.fill_in('form_first_name', with: 'a😀cd😴 🛌🏽🇵🇹 e🤾🏽♀️f')
|
|
218
|
+
expect(session.find(:fillable_field, 'form_first_name').value).to eq('a😀cd😴 🛌🏽🇵🇹 e🤾🏽♀️f')
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
describe '#send_keys' do
|
|
223
|
+
it 'defaults to sending keys to the active_element' do
|
|
224
|
+
session.visit('/form')
|
|
225
|
+
|
|
226
|
+
expect(session.active_element).to match_selector(:css, 'body')
|
|
227
|
+
|
|
228
|
+
session.send_keys(:tab)
|
|
229
|
+
|
|
230
|
+
expect(session.active_element).to match_selector(:css, '[tabindex="1"]')
|
|
137
231
|
end
|
|
138
232
|
end
|
|
139
233
|
|
|
140
|
-
describe
|
|
141
|
-
it
|
|
234
|
+
describe '#path' do
|
|
235
|
+
it 'returns xpath' do
|
|
142
236
|
# this is here because it is testing for an XPath that is specific to the algorithm used in the selenium driver
|
|
143
|
-
|
|
144
|
-
element =
|
|
145
|
-
expect(element.path).to eq('/
|
|
237
|
+
session.visit('/path')
|
|
238
|
+
element = session.find(:link, 'Second Link')
|
|
239
|
+
expect(element.path).to eq('/HTML/BODY[1]/DIV[2]/A[1]')
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it 'handles namespaces in xhtml' do
|
|
243
|
+
pending "IE 11 doesn't handle all XPath querys (namespace-uri, etc)" if ie?(session)
|
|
244
|
+
session.visit '/with_namespace'
|
|
245
|
+
rect = session.find(:css, 'div svg rect:first-of-type')
|
|
246
|
+
expect(rect.path).to eq("/HTML/BODY[1]/DIV[1]/*[local-name()='svg' and namespace-uri()='http://www.w3.org/2000/svg'][1]/*[local-name()='rect' and namespace-uri()='http://www.w3.org/2000/svg'][1]")
|
|
247
|
+
expect(session.find(:xpath, rect.path)).to eq rect
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it 'handles default namespaces in html5' do
|
|
251
|
+
pending "IE 11 doesn't handle all XPath querys (namespace-uri, etc)" if ie?(session)
|
|
252
|
+
session.visit '/with_html5_svg'
|
|
253
|
+
rect = session.find(:css, 'div svg rect:first-of-type')
|
|
254
|
+
expect(rect.path).to eq("/HTML/BODY[1]/DIV[1]/*[local-name()='svg' and namespace-uri()='http://www.w3.org/2000/svg'][1]/*[local-name()='rect' and namespace-uri()='http://www.w3.org/2000/svg'][1]")
|
|
255
|
+
expect(session.find(:xpath, rect.path)).to eq rect
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it 'handles case sensitive element names' do
|
|
259
|
+
pending "IE 11 doesn't handle all XPath querys (namespace-uri, etc)" if ie?(session)
|
|
260
|
+
session.visit '/with_namespace'
|
|
261
|
+
els = session.all(:css, 'div *', visible: :all)
|
|
262
|
+
expect { els.map(&:path) }.not_to raise_error
|
|
263
|
+
lg = session.find(:css, 'div linearGradient', visible: :all)
|
|
264
|
+
expect(session.find(:xpath, lg.path, visible: :all)).to eq lg
|
|
146
265
|
end
|
|
147
266
|
end
|
|
148
267
|
|
|
149
|
-
describe
|
|
150
|
-
it
|
|
151
|
-
|
|
152
|
-
elements =
|
|
268
|
+
describe 'all with disappearing elements' do
|
|
269
|
+
it 'ignores stale elements in results' do
|
|
270
|
+
session.visit('/path')
|
|
271
|
+
elements = session.all(:link) { |_node| raise Selenium::WebDriver::Error::StaleElementReferenceError }
|
|
153
272
|
expect(elements.size).to eq 0
|
|
154
273
|
end
|
|
155
274
|
end
|
|
156
275
|
|
|
157
|
-
describe
|
|
158
|
-
it
|
|
159
|
-
|
|
160
|
-
element =
|
|
161
|
-
expect(element).to eq
|
|
276
|
+
describe '#evaluate_script' do
|
|
277
|
+
it 'can return an element' do
|
|
278
|
+
session.visit('/form')
|
|
279
|
+
element = session.evaluate_script("document.getElementById('form_title')")
|
|
280
|
+
expect(element).to eq session.find(:id, 'form_title')
|
|
162
281
|
end
|
|
163
282
|
|
|
164
|
-
it
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
end
|
|
170
|
-
expect(elements).to eq @session.find(:css, '#form_city').all(:css, 'option').to_a
|
|
283
|
+
it 'returns a shadow root' do
|
|
284
|
+
session.visit('/with_shadow')
|
|
285
|
+
shadow = session.find(:css, '#shadow_host')
|
|
286
|
+
element = session.evaluate_script('arguments[0].shadowRoot', shadow)
|
|
287
|
+
expect(element).to be_instance_of(Capybara::Node::Element)
|
|
171
288
|
end
|
|
172
289
|
|
|
173
|
-
it
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
expect(
|
|
177
|
-
|
|
290
|
+
it 'can return arrays of nested elements' do
|
|
291
|
+
session.visit('/form')
|
|
292
|
+
elements = session.evaluate_script('document.querySelectorAll("#form_city option")')
|
|
293
|
+
expect(elements).to all(be_instance_of Capybara::Node::Element)
|
|
294
|
+
expect(elements).to eq session.find(:css, '#form_city').all(:css, 'option').to_a
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
it 'can return hashes with elements' do
|
|
298
|
+
session.visit('/form')
|
|
299
|
+
result = session.evaluate_script("{ a: document.getElementById('form_title'), b: {c: document.querySelectorAll('#form_city option')}}")
|
|
300
|
+
expect(result).to eq(
|
|
301
|
+
'a' => session.find(:id, 'form_title'),
|
|
178
302
|
'b' => {
|
|
179
|
-
'c' =>
|
|
303
|
+
'c' => session.find(:css, '#form_city').all(:css, 'option').to_a
|
|
180
304
|
}
|
|
181
|
-
|
|
305
|
+
)
|
|
182
306
|
end
|
|
183
307
|
|
|
184
|
-
describe
|
|
185
|
-
it
|
|
186
|
-
|
|
308
|
+
describe '#evaluate_async_script' do
|
|
309
|
+
it 'will timeout if the script takes too long' do
|
|
310
|
+
skip 'safaridriver returns the wrong error type' if safari?(session)
|
|
311
|
+
session.visit('/with_js')
|
|
187
312
|
expect do
|
|
188
|
-
|
|
189
|
-
|
|
313
|
+
session.using_wait_time(1) do
|
|
314
|
+
session.evaluate_async_script('var cb = arguments[0]; setTimeout(function(){ cb(null) }, 3000)')
|
|
190
315
|
end
|
|
191
316
|
end.to raise_error Selenium::WebDriver::Error::ScriptTimeoutError
|
|
192
317
|
end
|
|
193
318
|
end
|
|
194
319
|
end
|
|
195
320
|
|
|
196
|
-
describe
|
|
197
|
-
it
|
|
198
|
-
|
|
199
|
-
el =
|
|
200
|
-
expect(
|
|
201
|
-
|
|
202
|
-
expect(el.inspect).to eq
|
|
321
|
+
describe 'Element#inspect' do
|
|
322
|
+
it 'outputs obsolete elements' do
|
|
323
|
+
session.visit('/form')
|
|
324
|
+
el = session.find(:button, 'Click me!').click
|
|
325
|
+
expect(session).to have_no_button('Click me!')
|
|
326
|
+
allow(el).to receive(:synchronize)
|
|
327
|
+
expect(el.inspect).to eq 'Obsolete #<Capybara::Node::Element>'
|
|
328
|
+
expect(el).not_to have_received(:synchronize)
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
describe 'Element#click' do
|
|
333
|
+
it 'should handle fixed headers/footers' do
|
|
334
|
+
session.visit('/with_fixed_header_footer')
|
|
335
|
+
session.using_wait_time(2) do
|
|
336
|
+
session.find(:link, 'Go to root').click
|
|
337
|
+
end
|
|
338
|
+
expect(session).to have_current_path('/')
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
describe 'Capybara#Node#attach_file' do
|
|
343
|
+
it 'can attach a directory' do
|
|
344
|
+
pending "Geckodriver doesn't support uploading a directory" if firefox?(session)
|
|
345
|
+
pending "Selenium remote doesn't support transferring a directory" if remote?(session)
|
|
346
|
+
pending "Headless Chrome doesn't support directory upload - https://bugs.chromium.org/p/chromedriver/issues/detail?id=2521&q=directory%20upload&colspec=ID%20Status%20Pri%20Owner%20Summary" if chrome?(session) && chrome_lt?(110, session) && ENV.fetch('HEADLESS', nil)
|
|
347
|
+
pending "IE doesn't support uploading a directory" if ie?(session)
|
|
348
|
+
pending 'Chrome/chromedriver 73 breaks this' if chrome?(session) && chrome_gte?(73, session) && chrome_lt?(75, session)
|
|
349
|
+
|
|
350
|
+
session.visit('/form')
|
|
351
|
+
test_file_dir = File.expand_path('./fixtures', File.dirname(__FILE__))
|
|
352
|
+
session.attach_file('Directory Upload', test_file_dir)
|
|
353
|
+
session.click_button('Upload Multiple')
|
|
354
|
+
expect(session).to have_text('5 | ') # number of files
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
it 'can attach a relative file' do
|
|
358
|
+
pending 'Geckdoriver on windows requires alternate file separator which path expansion replaces' if Gem.win_platform? && firefox?(session)
|
|
359
|
+
|
|
360
|
+
session.visit('/form')
|
|
361
|
+
session.attach_file('Single Document', 'spec/fixtures/capybara.csv')
|
|
362
|
+
session.click_button('Upload Single')
|
|
363
|
+
expect(session).to have_text('Content-type: text/csv')
|
|
203
364
|
end
|
|
204
365
|
end
|
|
205
366
|
|
|
206
|
-
|
|
207
|
-
it "
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
expect(@session).to have_current_path('/')
|
|
367
|
+
context 'Windows' do
|
|
368
|
+
it "can't close the primary window" do
|
|
369
|
+
expect do
|
|
370
|
+
session.current_window.close
|
|
371
|
+
end.to raise_error(ArgumentError, 'Not allowed to close the primary window')
|
|
212
372
|
end
|
|
213
373
|
end
|
|
374
|
+
|
|
375
|
+
# rubocop:disable RSpec/InstanceVariable
|
|
376
|
+
describe 'Capybara#disable_animation' do
|
|
377
|
+
context 'when set to `true`' do
|
|
378
|
+
before(:context) do # rubocop:disable RSpec/BeforeAfterAll
|
|
379
|
+
skip "Safari doesn't support multiple sessions" if safari?(session)
|
|
380
|
+
# NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
|
|
381
|
+
# it doesn't affect any of these tests because the settings are applied per-session
|
|
382
|
+
Capybara.disable_animation = true
|
|
383
|
+
@animation_session = Capybara::Session.new(session.mode, TestApp.new)
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
it 'should add CSS to the <head> element' do
|
|
387
|
+
@animation_session.visit('with_animation')
|
|
388
|
+
|
|
389
|
+
expect(@animation_session).to have_selector(:css, 'head > style', text: 'transition: none', visible: :hidden)
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
it 'should disable CSS transitions' do
|
|
393
|
+
@animation_session.visit('with_animation')
|
|
394
|
+
@animation_session.click_link('transition me away')
|
|
395
|
+
expect(@animation_session).to have_no_link('transition me away', wait: 0.5)
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
it 'should disable CSS animations (set to 0s)' do
|
|
399
|
+
@animation_session.visit('with_animation')
|
|
400
|
+
sleep 1
|
|
401
|
+
@animation_session.click_link('animate me away')
|
|
402
|
+
expect(@animation_session).to have_no_link('animate me away', wait: 0.5)
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
it 'should disable CSS animations on pseudo elements (set to 0s)' do
|
|
406
|
+
@animation_session.visit('with_animation')
|
|
407
|
+
sleep 1
|
|
408
|
+
@animation_session.find_link('animate me away').right_click
|
|
409
|
+
expect(@animation_session).to have_content('Animation Ended', wait: 0.1)
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
it 'should scroll the page instantly', requires: [:js] do
|
|
413
|
+
@animation_session.visit('with_animation')
|
|
414
|
+
scroll_y = @animation_session.evaluate_script(<<~JS)
|
|
415
|
+
(function(){
|
|
416
|
+
window.scrollTo(0,500);
|
|
417
|
+
return window.scrollY;
|
|
418
|
+
})()
|
|
419
|
+
JS
|
|
420
|
+
expect(scroll_y).to eq 500
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
it 'should scroll the page instantly without jquery animation', requires: [:js] do
|
|
424
|
+
@animation_session.visit('with_jquery_animation')
|
|
425
|
+
@animation_session.click_link('scroll top 500')
|
|
426
|
+
scroll_y = @animation_session.evaluate_script('window.scrollY')
|
|
427
|
+
expect(scroll_y).to eq 500
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
context 'when set to `false`' do
|
|
432
|
+
before(:context) do # rubocop:disable RSpec/BeforeAfterAll
|
|
433
|
+
skip "Safari doesn't support multiple sessions" if safari?(session)
|
|
434
|
+
# NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
|
|
435
|
+
# it doesn't affect any of these tests because the settings are applied per-session
|
|
436
|
+
Capybara.disable_animation = false
|
|
437
|
+
@animation_session = Capybara::Session.new(session.mode, TestApp.new)
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
it 'should scroll the page with a smooth animation', requires: [:js] do
|
|
441
|
+
@animation_session.visit('with_animation')
|
|
442
|
+
scroll_y = @animation_session.evaluate_script(<<~JS)
|
|
443
|
+
(function(){
|
|
444
|
+
window.scrollTo(0,500);
|
|
445
|
+
return window.scrollY;
|
|
446
|
+
})()
|
|
447
|
+
JS
|
|
448
|
+
# measured over 0.5 seconds: 0, 75, 282, 478, 500
|
|
449
|
+
expect(scroll_y).to be < 500
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
it 'should scroll the page with jquery animation', requires: [:js] do
|
|
453
|
+
@animation_session.visit('with_jquery_animation')
|
|
454
|
+
@animation_session.click_link('scroll top 500')
|
|
455
|
+
scroll_y = @animation_session.evaluate_script('window.scrollY')
|
|
456
|
+
expect(scroll_y).to be < 500
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
context 'if we pass in css that matches elements' do
|
|
461
|
+
before(:context) do # rubocop:disable RSpec/BeforeAfterAll
|
|
462
|
+
skip "safaridriver doesn't support multiple sessions" if safari?(session)
|
|
463
|
+
# NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
|
|
464
|
+
# it doesn't affect any of these tests because the settings are applied per-session
|
|
465
|
+
Capybara.disable_animation = '#with_animation a'
|
|
466
|
+
@animation_session_with_matching_css = Capybara::Session.new(session.mode, TestApp.new)
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
it 'should disable CSS transitions' do
|
|
470
|
+
@animation_session_with_matching_css.visit('with_animation')
|
|
471
|
+
sleep 1
|
|
472
|
+
@animation_session_with_matching_css.click_link('transition me away')
|
|
473
|
+
expect(@animation_session_with_matching_css).to have_no_link('transition me away', wait: 0.5)
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
it 'should disable CSS animations' do
|
|
477
|
+
@animation_session_with_matching_css.visit('with_animation')
|
|
478
|
+
sleep 1
|
|
479
|
+
@animation_session_with_matching_css.click_link('animate me away')
|
|
480
|
+
expect(@animation_session_with_matching_css).to have_no_link('animate me away', wait: 0.5)
|
|
481
|
+
end
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
context 'if we pass in css that does not match elements' do
|
|
485
|
+
before(:context) do # rubocop:disable RSpec/BeforeAfterAll
|
|
486
|
+
skip "Safari doesn't support multiple sessions" if safari?(session)
|
|
487
|
+
# NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
|
|
488
|
+
# it doesn't affect any of these tests because the settings are applied per-session
|
|
489
|
+
Capybara.disable_animation = '.this-class-matches-nothing'
|
|
490
|
+
@animation_session_without_matching_css = Capybara::Session.new(session.mode, TestApp.new)
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
it 'should not disable CSS transitions' do
|
|
494
|
+
@animation_session_without_matching_css.visit('with_animation')
|
|
495
|
+
sleep 1
|
|
496
|
+
@animation_session_without_matching_css.click_link('transition me away')
|
|
497
|
+
sleep 0.5 # Wait long enough for click to have been processed
|
|
498
|
+
expect(@animation_session_without_matching_css).to have_link('transition me away', wait: false)
|
|
499
|
+
expect(@animation_session_without_matching_css).to have_no_link('transition me away', wait: 5)
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
it 'should not disable CSS animations' do
|
|
503
|
+
@animation_session_without_matching_css.visit('with_animation')
|
|
504
|
+
sleep 1
|
|
505
|
+
@animation_session_without_matching_css.click_link('animate me away')
|
|
506
|
+
sleep 0.5 # Wait long enough for click to have been processed
|
|
507
|
+
expect(@animation_session_without_matching_css).to have_link('animate me away', wait: false)
|
|
508
|
+
expect(@animation_session_without_matching_css).to have_no_link('animate me away', wait: 5)
|
|
509
|
+
end
|
|
510
|
+
end
|
|
511
|
+
end
|
|
512
|
+
# rubocop:enable RSpec/InstanceVariable
|
|
513
|
+
|
|
514
|
+
describe ':element selector' do
|
|
515
|
+
it 'can find html5 svg elements' do
|
|
516
|
+
session.visit('with_html5_svg')
|
|
517
|
+
expect(session).to have_selector(:element, :svg)
|
|
518
|
+
expect(session).to have_selector(:element, :rect, visible: :visible)
|
|
519
|
+
expect(session).to have_selector(:element, :circle)
|
|
520
|
+
expect(session).to have_selector(:element, :linearGradient, visible: :all)
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
it 'can query attributes with strange characters' do
|
|
524
|
+
session.visit('/form')
|
|
525
|
+
expect(session).to have_selector(:element, '{custom}': true)
|
|
526
|
+
expect(session).to have_selector(:element, '{custom}': 'abcdef')
|
|
527
|
+
end
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
describe 'with react' do
|
|
531
|
+
context 'controlled components' do
|
|
532
|
+
it 'can set and clear a text field' do
|
|
533
|
+
skip "This test doesn't support older browsers" if ie?(session)
|
|
534
|
+
|
|
535
|
+
session.visit 'react'
|
|
536
|
+
|
|
537
|
+
session.fill_in('Name:', with: 'abc')
|
|
538
|
+
session.accept_prompt 'A name was submitted: abc' do
|
|
539
|
+
session.click_button('Submit')
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
session.fill_in('Name:', with: '')
|
|
543
|
+
session.accept_prompt(/A name was submitted: $/) do
|
|
544
|
+
session.click_button('Submit')
|
|
545
|
+
end
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
it 'works with rapid fill' do
|
|
549
|
+
skip "This test doesn't support older browsers" if ie?(session)
|
|
550
|
+
|
|
551
|
+
session.visit 'react'
|
|
552
|
+
long_string = (0...60).map { |i| ((i % 26) + 65).chr }.join
|
|
553
|
+
|
|
554
|
+
session.fill_in('Name:', with: long_string)
|
|
555
|
+
session.accept_prompt "A name was submitted: #{long_string}" do
|
|
556
|
+
session.click_button('Submit')
|
|
557
|
+
end
|
|
558
|
+
end
|
|
559
|
+
end
|
|
560
|
+
end
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
def headless_or_remote?
|
|
564
|
+
!ENV['HEADLESS'].nil? || session.driver.options[:browser] == :remote
|
|
214
565
|
end
|
|
215
566
|
end
|