capybara 2.7.0 → 3.35.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.yardopts +1 -0
- data/History.md +1147 -11
- data/License.txt +1 -1
- data/README.md +252 -131
- data/lib/capybara/config.rb +92 -0
- data/lib/capybara/cucumber.rb +3 -3
- data/lib/capybara/driver/base.rb +52 -21
- data/lib/capybara/driver/node.rb +48 -14
- data/lib/capybara/dsl.rb +16 -9
- data/lib/capybara/helpers.rb +72 -81
- data/lib/capybara/minitest/spec.rb +267 -0
- data/lib/capybara/minitest.rb +385 -0
- data/lib/capybara/node/actions.rb +337 -89
- data/lib/capybara/node/base.rb +50 -32
- data/lib/capybara/node/document.rb +19 -3
- data/lib/capybara/node/document_matchers.rb +22 -24
- data/lib/capybara/node/element.rb +388 -125
- data/lib/capybara/node/finders.rb +231 -121
- data/lib/capybara/node/matchers.rb +503 -217
- data/lib/capybara/node/simple.rb +64 -27
- data/lib/capybara/queries/ancestor_query.rb +27 -0
- data/lib/capybara/queries/base_query.rb +87 -11
- data/lib/capybara/queries/current_path_query.rb +24 -24
- data/lib/capybara/queries/match_query.rb +15 -10
- data/lib/capybara/queries/selector_query.rb +675 -81
- data/lib/capybara/queries/sibling_query.rb +26 -0
- data/lib/capybara/queries/style_query.rb +45 -0
- data/lib/capybara/queries/text_query.rb +88 -20
- data/lib/capybara/queries/title_query.rb +9 -11
- data/lib/capybara/rack_test/browser.rb +63 -39
- data/lib/capybara/rack_test/css_handlers.rb +6 -4
- data/lib/capybara/rack_test/driver.rb +26 -16
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +73 -58
- data/lib/capybara/rack_test/node.rb +187 -67
- data/lib/capybara/rails.rb +4 -8
- data/lib/capybara/registration_container.rb +44 -0
- data/lib/capybara/registrations/drivers.rb +42 -0
- data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
- data/lib/capybara/registrations/servers.rb +45 -0
- data/lib/capybara/result.rb +142 -14
- data/lib/capybara/rspec/features.rb +17 -42
- data/lib/capybara/rspec/matcher_proxies.rb +82 -0
- data/lib/capybara/rspec/matchers/base.rb +111 -0
- data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
- data/lib/capybara/rspec/matchers/compound.rb +88 -0
- data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
- data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
- data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
- data/lib/capybara/rspec/matchers/have_selector.rb +77 -0
- data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
- data/lib/capybara/rspec/matchers/have_text.rb +33 -0
- data/lib/capybara/rspec/matchers/have_title.rb +29 -0
- data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
- data/lib/capybara/rspec/matchers/match_style.rb +43 -0
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
- data/lib/capybara/rspec/matchers.rb +143 -244
- data/lib/capybara/rspec.rb +10 -12
- data/lib/capybara/selector/builders/css_builder.rb +84 -0
- data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
- data/lib/capybara/selector/css.rb +102 -0
- data/lib/capybara/selector/definition/button.rb +63 -0
- data/lib/capybara/selector/definition/checkbox.rb +26 -0
- data/lib/capybara/selector/definition/css.rb +10 -0
- data/lib/capybara/selector/definition/datalist_input.rb +35 -0
- data/lib/capybara/selector/definition/datalist_option.rb +25 -0
- data/lib/capybara/selector/definition/element.rb +28 -0
- data/lib/capybara/selector/definition/field.rb +40 -0
- data/lib/capybara/selector/definition/fieldset.rb +14 -0
- data/lib/capybara/selector/definition/file_field.rb +13 -0
- data/lib/capybara/selector/definition/fillable_field.rb +33 -0
- data/lib/capybara/selector/definition/frame.rb +17 -0
- data/lib/capybara/selector/definition/id.rb +6 -0
- data/lib/capybara/selector/definition/label.rb +62 -0
- data/lib/capybara/selector/definition/link.rb +54 -0
- data/lib/capybara/selector/definition/link_or_button.rb +16 -0
- data/lib/capybara/selector/definition/option.rb +27 -0
- data/lib/capybara/selector/definition/radio_button.rb +27 -0
- data/lib/capybara/selector/definition/select.rb +81 -0
- data/lib/capybara/selector/definition/table.rb +109 -0
- data/lib/capybara/selector/definition/table_row.rb +21 -0
- data/lib/capybara/selector/definition/xpath.rb +5 -0
- data/lib/capybara/selector/definition.rb +278 -0
- data/lib/capybara/selector/filter.rb +3 -46
- data/lib/capybara/selector/filter_set.rb +124 -0
- data/lib/capybara/selector/filters/base.rb +77 -0
- data/lib/capybara/selector/filters/expression_filter.rb +22 -0
- data/lib/capybara/selector/filters/locator_filter.rb +29 -0
- data/lib/capybara/selector/filters/node_filter.rb +31 -0
- data/lib/capybara/selector/regexp_disassembler.rb +214 -0
- data/lib/capybara/selector/selector.rb +155 -0
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +232 -369
- data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
- data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
- data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
- data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
- data/lib/capybara/selenium/driver.rb +380 -142
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +124 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +89 -0
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
- data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
- data/lib/capybara/selenium/extensions/find.rb +110 -0
- data/lib/capybara/selenium/extensions/html5_drag.rb +228 -0
- data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
- data/lib/capybara/selenium/extensions/scroll.rb +76 -0
- data/lib/capybara/selenium/logger_suppressor.rb +40 -0
- data/lib/capybara/selenium/node.rb +528 -97
- data/lib/capybara/selenium/nodes/chrome_node.rb +137 -0
- data/lib/capybara/selenium/nodes/edge_node.rb +104 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +136 -0
- data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
- data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
- data/lib/capybara/selenium/patches/action_pauser.rb +26 -0
- data/lib/capybara/selenium/patches/atoms.rb +18 -0
- data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
- data/lib/capybara/selenium/patches/logs.rb +45 -0
- data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
- data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
- data/lib/capybara/server/animation_disabler.rb +63 -0
- data/lib/capybara/server/checker.rb +44 -0
- data/lib/capybara/server/middleware.rb +71 -0
- data/lib/capybara/server.rb +74 -71
- data/lib/capybara/session/config.rb +126 -0
- data/lib/capybara/session/matchers.rb +44 -27
- data/lib/capybara/session.rb +500 -297
- data/lib/capybara/spec/fixtures/no_extension +1 -0
- data/lib/capybara/spec/public/jquery.js +5 -5
- data/lib/capybara/spec/public/offset.js +6 -0
- data/lib/capybara/spec/public/test.js +168 -14
- data/lib/capybara/spec/session/accept_alert_spec.rb +37 -14
- data/lib/capybara/spec/session/accept_confirm_spec.rb +7 -6
- data/lib/capybara/spec/session/accept_prompt_spec.rb +38 -10
- data/lib/capybara/spec/session/all_spec.rb +179 -59
- data/lib/capybara/spec/session/ancestor_spec.rb +88 -0
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +140 -0
- data/lib/capybara/spec/session/assert_current_path_spec.rb +75 -0
- data/lib/capybara/spec/session/assert_selector_spec.rb +143 -0
- data/lib/capybara/spec/session/assert_style_spec.rb +26 -0
- data/lib/capybara/spec/session/assert_text_spec.rb +258 -0
- data/lib/capybara/spec/session/assert_title_spec.rb +93 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +154 -48
- data/lib/capybara/spec/session/body_spec.rb +12 -13
- data/lib/capybara/spec/session/check_spec.rb +168 -41
- data/lib/capybara/spec/session/choose_spec.rb +75 -23
- data/lib/capybara/spec/session/click_button_spec.rb +243 -175
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +57 -32
- data/lib/capybara/spec/session/click_link_spec.rb +100 -53
- data/lib/capybara/spec/session/current_scope_spec.rb +11 -10
- data/lib/capybara/spec/session/current_url_spec.rb +61 -35
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +7 -7
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +5 -4
- data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +13 -6
- data/lib/capybara/spec/session/element/match_css_spec.rb +21 -7
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +9 -7
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +91 -34
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +23 -0
- data/lib/capybara/spec/session/evaluate_script_spec.rb +45 -3
- data/lib/capybara/spec/session/execute_script_spec.rb +24 -4
- data/lib/capybara/spec/session/fill_in_spec.rb +166 -64
- data/lib/capybara/spec/session/find_button_spec.rb +37 -18
- data/lib/capybara/spec/session/find_by_id_spec.rb +10 -9
- data/lib/capybara/spec/session/find_field_spec.rb +57 -34
- data/lib/capybara/spec/session/find_link_spec.rb +47 -10
- data/lib/capybara/spec/session/find_spec.rb +290 -144
- data/lib/capybara/spec/session/first_spec.rb +91 -48
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +116 -0
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +112 -0
- data/lib/capybara/spec/session/go_back_spec.rb +3 -2
- data/lib/capybara/spec/session/go_forward_spec.rb +3 -2
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
- data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +25 -0
- data/lib/capybara/spec/session/has_button_spec.rb +76 -19
- data/lib/capybara/spec/session/has_css_spec.rb +277 -131
- data/lib/capybara/spec/session/has_current_path_spec.rb +98 -26
- data/lib/capybara/spec/session/has_field_spec.rb +177 -107
- data/lib/capybara/spec/session/has_link_spec.rb +13 -12
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +78 -0
- data/lib/capybara/spec/session/has_select_spec.rb +191 -95
- data/lib/capybara/spec/session/has_selector_spec.rb +128 -64
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +172 -5
- data/lib/capybara/spec/session/has_text_spec.rb +126 -60
- data/lib/capybara/spec/session/has_title_spec.rb +35 -12
- data/lib/capybara/spec/session/has_xpath_spec.rb +74 -53
- data/lib/capybara/spec/session/{headers.rb → headers_spec.rb} +3 -2
- data/lib/capybara/spec/session/html_spec.rb +14 -6
- data/lib/capybara/spec/session/matches_style_spec.rb +35 -0
- data/lib/capybara/spec/session/node_spec.rb +1028 -131
- data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
- data/lib/capybara/spec/session/refresh_spec.rb +34 -0
- data/lib/capybara/spec/session/reset_session_spec.rb +75 -34
- data/lib/capybara/spec/session/{response_code.rb → response_code_spec.rb} +2 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +3 -2
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +11 -15
- data/lib/capybara/spec/session/save_page_spec.rb +42 -55
- data/lib/capybara/spec/session/save_screenshot_spec.rb +16 -14
- data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/scroll_spec.rb +117 -0
- data/lib/capybara/spec/session/select_spec.rb +112 -85
- data/lib/capybara/spec/session/selectors_spec.rb +71 -8
- data/lib/capybara/spec/session/sibling_spec.rb +52 -0
- data/lib/capybara/spec/session/text_spec.rb +38 -23
- data/lib/capybara/spec/session/title_spec.rb +17 -5
- data/lib/capybara/spec/session/uncheck_spec.rb +71 -12
- data/lib/capybara/spec/session/unselect_spec.rb +44 -43
- data/lib/capybara/spec/session/visit_spec.rb +99 -32
- data/lib/capybara/spec/session/window/become_closed_spec.rb +33 -29
- data/lib/capybara/spec/session/window/current_window_spec.rb +5 -3
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +5 -3
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +39 -30
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +17 -10
- data/lib/capybara/spec/session/window/window_spec.rb +121 -73
- data/lib/capybara/spec/session/window/windows_spec.rb +12 -10
- data/lib/capybara/spec/session/window/within_window_spec.rb +52 -82
- data/lib/capybara/spec/session/within_spec.rb +76 -43
- data/lib/capybara/spec/spec_helper.rb +67 -33
- data/lib/capybara/spec/test_app.rb +85 -36
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/buttons.erb +1 -1
- data/lib/capybara/spec/views/fieldsets.erb +1 -1
- data/lib/capybara/spec/views/form.erb +227 -20
- data/lib/capybara/spec/views/frame_child.erb +10 -2
- data/lib/capybara/spec/views/frame_one.erb +2 -1
- data/lib/capybara/spec/views/frame_parent.erb +2 -2
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/header_links.erb +1 -1
- data/lib/capybara/spec/views/host_links.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +47 -0
- data/lib/capybara/spec/views/offset.erb +32 -0
- data/lib/capybara/spec/views/path.erb +1 -1
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/postback.erb +1 -1
- data/lib/capybara/spec/views/react.erb +45 -0
- data/lib/capybara/spec/views/scroll.erb +20 -0
- data/lib/capybara/spec/views/spatial.erb +31 -0
- data/lib/capybara/spec/views/tables.erb +69 -2
- data/lib/capybara/spec/views/with_animation.erb +82 -0
- data/lib/capybara/spec/views/with_base_tag.erb +1 -1
- data/lib/capybara/spec/views/with_count.erb +1 -1
- data/lib/capybara/spec/views/with_dragula.erb +24 -0
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
- data/lib/capybara/spec/views/with_hover.erb +7 -1
- data/lib/capybara/spec/views/with_hover1.erb +10 -0
- data/lib/capybara/spec/views/with_html.erb +100 -10
- data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
- data/lib/capybara/spec/views/with_html_entities.erb +1 -1
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +49 -3
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_namespace.erb +20 -0
- data/lib/capybara/spec/views/with_scope.erb +1 -1
- data/lib/capybara/spec/views/with_scope_other.erb +6 -0
- data/lib/capybara/spec/views/with_simple_html.erb +1 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
- data/lib/capybara/spec/views/with_title.erb +1 -1
- data/lib/capybara/spec/views/with_unload_alert.erb +3 -1
- data/lib/capybara/spec/views/with_windows.erb +7 -1
- data/lib/capybara/spec/views/within_frames.erb +6 -3
- data/lib/capybara/version.rb +2 -1
- data/lib/capybara/window.rb +39 -21
- data/lib/capybara.rb +208 -186
- data/spec/basic_node_spec.rb +52 -39
- data/spec/capybara_spec.rb +72 -50
- data/spec/css_builder_spec.rb +101 -0
- data/spec/css_splitter_spec.rb +38 -0
- data/spec/dsl_spec.rb +81 -61
- data/spec/filter_set_spec.rb +46 -0
- data/spec/fixtures/capybara.csv +1 -0
- data/spec/fixtures/certificate.pem +25 -0
- data/spec/fixtures/key.pem +27 -0
- data/spec/fixtures/selenium_driver_rspec_failure.rb +7 -3
- data/spec/fixtures/selenium_driver_rspec_success.rb +7 -3
- data/spec/minitest_spec.rb +164 -0
- data/spec/minitest_spec_spec.rb +162 -0
- data/spec/per_session_config_spec.rb +68 -0
- data/spec/rack_test_spec.rb +189 -96
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +143 -13
- data/spec/rspec/features_spec.rb +38 -32
- data/spec/rspec/scenarios_spec.rb +9 -7
- data/spec/rspec/shared_spec_matchers.rb +959 -0
- data/spec/rspec/views_spec.rb +9 -3
- data/spec/rspec_matchers_spec.rb +62 -0
- data/spec/rspec_spec.rb +127 -30
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +458 -37
- data/spec/selenium_spec_chrome.rb +196 -9
- data/spec/selenium_spec_chrome_remote.rb +100 -0
- data/spec/selenium_spec_edge.rb +47 -0
- data/spec/selenium_spec_firefox.rb +210 -0
- data/spec/selenium_spec_firefox_remote.rb +80 -0
- data/spec/selenium_spec_ie.rb +150 -0
- data/spec/selenium_spec_safari.rb +148 -0
- data/spec/server_spec.rb +200 -101
- data/spec/session_spec.rb +91 -0
- data/spec/shared_selenium_node.rb +83 -0
- data/spec/shared_selenium_session.rb +558 -0
- data/spec/spec_helper.rb +94 -2
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +420 -60
- data/lib/capybara/query.rb +0 -7
- data/lib/capybara/spec/session/assert_current_path.rb +0 -60
- data/lib/capybara/spec/session/assert_selector.rb +0 -148
- data/lib/capybara/spec/session/assert_text.rb +0 -196
- data/lib/capybara/spec/session/assert_title.rb +0 -70
- data/lib/capybara/spec/session/source_spec.rb +0 -0
- data/lib/capybara/spec/session/within_frame_spec.rb +0 -53
- data/spec/rspec/matchers_spec.rb +0 -827
- data/spec/selenium_spec.rb +0 -151
data/License.txt
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,23 @@
|
|
1
1
|
# Capybara
|
2
2
|
|
3
|
-
[![Build Status](https://secure.travis-ci.org/
|
4
|
-
[![
|
5
|
-
[![Code Climate](https://codeclimate.com/github/
|
3
|
+
[![Build Status](https://secure.travis-ci.org/teamcapybara/capybara.svg)](https://travis-ci.org/teamcapybara/capybara)
|
4
|
+
[![Build Status](https://ci.appveyor.com/api/projects/status/github/teamcapybara/capybara?svg=true)](https://ci.appveyor.com/api/projects/github/teamcapybara/capybara)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/teamcapybara/capybara.svg)](https://codeclimate.com/github/teamcapybara/capybara)
|
6
|
+
[![Coverage Status](https://coveralls.io/repos/github/teamcapybara/capybara/badge.svg?branch=master)](https://coveralls.io/github/teamcapybara/capybara?branch=master)
|
7
|
+
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jnicklas/capybara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
8
|
+
[![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=capybara&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=capybara&package-manager=bundler&version-scheme=semver)
|
6
9
|
|
7
10
|
Capybara helps you test web applications by simulating how a real user would
|
8
11
|
interact with your app. It is agnostic about the driver running your tests and
|
9
12
|
comes with Rack::Test and Selenium support built in. WebKit is supported
|
10
13
|
through an external gem.
|
11
14
|
|
15
|
+
## Support Capybara
|
16
|
+
|
17
|
+
If you and/or your company find value in Capybara and would like to contribute financially to its ongoing maintenance and development, please visit
|
18
|
+
<a href="https://www.patreon.com/capybara">Patreon</a>
|
19
|
+
|
20
|
+
|
12
21
|
**Need help?** Ask on the mailing list (please do not open an issue on
|
13
22
|
GitHub): http://groups.google.com/group/ruby-capybara
|
14
23
|
|
@@ -19,13 +28,13 @@ GitHub): http://groups.google.com/group/ruby-capybara
|
|
19
28
|
- [Using Capybara with Cucumber](#using-capybara-with-cucumber)
|
20
29
|
- [Using Capybara with RSpec](#using-capybara-with-rspec)
|
21
30
|
- [Using Capybara with Test::Unit](#using-capybara-with-testunit)
|
22
|
-
- [Using Capybara with
|
31
|
+
- [Using Capybara with Minitest](#using-capybara-with-minitest)
|
32
|
+
- [Using Capybara with Minitest::Spec](#using-capybara-with-minitestspec)
|
23
33
|
- [Drivers](#drivers)
|
24
34
|
- [Selecting the Driver](#selecting-the-driver)
|
25
35
|
- [RackTest](#racktest)
|
26
36
|
- [Selenium](#selenium)
|
27
|
-
- [
|
28
|
-
- [Poltergeist](#poltergeist)
|
37
|
+
- [Apparition](#apparition)
|
29
38
|
- [The DSL](#the-dsl)
|
30
39
|
- [Navigating](#navigating)
|
31
40
|
- [Clicking links and buttons](#clicking-links-and-buttons)
|
@@ -44,11 +53,14 @@ GitHub): http://groups.google.com/group/ruby-capybara
|
|
44
53
|
- [Asynchronous JavaScript (Ajax and friends)](#asynchronous-javascript-ajax-and-friends)
|
45
54
|
- [Using the DSL elsewhere](#using-the-dsl-elsewhere)
|
46
55
|
- [Calling remote servers](#calling-remote-servers)
|
47
|
-
- [Using
|
56
|
+
- [Using sessions](#using-sessions)
|
57
|
+
- [Named sessions](#named-sessions)
|
58
|
+
- [Using sessions manually](#using-sessions-manually)
|
48
59
|
- [XPath, CSS and selectors](#xpath-css-and-selectors)
|
49
60
|
- [Beware the XPath // trap](#beware-the-xpath--trap)
|
50
61
|
- [Configuring and adding drivers](#configuring-and-adding-drivers)
|
51
62
|
- [Gotchas:](#gotchas)
|
63
|
+
- ["Threadsafe" mode](#threadsafe-mode)
|
52
64
|
- [Development](#development)
|
53
65
|
|
54
66
|
## <a name="key-benefits"></a>Key benefits
|
@@ -62,24 +74,19 @@ GitHub): http://groups.google.com/group/ruby-capybara
|
|
62
74
|
|
63
75
|
## <a name="setup"></a>Setup
|
64
76
|
|
65
|
-
Capybara requires Ruby
|
77
|
+
Capybara requires Ruby 2.5.0 or later. To install, add this line to your
|
66
78
|
`Gemfile` and run `bundle install`:
|
67
79
|
|
68
80
|
```ruby
|
69
81
|
gem 'capybara'
|
70
82
|
```
|
71
83
|
|
72
|
-
**Note:** If using Ruby < 2.0 you will also need to limit the version of mime-types to < 3.0
|
73
|
-
|
74
84
|
If the application that you are testing is a Rails app, add this line to your test helper file:
|
75
85
|
|
76
86
|
```ruby
|
77
87
|
require 'capybara/rails'
|
78
88
|
```
|
79
89
|
|
80
|
-
**Note:** In Rails 4.0/4.1 the default test environment (`config/environments/test.rb`) is [not threadsafe](https://github.com/rails/rails/issues/15089).
|
81
|
-
If you experience random errors about missing constants, add `config.allow_concurrency = false` to `config/environments/test.rb`.
|
82
|
-
|
83
90
|
If the application that you are testing is a Rack app, but not Rails, set Capybara.app to your Rack app:
|
84
91
|
|
85
92
|
```ruby
|
@@ -87,7 +94,13 @@ Capybara.app = MyRackApp
|
|
87
94
|
```
|
88
95
|
|
89
96
|
If you need to test JavaScript, or if your app interacts with (or is located at)
|
90
|
-
a remote URL, you'll need to [use a different driver](#drivers).
|
97
|
+
a remote URL, you'll need to [use a different driver](#drivers). If using Rails 5.0+, but not using the Rails system tests from 5.1, you'll probably also
|
98
|
+
want to swap the "server" used to launch your app to Puma in order to match Rails defaults.
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
Capybara.server = :puma # Until your setup is working
|
102
|
+
Capybara.server = :puma, { Silent: true } # To clean up your test output
|
103
|
+
```
|
91
104
|
|
92
105
|
## <a name="using-capybara-with-cucumber"></a>Using Capybara with Cucumber
|
93
106
|
|
@@ -104,8 +117,8 @@ You can use the Capybara DSL in your steps, like so:
|
|
104
117
|
```ruby
|
105
118
|
When /I sign in/ do
|
106
119
|
within("#session") do
|
107
|
-
fill_in 'Email', :
|
108
|
-
fill_in 'Password', :
|
120
|
+
fill_in 'Email', with: 'user@example.com'
|
121
|
+
fill_in 'Password', with: 'password'
|
109
122
|
end
|
110
123
|
click_button 'Sign in'
|
111
124
|
end
|
@@ -121,40 +134,39 @@ Scenario: do something Ajaxy
|
|
121
134
|
...
|
122
135
|
```
|
123
136
|
|
124
|
-
There are also explicit `@selenium
|
125
|
-
tags set up for you.
|
137
|
+
There are also explicit tags for each registered driver set up for you (`@selenium`, `@rack_test`, etc).
|
126
138
|
|
127
139
|
## <a name="using-capybara-with-rspec"></a>Using Capybara with RSpec
|
128
140
|
|
129
|
-
Load RSpec
|
141
|
+
Load RSpec 3.5+ support by adding the following line (typically to your
|
130
142
|
`spec_helper.rb` file):
|
131
143
|
|
132
144
|
```ruby
|
133
145
|
require 'capybara/rspec'
|
134
146
|
```
|
135
147
|
|
136
|
-
If you are using Rails, put your Capybara specs in `spec/features` (only works
|
148
|
+
If you are using Rails, put your Capybara specs in `spec/features` or `spec/system` (only works
|
137
149
|
if [you have it configured in
|
138
|
-
RSpec](https://
|
150
|
+
RSpec](https://relishapp.com/rspec/rspec-rails/v/4-0/docs/directory-structure))
|
139
151
|
and if you have your Capybara specs in a different directory, then tag the
|
140
|
-
example groups with
|
152
|
+
example groups with `type: :feature` or `type: :system` depending on which type of test you're writing.
|
141
153
|
|
142
154
|
If you are not using Rails, tag all the example groups in which you want to use
|
143
|
-
Capybara with
|
155
|
+
Capybara with `type: :feature`.
|
144
156
|
|
145
157
|
You can now write your specs like so:
|
146
158
|
|
147
159
|
```ruby
|
148
|
-
describe "the signin process", :
|
160
|
+
describe "the signin process", type: :feature do
|
149
161
|
before :each do
|
150
|
-
User.make(:
|
162
|
+
User.make(email: 'user@example.com', password: 'password')
|
151
163
|
end
|
152
164
|
|
153
165
|
it "signs me in" do
|
154
166
|
visit '/sessions/new'
|
155
167
|
within("#session") do
|
156
|
-
fill_in 'Email', :
|
157
|
-
fill_in 'Password', :
|
168
|
+
fill_in 'Email', with: 'user@example.com'
|
169
|
+
fill_in 'Password', with: 'password'
|
158
170
|
end
|
159
171
|
click_button 'Sign in'
|
160
172
|
expect(page).to have_content 'Success'
|
@@ -162,14 +174,14 @@ describe "the signin process", :type => :feature do
|
|
162
174
|
end
|
163
175
|
```
|
164
176
|
|
165
|
-
Use
|
177
|
+
Use `js: true` to switch to the `Capybara.javascript_driver`
|
166
178
|
(`:selenium` by default), or provide a `:driver` option to switch
|
167
179
|
to one specific driver. For example:
|
168
180
|
|
169
181
|
```ruby
|
170
|
-
describe 'some stuff which requires js', :
|
182
|
+
describe 'some stuff which requires js', js: true do
|
171
183
|
it 'will use the default js driver'
|
172
|
-
it 'will switch to one specific driver', :
|
184
|
+
it 'will switch to one specific driver', driver: :apparition
|
173
185
|
end
|
174
186
|
```
|
175
187
|
|
@@ -178,26 +190,26 @@ Capybara also comes with a built in DSL for creating descriptive acceptance test
|
|
178
190
|
```ruby
|
179
191
|
feature "Signing in" do
|
180
192
|
background do
|
181
|
-
User.make(:
|
193
|
+
User.make(email: 'user@example.com', password: 'caplin')
|
182
194
|
end
|
183
195
|
|
184
196
|
scenario "Signing in with correct credentials" do
|
185
197
|
visit '/sessions/new'
|
186
198
|
within("#session") do
|
187
|
-
fill_in 'Email', :
|
188
|
-
fill_in 'Password', :
|
199
|
+
fill_in 'Email', with: 'user@example.com'
|
200
|
+
fill_in 'Password', with: 'caplin'
|
189
201
|
end
|
190
202
|
click_button 'Sign in'
|
191
203
|
expect(page).to have_content 'Success'
|
192
204
|
end
|
193
205
|
|
194
|
-
given(:other_user) { User.make(:
|
206
|
+
given(:other_user) { User.make(email: 'other@example.com', password: 'rous') }
|
195
207
|
|
196
208
|
scenario "Signing in as another user" do
|
197
209
|
visit '/sessions/new'
|
198
210
|
within("#session") do
|
199
|
-
fill_in 'Email', :
|
200
|
-
fill_in 'Password', :
|
211
|
+
fill_in 'Email', with: other_user.email
|
212
|
+
fill_in 'Password', with: other_user.password
|
201
213
|
end
|
202
214
|
click_button 'Sign in'
|
203
215
|
expect(page).to have_content 'Invalid email or password'
|
@@ -205,11 +217,11 @@ feature "Signing in" do
|
|
205
217
|
end
|
206
218
|
```
|
207
219
|
|
208
|
-
`feature` is in fact just an alias for `describe ..., :
|
220
|
+
`feature` is in fact just an alias for `describe ..., type: :feature`,
|
209
221
|
`background` is an alias for `before`, `scenario` for `it`, and
|
210
222
|
`given`/`given!` aliases for `let`/`let!`, respectively.
|
211
223
|
|
212
|
-
Finally, Capybara matchers are supported in view specs:
|
224
|
+
Finally, Capybara matchers are also supported in view specs:
|
213
225
|
|
214
226
|
```ruby
|
215
227
|
RSpec.describe "todos/show.html.erb", type: :view do
|
@@ -223,20 +235,45 @@ RSpec.describe "todos/show.html.erb", type: :view do
|
|
223
235
|
end
|
224
236
|
```
|
225
237
|
|
238
|
+
**Note: When you require 'capybara/rspec' proxy methods are installed to work around name collisions between Capybara::DSL methods
|
239
|
+
`all`/`within` and the identically named built-in RSpec matchers. If you opt not to require 'capybara/rspec' you can install the proxy methods by requiring 'capybara/rspec/matcher_proxies' after requiring RSpec and 'capybara/dsl'**
|
240
|
+
|
226
241
|
## <a name="using-capybara-with-testunit"></a>Using Capybara with Test::Unit
|
227
242
|
|
228
|
-
* If you are using
|
243
|
+
* If you are using `Test::Unit`, define a base class for your Capybara tests
|
244
|
+
like so:
|
245
|
+
|
246
|
+
```ruby
|
247
|
+
require 'capybara/dsl'
|
248
|
+
|
249
|
+
class CapybaraTestCase < Test::Unit::TestCase
|
250
|
+
include Capybara::DSL
|
251
|
+
|
252
|
+
def teardown
|
253
|
+
Capybara.reset_sessions!
|
254
|
+
Capybara.use_default_driver
|
255
|
+
end
|
256
|
+
end
|
257
|
+
```
|
258
|
+
|
259
|
+
## <a name="using-capybara-with-minitest"></a>Using Capybara with Minitest
|
260
|
+
|
261
|
+
* If you are using Rails, but not using Rails system tests, add the following code in your `test_helper.rb`
|
229
262
|
file to make Capybara available in all test cases deriving from
|
230
263
|
`ActionDispatch::IntegrationTest`:
|
231
264
|
|
232
265
|
```ruby
|
266
|
+
require 'capybara/rails'
|
267
|
+
require 'capybara/minitest'
|
268
|
+
|
233
269
|
class ActionDispatch::IntegrationTest
|
234
270
|
# Make the Capybara DSL available in all integration tests
|
235
271
|
include Capybara::DSL
|
272
|
+
# Make `assert_*` methods behave like Minitest assertions
|
273
|
+
include Capybara::Minitest::Assertions
|
236
274
|
|
237
275
|
# Reset sessions and driver between tests
|
238
|
-
|
239
|
-
def teardown
|
276
|
+
teardown do
|
240
277
|
Capybara.reset_sessions!
|
241
278
|
Capybara.use_default_driver
|
242
279
|
end
|
@@ -247,8 +284,11 @@ end
|
|
247
284
|
so:
|
248
285
|
|
249
286
|
```ruby
|
250
|
-
|
287
|
+
require 'capybara/minitest'
|
288
|
+
|
289
|
+
class CapybaraTestCase < Minitest::Test
|
251
290
|
include Capybara::DSL
|
291
|
+
include Capybara::Minitest::Assertions
|
252
292
|
|
253
293
|
def teardown
|
254
294
|
Capybara.reset_sessions!
|
@@ -274,14 +314,9 @@ class BlogTest < ActionDispatch::IntegrationTest
|
|
274
314
|
end
|
275
315
|
```
|
276
316
|
|
277
|
-
## <a name="using-capybara-with-minitestspec"></a>Using Capybara with
|
317
|
+
## <a name="using-capybara-with-minitestspec"></a>Using Capybara with Minitest::Spec
|
278
318
|
|
279
|
-
|
280
|
-
could be something other than ActionDispatch::IntegrationTest.)
|
281
|
-
|
282
|
-
The capybara_minitest_spec gem ([GitHub](https://github.com/ordinaryzelig/capybara_minitest_spec),
|
283
|
-
[rubygems.org](https://rubygems.org/gems/capybara_minitest_spec)) provides MiniTest::Spec
|
284
|
-
expectations for Capybara. For example:
|
319
|
+
Follow the above instructions for Minitest and additionally require capybara/minitest/spec
|
285
320
|
|
286
321
|
```ruby
|
287
322
|
page.must_have_content('Important!')
|
@@ -300,12 +335,12 @@ these limitations, you can set up a different default driver for your features.
|
|
300
335
|
For example if you'd prefer to run everything in Selenium, you could do:
|
301
336
|
|
302
337
|
```ruby
|
303
|
-
Capybara.default_driver = :selenium
|
338
|
+
Capybara.default_driver = :selenium # :selenium_chrome and :selenium_chrome_headless are also registered
|
304
339
|
```
|
305
340
|
|
306
|
-
However, if you are using RSpec or Cucumber
|
307
|
-
leaving the faster `:rack_test` as the __default_driver__, and
|
308
|
-
tests that require a JavaScript-capable driver using
|
341
|
+
However, if you are using RSpec or Cucumber (and your app runs correctly without JS),
|
342
|
+
you may instead want to consider leaving the faster `:rack_test` as the __default_driver__, and
|
343
|
+
marking only those tests that require a JavaScript-capable driver using `js: true` or
|
309
344
|
`@javascript`, respectively. By default, JavaScript tests are run using the
|
310
345
|
`:selenium` driver. You can change this by setting
|
311
346
|
`Capybara.javascript_driver`.
|
@@ -314,7 +349,7 @@ You can also change the driver temporarily (typically in the Before/setup and
|
|
314
349
|
After/teardown blocks):
|
315
350
|
|
316
351
|
```ruby
|
317
|
-
Capybara.current_driver = :
|
352
|
+
Capybara.current_driver = :apparition # temporarily select different driver
|
318
353
|
# tests here
|
319
354
|
Capybara.use_default_driver # switch back to default driver
|
320
355
|
```
|
@@ -341,7 +376,7 @@ RackTest can be configured with a set of headers like this:
|
|
341
376
|
|
342
377
|
```ruby
|
343
378
|
Capybara.register_driver :rack_test do |app|
|
344
|
-
Capybara::RackTest::Driver.new(app, :
|
379
|
+
Capybara::RackTest::Driver.new(app, headers: { 'HTTP_USER_AGENT' => 'Capybara' })
|
345
380
|
end
|
346
381
|
```
|
347
382
|
|
@@ -349,47 +384,40 @@ See the section on adding and configuring drivers.
|
|
349
384
|
|
350
385
|
### <a name="selenium"></a>Selenium
|
351
386
|
|
352
|
-
|
353
|
-
(Webdriver)](
|
354
|
-
|
355
|
-
|
356
|
-
Provided Firefox is installed, everything is set up for you, and you should be
|
357
|
-
able to start using Selenium right away.
|
387
|
+
Capybara supports [Selenium 3.5+
|
388
|
+
(Webdriver)](https://www.seleniumhq.org/projects/webdriver/).
|
389
|
+
In order to use Selenium, you'll need to install the `selenium-webdriver` gem,
|
390
|
+
and add it to your Gemfile if you're using bundler.
|
358
391
|
|
359
|
-
|
360
|
-
same transaction as your tests, causing data not to be shared between your test
|
361
|
-
and test server, see "Transactions and database setup" below.
|
392
|
+
Capybara pre-registers a number of named drivers that use Selenium - they are:
|
362
393
|
|
363
|
-
|
394
|
+
* :selenium => Selenium driving Firefox
|
395
|
+
* :selenium_headless => Selenium driving Firefox in a headless configuration
|
396
|
+
* :selenium_chrome => Selenium driving Chrome
|
397
|
+
* :selenium_chrome_headless => Selenium driving Chrome in a headless configuration
|
364
398
|
|
365
|
-
|
366
|
-
|
367
|
-
|
399
|
+
These should work (with relevant software installation) in a local desktop configuration but you may
|
400
|
+
need to customize them if using in a CI environment where additional options may need to be passed
|
401
|
+
to the browsers. See the section on adding and configuring drivers.
|
368
402
|
|
369
|
-
You can install it with:
|
370
403
|
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
And you can use it by:
|
376
|
-
|
377
|
-
```ruby
|
378
|
-
Capybara.javascript_driver = :webkit
|
379
|
-
```
|
404
|
+
**Note**: drivers which run the server in a different thread may not share the
|
405
|
+
same transaction as your tests, causing data not to be shared between your test
|
406
|
+
and test server, see [Transactions and database setup](#transactions-and-database-setup) below.
|
380
407
|
|
381
|
-
### <a name="
|
408
|
+
### <a name="apparition"></a>Apparition
|
382
409
|
|
383
|
-
[
|
384
|
-
|
385
|
-
[
|
386
|
-
|
387
|
-
|
410
|
+
The [apparition driver](https://github.com/twalpole/apparition) is a new driver that allows you to run tests using Chrome in a headless
|
411
|
+
or headed configuration. It attempts to provide backwards compatibility with the [Poltergeist driver API](https://github.com/teampoltergeist/poltergeist)
|
412
|
+
and [capybara-webkit API](https://github.com/thoughtbot/capybara-webkit) while allowing for the use of modern JS/CSS. It
|
413
|
+
uses CDP to communicate with Chrome, thereby obviating the need for chromedriver. This driver is being developed by the
|
414
|
+
current developer of Capybara and will attempt to keep up to date with new Capybara releases. It will probably be moved into the
|
415
|
+
teamcapybara repo once it reaches v1.0.
|
388
416
|
|
389
417
|
## <a name="the-dsl"></a>The DSL
|
390
418
|
|
391
419
|
*A complete reference is available at
|
392
|
-
[rubydoc.info](http://rubydoc.info/github/
|
420
|
+
[rubydoc.info](http://rubydoc.info/github/teamcapybara/capybara/master)*.
|
393
421
|
|
394
422
|
**Note: By default Capybara will only locate visible elements. This is because
|
395
423
|
a real user would not be able to interact with non-visible elements.**
|
@@ -400,7 +428,7 @@ Capybara heavily uses XPath, which doesn't support case insensitivity.
|
|
400
428
|
### <a name="navigating"></a>Navigating
|
401
429
|
|
402
430
|
You can use the
|
403
|
-
<tt>[visit](http://rubydoc.info/github/
|
431
|
+
<tt>[visit](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session#visit-instance_method)</tt>
|
404
432
|
method to navigate to other pages:
|
405
433
|
|
406
434
|
```ruby
|
@@ -411,8 +439,8 @@ visit(post_comments_path(post))
|
|
411
439
|
The visit method only takes a single parameter, the request method is **always**
|
412
440
|
GET.
|
413
441
|
|
414
|
-
You can get the [current path](http://rubydoc.info/github/
|
415
|
-
of the browsing session, and test it using the [`have_current_path`](http://www.rubydoc.info/github/
|
442
|
+
You can get the [current path](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session#current_path-instance_method)
|
443
|
+
of the browsing session, and test it using the [`have_current_path`](http://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/RSpecMatchers#have_current_path-instance_method) matcher:
|
416
444
|
|
417
445
|
```ruby
|
418
446
|
expect(page).to have_current_path(post_comments_path(post))
|
@@ -425,7 +453,7 @@ to ensure that preceding actions (such as a `click_link`) have completed.
|
|
425
453
|
|
426
454
|
### <a name="clicking-links-and-buttons"></a>Clicking links and buttons
|
427
455
|
|
428
|
-
*Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/
|
456
|
+
*Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions)*
|
429
457
|
|
430
458
|
You can interact with the webapp by following links and buttons. Capybara
|
431
459
|
automatically follows any redirects, and submits forms associated with buttons.
|
@@ -440,33 +468,33 @@ click_on('Button Value')
|
|
440
468
|
|
441
469
|
### <a name="interacting-with-forms"></a>Interacting with forms
|
442
470
|
|
443
|
-
*Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/
|
471
|
+
*Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions)*
|
444
472
|
|
445
473
|
There are a number of tools for interacting with form elements:
|
446
474
|
|
447
475
|
```ruby
|
448
|
-
fill_in('First Name', :
|
449
|
-
fill_in('Password', :
|
450
|
-
fill_in('Description', :
|
476
|
+
fill_in('First Name', with: 'John')
|
477
|
+
fill_in('Password', with: 'Seekrit')
|
478
|
+
fill_in('Description', with: 'Really Long Text...')
|
451
479
|
choose('A Radio Button')
|
452
480
|
check('A Checkbox')
|
453
481
|
uncheck('A Checkbox')
|
454
482
|
attach_file('Image', '/path/to/image.jpg')
|
455
|
-
select('Option', :
|
483
|
+
select('Option', from: 'Select Box')
|
456
484
|
```
|
457
485
|
|
458
486
|
### <a name="querying"></a>Querying
|
459
487
|
|
460
|
-
*Full reference: [Capybara::Node::Matchers](http://rubydoc.info/github/
|
488
|
+
*Full reference: [Capybara::Node::Matchers](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Matchers)*
|
461
489
|
|
462
490
|
Capybara has a rich set of options for querying the page for the existence of
|
463
491
|
certain elements, and working with and manipulating those elements.
|
464
492
|
|
465
493
|
```ruby
|
466
494
|
page.has_selector?('table tr')
|
467
|
-
page.has_selector?(:xpath, '
|
495
|
+
page.has_selector?(:xpath, './/table/tr')
|
468
496
|
|
469
|
-
page.has_xpath?('
|
497
|
+
page.has_xpath?('.//table/tr')
|
470
498
|
page.has_css?('table tr.foo')
|
471
499
|
page.has_content?('foo')
|
472
500
|
```
|
@@ -478,29 +506,41 @@ You can use these with RSpec's magic matchers:
|
|
478
506
|
|
479
507
|
```ruby
|
480
508
|
expect(page).to have_selector('table tr')
|
481
|
-
expect(page).to have_selector(:xpath, '
|
509
|
+
expect(page).to have_selector(:xpath, './/table/tr')
|
482
510
|
|
483
|
-
expect(page).to have_xpath('
|
511
|
+
expect(page).to have_xpath('.//table/tr')
|
484
512
|
expect(page).to have_css('table tr.foo')
|
485
513
|
expect(page).to have_content('foo')
|
486
514
|
```
|
487
515
|
|
488
516
|
### <a name="finding"></a>Finding
|
489
517
|
|
490
|
-
_Full reference: [Capybara::Node::Finders](http://rubydoc.info/github/
|
518
|
+
_Full reference: [Capybara::Node::Finders](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders)_
|
491
519
|
|
492
520
|
You can also find specific elements, in order to manipulate them:
|
493
521
|
|
494
522
|
```ruby
|
495
523
|
find_field('First Name').value
|
524
|
+
find_field(id: 'my_field').value
|
496
525
|
find_link('Hello', :visible => :all).visible?
|
526
|
+
find_link(class: ['some_class', 'some_other_class'], :visible => :all).visible?
|
527
|
+
|
497
528
|
find_button('Send').click
|
529
|
+
find_button(value: '1234').click
|
498
530
|
|
499
|
-
find(:xpath, "
|
531
|
+
find(:xpath, ".//table/tr").click
|
500
532
|
find("#overlay").find("h1").click
|
501
533
|
all('a').each { |a| a[:href] }
|
502
534
|
```
|
503
535
|
|
536
|
+
If you need to find elements by additional attributes/properties you can also pass a filter block, which will be checked inside the normal waiting behavior.
|
537
|
+
If you find yourself needing to use this a lot you may be better off adding a [custom selector](http://www.rubydoc.info/github/teamcapybara/capybara/Capybara#add_selector-class_method) or [adding a filter to an existing selector](http://www.rubydoc.info/github/teamcapybara/capybara/Capybara#modify_selector-class_method).
|
538
|
+
|
539
|
+
```ruby
|
540
|
+
find_field('First Name'){ |el| el['data-xyz'] == '123' }
|
541
|
+
find("#img_loading"){ |img| img['complete'] == true }
|
542
|
+
```
|
543
|
+
|
504
544
|
**Note**: `find` will wait for an element to appear on the page, as explained in the
|
505
545
|
Ajax section. If the element does not appear it will raise an error.
|
506
546
|
|
@@ -517,16 +557,16 @@ expect(find('#navigation')).to have_button('Sign out')
|
|
517
557
|
Capybara makes it possible to restrict certain actions, such as interacting with
|
518
558
|
forms or clicking links and buttons, to within a specific area of the page. For
|
519
559
|
this purpose you can use the generic
|
520
|
-
<tt>[within](http://rubydoc.info/github/
|
560
|
+
<tt>[within](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session#within-instance_method)</tt>
|
521
561
|
method. Optionally you can specify which kind of selector to use.
|
522
562
|
|
523
563
|
```ruby
|
524
564
|
within("li#employee") do
|
525
|
-
fill_in 'Name', :
|
565
|
+
fill_in 'Name', with: 'Jimmy'
|
526
566
|
end
|
527
567
|
|
528
|
-
within(:xpath, "
|
529
|
-
fill_in 'Name', :
|
568
|
+
within(:xpath, ".//li[@id='employee']") do
|
569
|
+
fill_in 'Name', with: 'Jimmy'
|
530
570
|
end
|
531
571
|
```
|
532
572
|
|
@@ -536,11 +576,11 @@ specific table, identified by either id or text of the table's caption tag.
|
|
536
576
|
|
537
577
|
```ruby
|
538
578
|
within_fieldset('Employee') do
|
539
|
-
fill_in 'Name', :
|
579
|
+
fill_in 'Name', with: 'Jimmy'
|
540
580
|
end
|
541
581
|
|
542
582
|
within_table('Employee') do
|
543
|
-
fill_in 'Name', :
|
583
|
+
fill_in 'Name', with: 'Jimmy'
|
544
584
|
end
|
545
585
|
```
|
546
586
|
|
@@ -567,13 +607,23 @@ In drivers which support it, you can easily execute JavaScript:
|
|
567
607
|
page.execute_script("$('body').empty()")
|
568
608
|
```
|
569
609
|
|
570
|
-
For simple expressions, you can return the result of the script.
|
571
|
-
that this may break with more complicated expressions:
|
610
|
+
For simple expressions, you can return the result of the script.
|
572
611
|
|
573
612
|
```ruby
|
574
613
|
result = page.evaluate_script('4 + 4');
|
575
614
|
```
|
576
615
|
|
616
|
+
For more complicated scripts you'll need to write them as one expression.
|
617
|
+
|
618
|
+
```ruby
|
619
|
+
result = page.evaluate_script(<<~JS, 3, element)
|
620
|
+
(function(n, el){
|
621
|
+
var val = parseInt(el.value, 10);
|
622
|
+
return n+val;
|
623
|
+
})(arguments[0], arguments[1])
|
624
|
+
JS
|
625
|
+
```
|
626
|
+
|
577
627
|
### <a name="modals"></a>Modals
|
578
628
|
|
579
629
|
In drivers which support it, you can accept, dismiss and respond to alerts, confirms and prompts.
|
@@ -622,7 +672,7 @@ save_and_open_page
|
|
622
672
|
```
|
623
673
|
|
624
674
|
You can also retrieve the current state of the DOM as a string using
|
625
|
-
<tt>[page.html](http://rubydoc.info/github/
|
675
|
+
<tt>[page.html](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session#html-instance_method)</tt>.
|
626
676
|
|
627
677
|
```ruby
|
628
678
|
print page.html
|
@@ -643,6 +693,10 @@ Or have it save and automatically open:
|
|
643
693
|
save_and_open_screenshot
|
644
694
|
```
|
645
695
|
|
696
|
+
Screenshots are saved to `Capybara.save_path`, relative to the app directory.
|
697
|
+
If you have required `capybara/rails`, `Capybara.save_path` will default to
|
698
|
+
`tmp/capybara`.
|
699
|
+
|
646
700
|
## <a name="matching"></a>Matching
|
647
701
|
|
648
702
|
It is possible to customize how Capybara finds elements. At your disposal
|
@@ -688,6 +742,9 @@ Capybara 1.x, set `Capybara.match` to `:prefer_exact`.
|
|
688
742
|
|
689
743
|
## <a name="transactions-and-database-setup"></a>Transactions and database setup
|
690
744
|
|
745
|
+
**Note:** Rails 5.1+ "safely" shares the database connection between the app and test threads. Therefore,
|
746
|
+
if using Rails 5.1+ you SHOULD be able to ignore this section.
|
747
|
+
|
691
748
|
Some Capybara drivers need to run against an actual HTTP server. Capybara takes
|
692
749
|
care of this and starts one for you in the same process as your test, but on
|
693
750
|
another thread. Selenium is one of those drivers, whereas RackTest is not.
|
@@ -778,9 +835,9 @@ module MyModule
|
|
778
835
|
include Capybara::DSL
|
779
836
|
|
780
837
|
def login!
|
781
|
-
within("
|
782
|
-
fill_in 'Email', :
|
783
|
-
fill_in 'Password', :
|
838
|
+
within(:xpath, ".//form[@id='session']") do
|
839
|
+
fill_in 'Email', with: 'user@example.com'
|
840
|
+
fill_in 'Password', with: 'password'
|
784
841
|
end
|
785
842
|
click_button 'Sign in'
|
786
843
|
end
|
@@ -818,19 +875,40 @@ remote application:
|
|
818
875
|
Capybara.run_server = false
|
819
876
|
```
|
820
877
|
|
821
|
-
## <a name="using-
|
878
|
+
## <a name="using-sessions"></a>Using sessions
|
879
|
+
|
880
|
+
Capybara manages named sessions (:default if not specified) allowing multiple sessions using the same driver and test app instance to be interacted with.
|
881
|
+
A new session will be created using the current driver if a session with the given name using the current driver and test app instance is not found.
|
882
|
+
|
883
|
+
### Named sessions
|
884
|
+
To perform operations in a different session and then revert to the previous session
|
885
|
+
|
886
|
+
```ruby
|
887
|
+
Capybara.using_session("Bob's session") do
|
888
|
+
#do something in Bob's browser session
|
889
|
+
end
|
890
|
+
#reverts to previous session
|
891
|
+
```
|
892
|
+
|
893
|
+
To permanently switch the current session to a different session
|
894
|
+
|
895
|
+
```ruby
|
896
|
+
Capybara.session_name = "some other session"
|
897
|
+
```
|
898
|
+
|
899
|
+
### <a name="using-sessions-manually"></a>Using sessions manually
|
822
900
|
|
823
901
|
For ultimate control, you can instantiate and use a
|
824
|
-
[Session](http://rubydoc.info/github/
|
902
|
+
[Session](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session)
|
825
903
|
manually.
|
826
904
|
|
827
905
|
```ruby
|
828
906
|
require 'capybara'
|
829
907
|
|
830
908
|
session = Capybara::Session.new(:webkit, my_rack_app)
|
831
|
-
session.within("
|
832
|
-
session.fill_in 'Email', :
|
833
|
-
session.fill_in 'Password', :
|
909
|
+
session.within("form#session") do
|
910
|
+
session.fill_in 'Email', with: 'user@example.com'
|
911
|
+
session.fill_in 'Password', with: 'password'
|
834
912
|
end
|
835
913
|
session.click_button 'Sign in'
|
836
914
|
```
|
@@ -842,24 +920,29 @@ and will always use CSS by default. If you want to use XPath, you'll need to
|
|
842
920
|
do:
|
843
921
|
|
844
922
|
```ruby
|
845
|
-
within(:xpath, '
|
846
|
-
find(:xpath, '
|
847
|
-
find(:xpath, '
|
923
|
+
within(:xpath, './/ul/li') { ... }
|
924
|
+
find(:xpath, './/ul/li').text
|
925
|
+
find(:xpath, './/li[contains(.//a[@href = "#"]/text(), "foo")]').value
|
848
926
|
```
|
849
927
|
|
850
928
|
Alternatively you can set the default selector to XPath:
|
851
929
|
|
852
930
|
```ruby
|
853
931
|
Capybara.default_selector = :xpath
|
854
|
-
find('
|
932
|
+
find('.//ul/li').text
|
855
933
|
```
|
856
934
|
|
857
|
-
Capybara
|
858
|
-
|
935
|
+
Capybara provides a number of other built-in selector types. The full list, along
|
936
|
+
with applicable filters, can be seen at [built-in selectors](https://www.rubydoc.info/github/teamcapybara/capybara/Capybara/Selector)
|
937
|
+
|
938
|
+
Capybara also allows you to add custom selectors, which can be very useful if you
|
939
|
+
find yourself using the same kinds of selectors very often. The examples below are very
|
940
|
+
simple, and there are many available features not demonstrated. For more in-depth examples
|
941
|
+
please see Capybaras built-in selector definitions.
|
859
942
|
|
860
943
|
```ruby
|
861
|
-
Capybara.add_selector(:
|
862
|
-
xpath { |id| XPath.descendant[XPath.attr(:
|
944
|
+
Capybara.add_selector(:my_attribute) do
|
945
|
+
xpath { |id| XPath.descendant[XPath.attr(:my_attribute) == id.to_s] }
|
863
946
|
end
|
864
947
|
|
865
948
|
Capybara.add_selector(:row) do
|
@@ -876,9 +959,9 @@ an XPath expression generated through the XPath gem. You can now use these
|
|
876
959
|
selectors like this:
|
877
960
|
|
878
961
|
```ruby
|
879
|
-
find(:
|
880
|
-
find(:row, 3)
|
881
|
-
find(:flash_type, :notice)
|
962
|
+
find(:my_attribute, 'post_123') # find element with matching attribute
|
963
|
+
find(:row, 3) # find 3rd row in table body
|
964
|
+
find(:flash_type, :notice) # find element with id of 'flash' and class of 'notice'
|
882
965
|
```
|
883
966
|
|
884
967
|
## <a name="beware-the-xpath--trap"></a>Beware the XPath // trap
|
@@ -924,6 +1007,7 @@ end
|
|
924
1007
|
However, it's also possible to give this configuration a different name.
|
925
1008
|
|
926
1009
|
```ruby
|
1010
|
+
# Note: Capybara registers this by default
|
927
1011
|
Capybara.register_driver :selenium_chrome do |app|
|
928
1012
|
Capybara::Selenium::Driver.new(app, :browser => :chrome)
|
929
1013
|
end
|
@@ -969,15 +1053,52 @@ additional info about how the underlying driver can be configured.
|
|
969
1053
|
are testing for specific server errors and using multiple sessions make sure to test for the
|
970
1054
|
errors using the initial session (usually :default)
|
971
1055
|
|
1056
|
+
* If WebMock is enabled, you may encounter a "Too many open files"
|
1057
|
+
error. A simple `page.find` call may cause thousands of HTTP requests
|
1058
|
+
until the timeout occurs. By default, WebMock will cause each of these
|
1059
|
+
requests to spawn a new connection. To work around this problem, you
|
1060
|
+
may need to [enable WebMock's `net_http_connect_on_start: true`
|
1061
|
+
parameter](https://github.com/bblimke/webmock/blob/master/README.md#connecting-on-nethttpstart).
|
1062
|
+
|
1063
|
+
## <a name="threadsafe"></a>"Threadsafe" mode
|
1064
|
+
|
1065
|
+
In normal mode most of Capybara's configuration options are global settings which can cause issues
|
1066
|
+
if using multiple sessions and wanting to change a setting for only one of the sessions. To provide
|
1067
|
+
support for this type of usage Capybara now provides a "threadsafe" mode which can be enabled by setting
|
1068
|
+
|
1069
|
+
```ruby
|
1070
|
+
Capybara.threadsafe = true
|
1071
|
+
```
|
1072
|
+
|
1073
|
+
This setting can only be changed before any sessions have been created. In "threadsafe" mode the following
|
1074
|
+
behaviors of Capybara change
|
1075
|
+
|
1076
|
+
* Most options can now be set on a session. These can either be set at session creation time or after, and
|
1077
|
+
default to the global options at the time of session creation. Options which are NOT session specific are
|
1078
|
+
`app`, `reuse_server`, `default_driver`, `javascript_driver`, and (obviously) `threadsafe`. Any drivers and servers
|
1079
|
+
registered through `register_driver` and `register_server` are also global.
|
1080
|
+
|
1081
|
+
```ruby
|
1082
|
+
my_session = Capybara::Session.new(:driver, some_app) do |config|
|
1083
|
+
config.automatic_label_click = true # only set for my_session
|
1084
|
+
end
|
1085
|
+
my_session.config.default_max_wait_time = 10 # only set for my_session
|
1086
|
+
Capybara.default_max_wait_time = 2 # will not change the default_max_wait in my_session
|
1087
|
+
```
|
1088
|
+
|
1089
|
+
* `current_driver` and `session_name` are thread specific. This means that `using_session` and
|
1090
|
+
`using_driver` also only affect the current thread.
|
1091
|
+
|
972
1092
|
## <a name="development"></a>Development
|
973
1093
|
|
974
1094
|
To set up a development environment, simply do:
|
975
1095
|
|
976
1096
|
```bash
|
977
1097
|
bundle install
|
978
|
-
bundle exec rake # run the test suite
|
1098
|
+
bundle exec rake # run the test suite with Firefox - requires `geckodriver` to be installed
|
1099
|
+
bundle exec rake spec_chrome # run the test suite with Chrome - require `chromedriver` to be installed
|
979
1100
|
```
|
980
1101
|
|
981
1102
|
See
|
982
|
-
[CONTRIBUTING.md](https://github.com/
|
1103
|
+
[CONTRIBUTING.md](https://github.com/teamcapybara/capybara/blob/master/CONTRIBUTING.md)
|
983
1104
|
for how to send issues and pull requests.
|