capybara 3.32.2
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 +7 -0
- data/.yardopts +1 -0
- data/History.md +1813 -0
- data/License.txt +22 -0
- data/README.md +1099 -0
- data/lib/capybara.rb +511 -0
- data/lib/capybara/config.rb +94 -0
- data/lib/capybara/cucumber.rb +27 -0
- data/lib/capybara/driver/base.rb +170 -0
- data/lib/capybara/driver/node.rb +139 -0
- data/lib/capybara/dsl.rb +65 -0
- data/lib/capybara/helpers.rb +108 -0
- data/lib/capybara/minitest.rb +386 -0
- data/lib/capybara/minitest/spec.rb +264 -0
- data/lib/capybara/node/actions.rb +420 -0
- data/lib/capybara/node/base.rb +143 -0
- data/lib/capybara/node/document.rb +48 -0
- data/lib/capybara/node/document_matchers.rb +67 -0
- data/lib/capybara/node/element.rb +606 -0
- data/lib/capybara/node/finders.rb +325 -0
- data/lib/capybara/node/matchers.rb +883 -0
- data/lib/capybara/node/simple.rb +208 -0
- data/lib/capybara/queries/ancestor_query.rb +27 -0
- data/lib/capybara/queries/base_query.rb +106 -0
- data/lib/capybara/queries/current_path_query.rb +51 -0
- data/lib/capybara/queries/match_query.rb +26 -0
- data/lib/capybara/queries/selector_query.rb +710 -0
- 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 +110 -0
- data/lib/capybara/queries/title_query.rb +39 -0
- data/lib/capybara/rack_test/browser.rb +140 -0
- data/lib/capybara/rack_test/css_handlers.rb +13 -0
- data/lib/capybara/rack_test/driver.rb +109 -0
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +127 -0
- data/lib/capybara/rack_test/node.rb +325 -0
- data/lib/capybara/rails.rb +16 -0
- data/lib/capybara/registrations/drivers.rb +36 -0
- data/lib/capybara/registrations/patches/puma_ssl.rb +27 -0
- data/lib/capybara/registrations/servers.rb +44 -0
- data/lib/capybara/result.rb +190 -0
- data/lib/capybara/rspec.rb +29 -0
- data/lib/capybara/rspec/features.rb +23 -0
- data/lib/capybara/rspec/matcher_proxies.rb +82 -0
- data/lib/capybara/rspec/matchers.rb +201 -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 +38 -0
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
- data/lib/capybara/selector.rb +233 -0
- data/lib/capybara/selector/builders/css_builder.rb +84 -0
- data/lib/capybara/selector/builders/xpath_builder.rb +69 -0
- data/lib/capybara/selector/css.rb +102 -0
- data/lib/capybara/selector/definition.rb +276 -0
- data/lib/capybara/selector/definition/button.rb +51 -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 +27 -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 +46 -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/filter.rb +5 -0
- 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 +147 -0
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- 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 +496 -0
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +119 -0
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +126 -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 +78 -0
- data/lib/capybara/selenium/logger_suppressor.rb +34 -0
- data/lib/capybara/selenium/node.rb +610 -0
- data/lib/capybara/selenium/nodes/chrome_node.rb +119 -0
- data/lib/capybara/selenium/nodes/edge_node.rb +104 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +131 -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 +47 -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.rb +126 -0
- data/lib/capybara/server/animation_disabler.rb +58 -0
- data/lib/capybara/server/checker.rb +44 -0
- data/lib/capybara/server/middleware.rb +69 -0
- data/lib/capybara/session.rb +942 -0
- data/lib/capybara/session/config.rb +124 -0
- data/lib/capybara/session/matchers.rb +87 -0
- data/lib/capybara/spec/fixtures/another_test_file.txt +1 -0
- data/lib/capybara/spec/fixtures/capybara.jpg +3 -0
- data/lib/capybara/spec/fixtures/no_extension +1 -0
- data/lib/capybara/spec/fixtures/test_file.txt +1 -0
- data/lib/capybara/spec/public/jquery-ui.js +13 -0
- data/lib/capybara/spec/public/jquery.js +5 -0
- data/lib/capybara/spec/public/offset.js +6 -0
- data/lib/capybara/spec/public/test.js +268 -0
- data/lib/capybara/spec/session/accept_alert_spec.rb +81 -0
- data/lib/capybara/spec/session/accept_confirm_spec.rb +32 -0
- data/lib/capybara/spec/session/accept_prompt_spec.rb +78 -0
- data/lib/capybara/spec/session/all_spec.rb +278 -0
- 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 +216 -0
- data/lib/capybara/spec/session/body_spec.rb +23 -0
- data/lib/capybara/spec/session/check_spec.rb +235 -0
- data/lib/capybara/spec/session/choose_spec.rb +121 -0
- data/lib/capybara/spec/session/click_button_spec.rb +506 -0
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +129 -0
- data/lib/capybara/spec/session/click_link_spec.rb +229 -0
- data/lib/capybara/spec/session/current_scope_spec.rb +31 -0
- data/lib/capybara/spec/session/current_url_spec.rb +115 -0
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +36 -0
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +21 -0
- data/lib/capybara/spec/session/element/assert_match_selector_spec.rb +38 -0
- data/lib/capybara/spec/session/element/match_css_spec.rb +31 -0
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +25 -0
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +120 -0
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +23 -0
- data/lib/capybara/spec/session/evaluate_script_spec.rb +49 -0
- data/lib/capybara/spec/session/execute_script_spec.rb +28 -0
- data/lib/capybara/spec/session/fill_in_spec.rb +286 -0
- data/lib/capybara/spec/session/find_button_spec.rb +74 -0
- data/lib/capybara/spec/session/find_by_id_spec.rb +33 -0
- data/lib/capybara/spec/session/find_field_spec.rb +113 -0
- data/lib/capybara/spec/session/find_link_spec.rb +70 -0
- data/lib/capybara/spec/session/find_spec.rb +531 -0
- data/lib/capybara/spec/session/first_spec.rb +156 -0
- 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 +12 -0
- data/lib/capybara/spec/session/go_forward_spec.rb +14 -0
- 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 +69 -0
- data/lib/capybara/spec/session/has_css_spec.rb +374 -0
- data/lib/capybara/spec/session/has_current_path_spec.rb +138 -0
- data/lib/capybara/spec/session/has_field_spec.rb +349 -0
- data/lib/capybara/spec/session/has_link_spec.rb +39 -0
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +78 -0
- data/lib/capybara/spec/session/has_select_spec.rb +310 -0
- data/lib/capybara/spec/session/has_selector_spec.rb +202 -0
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +198 -0
- data/lib/capybara/spec/session/has_text_spec.rb +394 -0
- data/lib/capybara/spec/session/has_title_spec.rb +71 -0
- data/lib/capybara/spec/session/has_xpath_spec.rb +149 -0
- data/lib/capybara/spec/session/headers_spec.rb +8 -0
- data/lib/capybara/spec/session/html_spec.rb +47 -0
- data/lib/capybara/spec/session/matches_style_spec.rb +35 -0
- data/lib/capybara/spec/session/node_spec.rb +1292 -0
- data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
- data/lib/capybara/spec/session/refresh_spec.rb +33 -0
- data/lib/capybara/spec/session/reset_session_spec.rb +148 -0
- data/lib/capybara/spec/session/response_code_spec.rb +8 -0
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +21 -0
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +43 -0
- data/lib/capybara/spec/session/save_page_spec.rb +110 -0
- data/lib/capybara/spec/session/save_screenshot_spec.rb +55 -0
- data/lib/capybara/spec/session/screenshot_spec.rb +18 -0
- data/lib/capybara/spec/session/scroll_spec.rb +117 -0
- data/lib/capybara/spec/session/select_spec.rb +229 -0
- data/lib/capybara/spec/session/selectors_spec.rb +98 -0
- data/lib/capybara/spec/session/sibling_spec.rb +52 -0
- data/lib/capybara/spec/session/source_spec.rb +0 -0
- data/lib/capybara/spec/session/text_spec.rb +74 -0
- data/lib/capybara/spec/session/title_spec.rb +29 -0
- data/lib/capybara/spec/session/uncheck_spec.rb +100 -0
- data/lib/capybara/spec/session/unselect_spec.rb +116 -0
- data/lib/capybara/spec/session/visit_spec.rb +204 -0
- data/lib/capybara/spec/session/window/become_closed_spec.rb +89 -0
- data/lib/capybara/spec/session/window/current_window_spec.rb +28 -0
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +31 -0
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +132 -0
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +99 -0
- data/lib/capybara/spec/session/window/window_spec.rb +203 -0
- data/lib/capybara/spec/session/window/windows_spec.rb +34 -0
- data/lib/capybara/spec/session/window/within_window_spec.rb +157 -0
- data/lib/capybara/spec/session/within_spec.rb +199 -0
- data/lib/capybara/spec/spec_helper.rb +134 -0
- data/lib/capybara/spec/test_app.rb +226 -0
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/buttons.erb +5 -0
- data/lib/capybara/spec/views/fieldsets.erb +30 -0
- data/lib/capybara/spec/views/form.erb +685 -0
- data/lib/capybara/spec/views/frame_child.erb +18 -0
- data/lib/capybara/spec/views/frame_one.erb +10 -0
- data/lib/capybara/spec/views/frame_parent.erb +9 -0
- data/lib/capybara/spec/views/frame_two.erb +9 -0
- data/lib/capybara/spec/views/header_links.erb +8 -0
- data/lib/capybara/spec/views/host_links.erb +13 -0
- 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 +13 -0
- data/lib/capybara/spec/views/popup_one.erb +9 -0
- data/lib/capybara/spec/views/popup_two.erb +9 -0
- data/lib/capybara/spec/views/postback.erb +14 -0
- 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 +130 -0
- data/lib/capybara/spec/views/with_animation.erb +74 -0
- data/lib/capybara/spec/views/with_base_tag.erb +11 -0
- data/lib/capybara/spec/views/with_count.erb +8 -0
- data/lib/capybara/spec/views/with_dragula.erb +22 -0
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
- data/lib/capybara/spec/views/with_hover.erb +24 -0
- data/lib/capybara/spec/views/with_hover1.erb +10 -0
- data/lib/capybara/spec/views/with_html.erb +208 -0
- data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
- data/lib/capybara/spec/views/with_html_entities.erb +2 -0
- data/lib/capybara/spec/views/with_js.erb +160 -0
- 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 +42 -0
- data/lib/capybara/spec/views/with_scope_other.erb +6 -0
- data/lib/capybara/spec/views/with_simple_html.erb +2 -0
- data/lib/capybara/spec/views/with_slow_unload.erb +17 -0
- data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
- data/lib/capybara/spec/views/with_title.erb +5 -0
- data/lib/capybara/spec/views/with_unload_alert.erb +14 -0
- data/lib/capybara/spec/views/with_windows.erb +54 -0
- data/lib/capybara/spec/views/within_frames.erb +15 -0
- data/lib/capybara/version.rb +5 -0
- data/lib/capybara/window.rb +146 -0
- data/spec/basic_node_spec.rb +154 -0
- data/spec/capybara_spec.rb +112 -0
- data/spec/css_builder_spec.rb +101 -0
- data/spec/css_splitter_spec.rb +38 -0
- data/spec/dsl_spec.rb +276 -0
- 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 +13 -0
- data/spec/fixtures/selenium_driver_rspec_success.rb +13 -0
- data/spec/minitest_spec.rb +163 -0
- data/spec/minitest_spec_spec.rb +162 -0
- data/spec/per_session_config_spec.rb +68 -0
- data/spec/rack_test_spec.rb +268 -0
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +196 -0
- data/spec/rspec/features_spec.rb +99 -0
- data/spec/rspec/scenarios_spec.rb +19 -0
- data/spec/rspec/shared_spec_matchers.rb +947 -0
- data/spec/rspec/views_spec.rb +14 -0
- data/spec/rspec_matchers_spec.rb +62 -0
- data/spec/rspec_spec.rb +145 -0
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +513 -0
- data/spec/selenium_spec_chrome.rb +188 -0
- data/spec/selenium_spec_chrome_remote.rb +96 -0
- data/spec/selenium_spec_edge.rb +47 -0
- data/spec/selenium_spec_firefox.rb +208 -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 +292 -0
- data/spec/session_spec.rb +91 -0
- data/spec/shared_selenium_node.rb +83 -0
- data/spec/shared_selenium_session.rb +476 -0
- data/spec/spec_helper.rb +100 -0
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +753 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe Capybara::Session do
|
|
6
|
+
describe '#new' do
|
|
7
|
+
it 'should raise an error if passed non-existent driver' do
|
|
8
|
+
expect do
|
|
9
|
+
described_class.new(:quox, TestApp).driver
|
|
10
|
+
end.to raise_error(Capybara::DriverNotFoundError)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'verifies a passed app is a rack app' do
|
|
14
|
+
expect do
|
|
15
|
+
described_class.new(:unknown, random: 'hash')
|
|
16
|
+
end.to raise_error TypeError, 'The second parameter to Session::new should be a rack app if passed.'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'current_driver' do
|
|
21
|
+
around do |example|
|
|
22
|
+
orig_driver = Capybara.current_driver
|
|
23
|
+
example.run
|
|
24
|
+
Capybara.current_driver = orig_driver
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'is global when threadsafe false' do
|
|
28
|
+
Capybara.threadsafe = false
|
|
29
|
+
Capybara.current_driver = :selenium
|
|
30
|
+
thread = Thread.new do
|
|
31
|
+
Capybara.current_driver = :random
|
|
32
|
+
end
|
|
33
|
+
thread.join
|
|
34
|
+
expect(Capybara.current_driver).to eq :random
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'is thread specific threadsafe true' do
|
|
38
|
+
Capybara.threadsafe = true
|
|
39
|
+
Capybara.current_driver = :selenium
|
|
40
|
+
thread = Thread.new do
|
|
41
|
+
Capybara.current_driver = :random
|
|
42
|
+
end
|
|
43
|
+
thread.join
|
|
44
|
+
expect(Capybara.current_driver).to eq :selenium
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context 'session_name' do
|
|
49
|
+
around do |example|
|
|
50
|
+
orig_name = Capybara.session_name
|
|
51
|
+
example.run
|
|
52
|
+
Capybara.session_name = orig_name
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'is global when threadsafe false' do
|
|
56
|
+
Capybara.threadsafe = false
|
|
57
|
+
Capybara.session_name = 'sess1'
|
|
58
|
+
thread = Thread.new do
|
|
59
|
+
Capybara.session_name = 'sess2'
|
|
60
|
+
end
|
|
61
|
+
thread.join
|
|
62
|
+
expect(Capybara.session_name).to eq 'sess2'
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'is thread specific when threadsafe true' do
|
|
66
|
+
Capybara.threadsafe = true
|
|
67
|
+
Capybara.session_name = 'sess1'
|
|
68
|
+
thread = Thread.new do
|
|
69
|
+
Capybara.session_name = 'sess2'
|
|
70
|
+
end
|
|
71
|
+
thread.join
|
|
72
|
+
expect(Capybara.session_name).to eq 'sess1'
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context 'quit' do
|
|
77
|
+
it 'will reset the driver' do
|
|
78
|
+
session = described_class.new(:rack_test, TestApp)
|
|
79
|
+
driver = session.driver
|
|
80
|
+
session.quit
|
|
81
|
+
expect(session.driver).not_to eql driver
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it 'resets the document' do
|
|
85
|
+
session = described_class.new(:rack_test, TestApp)
|
|
86
|
+
document = session.document
|
|
87
|
+
session.quit
|
|
88
|
+
expect(session.document.base).not_to eql document.base
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'selenium-webdriver'
|
|
5
|
+
|
|
6
|
+
RSpec.shared_examples 'Capybara::Node' do |session, _mode|
|
|
7
|
+
let(:session) { session }
|
|
8
|
+
|
|
9
|
+
describe '#content_editable?' do
|
|
10
|
+
it 'returns true when the element is content editable' do
|
|
11
|
+
session.visit('/with_js')
|
|
12
|
+
expect(session.find(:css, '#existing_content_editable').base.content_editable?).to be true
|
|
13
|
+
expect(session.find(:css, '#existing_content_editable_child').base.content_editable?).to be true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'returns false when the element is not content editable' do
|
|
17
|
+
session.visit('/with_js')
|
|
18
|
+
expect(session.find(:css, '#drag').base.content_editable?).to be false
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe '#send_keys' do
|
|
23
|
+
it 'should process space' do
|
|
24
|
+
session.visit('/form')
|
|
25
|
+
session.find(:css, '#address1_city').send_keys('ocean', [:shift, :space, 'side'])
|
|
26
|
+
expect(session.find(:css, '#address1_city').value).to eq 'ocean SIDE'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe '#[]' do
|
|
31
|
+
it 'should work for spellcheck' do
|
|
32
|
+
session.visit('/with_html')
|
|
33
|
+
expect(session.find('//input[@spellcheck="TRUE"]')[:spellcheck]).to eq('true')
|
|
34
|
+
expect(session.find('//input[@spellcheck="FALSE"]')[:spellcheck]).to eq('false')
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe '#set' do
|
|
39
|
+
it 'respects maxlength when using rapid set' do
|
|
40
|
+
session.visit('/form')
|
|
41
|
+
inp = session.find(:css, '#long_length')
|
|
42
|
+
value = (0...50).map { |i| ((i % 26) + 65).chr }.join
|
|
43
|
+
inp.set(value, rapid: true)
|
|
44
|
+
expect(inp.value).to eq value[0...35]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe '#visible?' do
|
|
49
|
+
let(:bridge) do
|
|
50
|
+
session.driver.browser.send(:bridge)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
around do |example|
|
|
54
|
+
native_displayed = session.driver.options[:native_displayed]
|
|
55
|
+
example.run
|
|
56
|
+
session.driver.options[:native_displayed] = native_displayed
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
before do
|
|
60
|
+
allow(bridge).to receive(:execute_atom).and_call_original
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'will use native displayed if told to' do
|
|
64
|
+
pending "Chromedriver < 76.0.3809.25 doesn't support native displayed in W3C mode" if chrome_lt?(76, session) && (ENV['W3C'] != 'false')
|
|
65
|
+
|
|
66
|
+
session.driver.options[:native_displayed] = true
|
|
67
|
+
session.visit('/form')
|
|
68
|
+
session.find(:css, '#address1_city', visible: true)
|
|
69
|
+
|
|
70
|
+
expect(bridge).not_to have_received(:execute_atom)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "won't use native displayed if told not to" do
|
|
74
|
+
skip 'Non-W3C uses native' if chrome?(session) && (ENV['W3C'] == 'false')
|
|
75
|
+
|
|
76
|
+
session.driver.options[:native_displayed] = false
|
|
77
|
+
session.visit('/form')
|
|
78
|
+
session.find(:css, '#address1_city', visible: true)
|
|
79
|
+
|
|
80
|
+
expect(bridge).to have_received(:execute_atom).with(:isDisplayed, any_args)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'selenium-webdriver'
|
|
5
|
+
|
|
6
|
+
RSpec.shared_examples 'Capybara::Session' do |session, mode|
|
|
7
|
+
let(:session) { session }
|
|
8
|
+
|
|
9
|
+
context 'with selenium driver' do
|
|
10
|
+
describe '#driver' do
|
|
11
|
+
it 'should be a selenium driver' do
|
|
12
|
+
expect(session.driver).to be_an_instance_of(Capybara::Selenium::Driver)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe '#mode' do
|
|
17
|
+
it 'should remember the mode' do
|
|
18
|
+
expect(session.mode).to eq(mode)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
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 eq false
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe 'exit codes' do
|
|
31
|
+
let(:env) { { 'SELENIUM_BROWSER' => session.driver.options[:browser].to_s } }
|
|
32
|
+
let!(:orig_dir) { Dir.getwd }
|
|
33
|
+
|
|
34
|
+
before do
|
|
35
|
+
Dir.chdir(File.join(File.dirname(__FILE__), '..'))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
after do
|
|
39
|
+
Dir.chdir(orig_dir)
|
|
40
|
+
end
|
|
41
|
+
|
|
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)
|
|
48
|
+
end
|
|
49
|
+
|
|
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)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
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))
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'can be called before visiting' do
|
|
68
|
+
session.accept_alert 'Initial alert' do
|
|
69
|
+
session.visit('/initial_alert')
|
|
70
|
+
end
|
|
71
|
+
expect(session).to have_text('Initial alert page')
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe '#fill_in_with empty string and no options' do
|
|
76
|
+
it 'should trigger change when clearing a field' do
|
|
77
|
+
pending "safaridriver doesn't trigger change for clear" if safari?(session)
|
|
78
|
+
session.visit('/with_js')
|
|
79
|
+
session.fill_in('with_change_event', with: '')
|
|
80
|
+
# click outside the field to trigger the change event
|
|
81
|
+
session.find(:css, 'body').click
|
|
82
|
+
expect(session).to have_selector(:css, '.change_event_triggered', match: :one)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
describe '#fill_in with { :clear => :backspace } fill_option', requires: [:js] do
|
|
87
|
+
before do
|
|
88
|
+
# Firefox has an issue with change events if the main window doesn't think it's focused
|
|
89
|
+
session.execute_script('window.focus()')
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'should fill in a field, replacing an existing value' do
|
|
93
|
+
session.visit('/form')
|
|
94
|
+
session.fill_in('form_first_name',
|
|
95
|
+
with: 'Harry',
|
|
96
|
+
fill_options: { clear: :backspace })
|
|
97
|
+
expect(session.find(:fillable_field, 'form_first_name').value).to eq('Harry')
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'should fill in a field, replacing an existing value, even with caret position' do
|
|
101
|
+
session.visit('/form')
|
|
102
|
+
session.find(:css, '#form_first_name').execute_script <<-JS
|
|
103
|
+
this.focus();
|
|
104
|
+
this.setSelectionRange(0, 0);
|
|
105
|
+
JS
|
|
106
|
+
|
|
107
|
+
session.fill_in('form_first_name',
|
|
108
|
+
with: 'Harry',
|
|
109
|
+
fill_options: { clear: :backspace })
|
|
110
|
+
expect(session.find(:fillable_field, 'form_first_name').value).to eq('Harry')
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it 'should fill in if the option is set via global option' do
|
|
114
|
+
Capybara.default_set_options = { clear: :backspace }
|
|
115
|
+
session.visit('/form')
|
|
116
|
+
session.fill_in('form_first_name', with: 'Thomas')
|
|
117
|
+
expect(session.find(:fillable_field, 'form_first_name').value).to eq('Thomas')
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it 'should only trigger onchange once' do
|
|
121
|
+
session.visit('/with_js')
|
|
122
|
+
sleep 2 if safari?(session) # Safari needs a delay (to load event handlers maybe ???)
|
|
123
|
+
session.fill_in('with_change_event',
|
|
124
|
+
with: 'some value',
|
|
125
|
+
fill_options: { clear: :backspace })
|
|
126
|
+
# click outside the field to trigger the change event
|
|
127
|
+
session.find(:css, '#with_focus_event').click
|
|
128
|
+
expect(session.find(:css, '.change_event_triggered', match: :one, wait: 5)).to have_text 'some value'
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it 'should trigger change when clearing field' do
|
|
132
|
+
session.visit('/with_js')
|
|
133
|
+
session.fill_in('with_change_event',
|
|
134
|
+
with: '',
|
|
135
|
+
fill_options: { clear: :backspace })
|
|
136
|
+
# click outside the field to trigger the change event
|
|
137
|
+
session.find(:css, '#with_focus_event').click
|
|
138
|
+
expect(session).to have_selector(:css, '.change_event_triggered', match: :one, wait: 5)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it 'should trigger input event field_value.length times' do
|
|
142
|
+
session.visit('/with_js')
|
|
143
|
+
session.fill_in('with_change_event',
|
|
144
|
+
with: '',
|
|
145
|
+
fill_options: { clear: :backspace })
|
|
146
|
+
# click outside the field to trigger the change event
|
|
147
|
+
# session.find(:css, 'body').click
|
|
148
|
+
session.find(:css, 'h1', text: 'FooBar').click
|
|
149
|
+
expect(session).to have_xpath('//p[@class="input_event_triggered"]', count: 13)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
describe '#fill_in with { clear: :none } fill_options' do
|
|
154
|
+
it 'should append to content in a field' do
|
|
155
|
+
pending 'Safari overwrites by default - need to figure out a workaround' if safari?(session)
|
|
156
|
+
|
|
157
|
+
session.visit('/form')
|
|
158
|
+
session.fill_in('form_first_name',
|
|
159
|
+
with: 'Harry',
|
|
160
|
+
fill_options: { clear: :none })
|
|
161
|
+
expect(session.find(:fillable_field, 'form_first_name').value).to eq('JohnHarry')
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
describe '#fill_in with Date' do
|
|
166
|
+
before do
|
|
167
|
+
session.visit('/form')
|
|
168
|
+
session.find(:css, '#form_date').execute_script <<-JS
|
|
169
|
+
window.capybara_formDateFiredEvents = [];
|
|
170
|
+
var fd = this;
|
|
171
|
+
['focus', 'input', 'change'].forEach(function(eventType) {
|
|
172
|
+
fd.addEventListener(eventType, function() { window.capybara_formDateFiredEvents.push(eventType); });
|
|
173
|
+
});
|
|
174
|
+
JS
|
|
175
|
+
# work around weird FF issue where it would create an extra focus issue in some cases
|
|
176
|
+
session.find(:css, 'h1', text: 'Form').click
|
|
177
|
+
# session.find(:css, 'body').click
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it 'should generate standard events on changing value' do
|
|
181
|
+
pending "IE 11 doesn't support date input type" if ie?(session)
|
|
182
|
+
pending "Safari doesn't support date input type" if safari?(session)
|
|
183
|
+
session.fill_in('form_date', with: Date.today)
|
|
184
|
+
expect(session.evaluate_script('window.capybara_formDateFiredEvents')).to eq %w[focus input change]
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it 'should not generate input and change events if the value is not changed' do
|
|
188
|
+
pending "IE 11 doesn't support date input type" if ie?(session)
|
|
189
|
+
pending "Safari doesn't support date input type" if safari?(session)
|
|
190
|
+
session.fill_in('form_date', with: Date.today)
|
|
191
|
+
session.fill_in('form_date', with: Date.today)
|
|
192
|
+
# Chrome adds an extra focus for some reason - ok for now
|
|
193
|
+
expect(session.evaluate_script('window.capybara_formDateFiredEvents')).to eq(%w[focus input change])
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
describe '#fill_in with { clear: Array } fill_options' do
|
|
198
|
+
it 'should pass the array through to the element' do
|
|
199
|
+
# this is mainly for use with [[:control, 'a'], :backspace] - however since that is platform dependant I'm testing with something less useful
|
|
200
|
+
session.visit('/form')
|
|
201
|
+
session.fill_in('form_first_name',
|
|
202
|
+
with: 'Harry',
|
|
203
|
+
fill_options: { clear: [[:shift, 'abc'], :backspace] })
|
|
204
|
+
expect(session.find(:fillable_field, 'form_first_name').value).to eq('JohnABHarry')
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
describe '#path' do
|
|
209
|
+
it 'returns xpath' do
|
|
210
|
+
# this is here because it is testing for an XPath that is specific to the algorithm used in the selenium driver
|
|
211
|
+
session.visit('/path')
|
|
212
|
+
element = session.find(:link, 'Second Link')
|
|
213
|
+
expect(element.path).to eq('/HTML/BODY[1]/DIV[2]/A[1]')
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it 'handles namespaces in xhtml' do
|
|
217
|
+
pending "IE 11 doesn't handle all XPath querys (namespace-uri, etc)" if ie?(session)
|
|
218
|
+
session.visit '/with_namespace'
|
|
219
|
+
rect = session.find(:css, 'div svg rect:first-of-type')
|
|
220
|
+
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]")
|
|
221
|
+
expect(session.find(:xpath, rect.path)).to eq rect
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it 'handles default namespaces in html5' do
|
|
225
|
+
pending "IE 11 doesn't handle all XPath querys (namespace-uri, etc)" if ie?(session)
|
|
226
|
+
session.visit '/with_html5_svg'
|
|
227
|
+
rect = session.find(:css, 'div svg rect:first-of-type')
|
|
228
|
+
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]")
|
|
229
|
+
expect(session.find(:xpath, rect.path)).to eq rect
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
it 'handles case sensitive element names' do
|
|
233
|
+
pending "IE 11 doesn't handle all XPath querys (namespace-uri, etc)" if ie?(session)
|
|
234
|
+
session.visit '/with_namespace'
|
|
235
|
+
els = session.all(:css, 'div *', visible: :all)
|
|
236
|
+
expect { els.map(&:path) }.not_to raise_error
|
|
237
|
+
lg = session.find(:css, 'div linearGradient', visible: :all)
|
|
238
|
+
expect(session.find(:xpath, lg.path, visible: :all)).to eq lg
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
describe 'all with disappearing elements' do
|
|
243
|
+
it 'ignores stale elements in results' do
|
|
244
|
+
session.visit('/path')
|
|
245
|
+
elements = session.all(:link) { |_node| raise Selenium::WebDriver::Error::StaleElementReferenceError }
|
|
246
|
+
expect(elements.size).to eq 0
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
describe '#evaluate_script' do
|
|
251
|
+
it 'can return an element' do
|
|
252
|
+
session.visit('/form')
|
|
253
|
+
element = session.evaluate_script("document.getElementById('form_title')")
|
|
254
|
+
expect(element).to eq session.find(:id, 'form_title')
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
it 'can return arrays of nested elements' do
|
|
258
|
+
session.visit('/form')
|
|
259
|
+
elements = session.evaluate_script('document.querySelectorAll("#form_city option")')
|
|
260
|
+
expect(elements).to all(be_instance_of Capybara::Node::Element)
|
|
261
|
+
expect(elements).to eq session.find(:css, '#form_city').all(:css, 'option').to_a
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it 'can return hashes with elements' do
|
|
265
|
+
session.visit('/form')
|
|
266
|
+
result = session.evaluate_script("{ a: document.getElementById('form_title'), b: {c: document.querySelectorAll('#form_city option')}}")
|
|
267
|
+
expect(result).to eq(
|
|
268
|
+
'a' => session.find(:id, 'form_title'),
|
|
269
|
+
'b' => {
|
|
270
|
+
'c' => session.find(:css, '#form_city').all(:css, 'option').to_a
|
|
271
|
+
}
|
|
272
|
+
)
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
describe '#evaluate_async_script' do
|
|
276
|
+
it 'will timeout if the script takes too long' do
|
|
277
|
+
skip 'safaridriver returns the wrong error type' if safari?(session)
|
|
278
|
+
session.visit('/with_js')
|
|
279
|
+
expect do
|
|
280
|
+
session.using_wait_time(1) do
|
|
281
|
+
session.evaluate_async_script('var cb = arguments[0]; setTimeout(function(){ cb(null) }, 3000)')
|
|
282
|
+
end
|
|
283
|
+
end.to raise_error Selenium::WebDriver::Error::ScriptTimeoutError
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
describe 'Element#inspect' do
|
|
289
|
+
it 'outputs obsolete elements' do
|
|
290
|
+
session.visit('/form')
|
|
291
|
+
el = session.find(:button, 'Click me!').click
|
|
292
|
+
expect(session).to have_no_button('Click me!')
|
|
293
|
+
allow(el).to receive(:synchronize)
|
|
294
|
+
expect(el.inspect).to eq 'Obsolete #<Capybara::Node::Element>'
|
|
295
|
+
expect(el).not_to have_received(:synchronize)
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
describe 'Element#click' do
|
|
300
|
+
it 'should handle fixed headers/footers' do
|
|
301
|
+
session.visit('/with_fixed_header_footer')
|
|
302
|
+
session.using_wait_time(2) do
|
|
303
|
+
session.find(:link, 'Go to root').click
|
|
304
|
+
end
|
|
305
|
+
expect(session).to have_current_path('/')
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
describe 'Capybara#Node#attach_file' do
|
|
310
|
+
it 'can attach a directory' do
|
|
311
|
+
pending "Geckodriver doesn't support uploading a directory" if firefox?(session)
|
|
312
|
+
pending "Selenium remote doesn't support transferring a directory" if remote?(session)
|
|
313
|
+
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) && ENV['HEADLESS']
|
|
314
|
+
pending "IE doesn't support uploading a directory" if ie?(session)
|
|
315
|
+
pending 'Chrome/chromedriver 73 breaks this' if chrome?(session) && chrome_gte?(73, session) && chrome_lt?(75, session)
|
|
316
|
+
pending "Safari doesn't support uploading a directory" if safari?(session)
|
|
317
|
+
# pending "Edge/msedgedriver doesn't support directory upload" if edge?(session) && edge_gte?(75, session)
|
|
318
|
+
|
|
319
|
+
session.visit('/form')
|
|
320
|
+
test_file_dir = File.expand_path('./fixtures', File.dirname(__FILE__))
|
|
321
|
+
session.attach_file('Directory Upload', test_file_dir)
|
|
322
|
+
session.click_button('Upload Multiple')
|
|
323
|
+
expect(session.body).to include('5 | ') # number of files
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
it 'can attach a relative file' do
|
|
327
|
+
pending 'Geckdoriver on windows requires alternate file separator which path expansion replaces' if Gem.win_platform? && firefox?(session)
|
|
328
|
+
|
|
329
|
+
session.visit('/form')
|
|
330
|
+
session.attach_file('Single Document', 'spec/fixtures/capybara.csv')
|
|
331
|
+
session.click_button('Upload Single')
|
|
332
|
+
expect(session.body).to include('Content-type: text/csv')
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
context 'Windows' do
|
|
337
|
+
it "can't close the primary window" do
|
|
338
|
+
expect do
|
|
339
|
+
session.current_window.close
|
|
340
|
+
end.to raise_error(ArgumentError, 'Not allowed to close the primary window')
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
# rubocop:disable RSpec/InstanceVariable
|
|
345
|
+
describe 'Capybara#disable_animation' do
|
|
346
|
+
context 'when set to `true`' do
|
|
347
|
+
before(:context) do # rubocop:disable RSpec/BeforeAfterAll
|
|
348
|
+
skip "Safari doesn't support multiple sessions" if safari?(session)
|
|
349
|
+
# NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
|
|
350
|
+
# it doesn't affect any of these tests because the settings are applied per-session
|
|
351
|
+
Capybara.disable_animation = true
|
|
352
|
+
@animation_session = Capybara::Session.new(session.mode, TestApp.new)
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
it 'should disable CSS transitions' do
|
|
356
|
+
@animation_session.visit('with_animation')
|
|
357
|
+
@animation_session.click_link('transition me away')
|
|
358
|
+
expect(@animation_session).to have_no_link('transition me away', wait: 0.5)
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
it 'should disable CSS animations (set to 0s)' do
|
|
362
|
+
@animation_session.visit('with_animation')
|
|
363
|
+
@animation_session.click_link('animate me away')
|
|
364
|
+
expect(@animation_session).to have_no_link('animate me away', wait: 0.5)
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
it 'should disable CSS animations on pseudo elements (set to 0s)' do
|
|
368
|
+
@animation_session.visit('with_animation')
|
|
369
|
+
@animation_session.find_link('animate me away').right_click
|
|
370
|
+
expect(@animation_session).to have_content('Animation Ended', wait: 0.1)
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
context 'if we pass in css that matches elements' do
|
|
375
|
+
before(:context) do # rubocop:disable RSpec/BeforeAfterAll
|
|
376
|
+
skip "safaridriver doesn't support multiple sessions" if safari?(session)
|
|
377
|
+
# NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
|
|
378
|
+
# it doesn't affect any of these tests because the settings are applied per-session
|
|
379
|
+
Capybara.disable_animation = '#with_animation a'
|
|
380
|
+
@animation_session_with_matching_css = Capybara::Session.new(session.mode, TestApp.new)
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
it 'should disable CSS transitions' do
|
|
384
|
+
@animation_session_with_matching_css.visit('with_animation')
|
|
385
|
+
@animation_session_with_matching_css.click_link('transition me away')
|
|
386
|
+
expect(@animation_session_with_matching_css).to have_no_link('transition me away', wait: 0.5)
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
it 'should disable CSS animations' do
|
|
390
|
+
@animation_session_with_matching_css.visit('with_animation')
|
|
391
|
+
@animation_session_with_matching_css.click_link('animate me away')
|
|
392
|
+
expect(@animation_session_with_matching_css).to have_no_link('animate me away', wait: 0.5)
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
context 'if we pass in css that does not match elements' do
|
|
397
|
+
before(:context) do # rubocop:disable RSpec/BeforeAfterAll
|
|
398
|
+
skip "Safari doesn't support multiple sessions" if safari?(session)
|
|
399
|
+
# NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
|
|
400
|
+
# it doesn't affect any of these tests because the settings are applied per-session
|
|
401
|
+
Capybara.disable_animation = '.this-class-matches-nothing'
|
|
402
|
+
@animation_session_without_matching_css = Capybara::Session.new(session.mode, TestApp.new)
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
it 'should not disable CSS transitions' do
|
|
406
|
+
@animation_session_without_matching_css.visit('with_animation')
|
|
407
|
+
@animation_session_without_matching_css.click_link('transition me away')
|
|
408
|
+
sleep 0.5 # Wait long enough for click to have been processed
|
|
409
|
+
expect(@animation_session_without_matching_css).to have_link('transition me away', wait: false)
|
|
410
|
+
expect(@animation_session_without_matching_css).to have_no_link('transition me away', wait: 5)
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
it 'should not disable CSS animations' do
|
|
414
|
+
@animation_session_without_matching_css.visit('with_animation')
|
|
415
|
+
@animation_session_without_matching_css.click_link('animate me away')
|
|
416
|
+
sleep 0.5 # Wait long enough for click to have been processed
|
|
417
|
+
expect(@animation_session_without_matching_css).to have_link('animate me away', wait: false)
|
|
418
|
+
expect(@animation_session_without_matching_css).to have_no_link('animate me away', wait: 5)
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
# rubocop:enable RSpec/InstanceVariable
|
|
423
|
+
|
|
424
|
+
describe ':element selector' do
|
|
425
|
+
it 'can find html5 svg elements' do
|
|
426
|
+
session.visit('with_html5_svg')
|
|
427
|
+
expect(session).to have_selector(:element, :svg)
|
|
428
|
+
expect(session).to have_selector(:element, :rect, visible: true)
|
|
429
|
+
expect(session).to have_selector(:element, :circle)
|
|
430
|
+
expect(session).to have_selector(:element, :linearGradient, visible: :all)
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
it 'can query attributes with strange characters' do
|
|
434
|
+
session.visit('/form')
|
|
435
|
+
expect(session).to have_selector(:element, "{custom}": true)
|
|
436
|
+
expect(session).to have_selector(:element, "{custom}": 'abcdef')
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
describe 'with react' do
|
|
441
|
+
context 'controlled components' do
|
|
442
|
+
it 'can set and clear a text field' do
|
|
443
|
+
skip "This test doesn't support older browsers" if ie?(session)
|
|
444
|
+
|
|
445
|
+
session.visit 'react'
|
|
446
|
+
|
|
447
|
+
session.fill_in('Name:', with: 'abc')
|
|
448
|
+
session.accept_prompt 'A name was submitted: abc' do
|
|
449
|
+
session.click_button('Submit')
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
session.fill_in('Name:', with: '')
|
|
453
|
+
session.accept_prompt(/A name was submitted: $/) do
|
|
454
|
+
session.click_button('Submit')
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
it 'works with rapid fill' do
|
|
459
|
+
skip "This test doesn't support older browsers" if ie?(session)
|
|
460
|
+
|
|
461
|
+
session.visit 'react'
|
|
462
|
+
long_string = (0...60).map { |i| ((i % 26) + 65).chr }.join
|
|
463
|
+
|
|
464
|
+
session.fill_in('Name:', with: long_string)
|
|
465
|
+
session.accept_prompt "A name was submitted: #{long_string}" do
|
|
466
|
+
session.click_button('Submit')
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
def headless_or_remote?
|
|
474
|
+
!ENV['HEADLESS'].nil? || session.driver.options[:browser] == :remote
|
|
475
|
+
end
|
|
476
|
+
end
|