capybara 2.7.0 → 3.35.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.yardopts +1 -0
- data/History.md +1147 -11
- data/License.txt +1 -1
- data/README.md +252 -131
- data/lib/capybara/config.rb +92 -0
- data/lib/capybara/cucumber.rb +3 -3
- data/lib/capybara/driver/base.rb +52 -21
- data/lib/capybara/driver/node.rb +48 -14
- data/lib/capybara/dsl.rb +16 -9
- data/lib/capybara/helpers.rb +72 -81
- data/lib/capybara/minitest/spec.rb +267 -0
- data/lib/capybara/minitest.rb +385 -0
- data/lib/capybara/node/actions.rb +337 -89
- data/lib/capybara/node/base.rb +50 -32
- data/lib/capybara/node/document.rb +19 -3
- data/lib/capybara/node/document_matchers.rb +22 -24
- data/lib/capybara/node/element.rb +388 -125
- data/lib/capybara/node/finders.rb +231 -121
- data/lib/capybara/node/matchers.rb +503 -217
- data/lib/capybara/node/simple.rb +64 -27
- data/lib/capybara/queries/ancestor_query.rb +27 -0
- data/lib/capybara/queries/base_query.rb +87 -11
- data/lib/capybara/queries/current_path_query.rb +24 -24
- data/lib/capybara/queries/match_query.rb +15 -10
- data/lib/capybara/queries/selector_query.rb +675 -81
- data/lib/capybara/queries/sibling_query.rb +26 -0
- data/lib/capybara/queries/style_query.rb +45 -0
- data/lib/capybara/queries/text_query.rb +88 -20
- data/lib/capybara/queries/title_query.rb +9 -11
- data/lib/capybara/rack_test/browser.rb +63 -39
- data/lib/capybara/rack_test/css_handlers.rb +6 -4
- data/lib/capybara/rack_test/driver.rb +26 -16
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +73 -58
- data/lib/capybara/rack_test/node.rb +187 -67
- data/lib/capybara/rails.rb +4 -8
- data/lib/capybara/registration_container.rb +44 -0
- data/lib/capybara/registrations/drivers.rb +42 -0
- data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
- data/lib/capybara/registrations/servers.rb +45 -0
- data/lib/capybara/result.rb +142 -14
- data/lib/capybara/rspec/features.rb +17 -42
- data/lib/capybara/rspec/matcher_proxies.rb +82 -0
- data/lib/capybara/rspec/matchers/base.rb +111 -0
- data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
- data/lib/capybara/rspec/matchers/compound.rb +88 -0
- data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
- data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
- data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
- data/lib/capybara/rspec/matchers/have_selector.rb +77 -0
- data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
- data/lib/capybara/rspec/matchers/have_text.rb +33 -0
- data/lib/capybara/rspec/matchers/have_title.rb +29 -0
- data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
- data/lib/capybara/rspec/matchers/match_style.rb +43 -0
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
- data/lib/capybara/rspec/matchers.rb +143 -244
- data/lib/capybara/rspec.rb +10 -12
- data/lib/capybara/selector/builders/css_builder.rb +84 -0
- data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
- data/lib/capybara/selector/css.rb +102 -0
- data/lib/capybara/selector/definition/button.rb +63 -0
- data/lib/capybara/selector/definition/checkbox.rb +26 -0
- data/lib/capybara/selector/definition/css.rb +10 -0
- data/lib/capybara/selector/definition/datalist_input.rb +35 -0
- data/lib/capybara/selector/definition/datalist_option.rb +25 -0
- data/lib/capybara/selector/definition/element.rb +28 -0
- data/lib/capybara/selector/definition/field.rb +40 -0
- data/lib/capybara/selector/definition/fieldset.rb +14 -0
- data/lib/capybara/selector/definition/file_field.rb +13 -0
- data/lib/capybara/selector/definition/fillable_field.rb +33 -0
- data/lib/capybara/selector/definition/frame.rb +17 -0
- data/lib/capybara/selector/definition/id.rb +6 -0
- data/lib/capybara/selector/definition/label.rb +62 -0
- data/lib/capybara/selector/definition/link.rb +54 -0
- data/lib/capybara/selector/definition/link_or_button.rb +16 -0
- data/lib/capybara/selector/definition/option.rb +27 -0
- data/lib/capybara/selector/definition/radio_button.rb +27 -0
- data/lib/capybara/selector/definition/select.rb +81 -0
- data/lib/capybara/selector/definition/table.rb +109 -0
- data/lib/capybara/selector/definition/table_row.rb +21 -0
- data/lib/capybara/selector/definition/xpath.rb +5 -0
- data/lib/capybara/selector/definition.rb +278 -0
- data/lib/capybara/selector/filter.rb +3 -46
- data/lib/capybara/selector/filter_set.rb +124 -0
- data/lib/capybara/selector/filters/base.rb +77 -0
- data/lib/capybara/selector/filters/expression_filter.rb +22 -0
- data/lib/capybara/selector/filters/locator_filter.rb +29 -0
- data/lib/capybara/selector/filters/node_filter.rb +31 -0
- data/lib/capybara/selector/regexp_disassembler.rb +214 -0
- data/lib/capybara/selector/selector.rb +155 -0
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +232 -369
- data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
- data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
- data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
- data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
- data/lib/capybara/selenium/driver.rb +380 -142
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +124 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +89 -0
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
- data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
- data/lib/capybara/selenium/extensions/find.rb +110 -0
- data/lib/capybara/selenium/extensions/html5_drag.rb +228 -0
- data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
- data/lib/capybara/selenium/extensions/scroll.rb +76 -0
- data/lib/capybara/selenium/logger_suppressor.rb +40 -0
- data/lib/capybara/selenium/node.rb +528 -97
- data/lib/capybara/selenium/nodes/chrome_node.rb +137 -0
- data/lib/capybara/selenium/nodes/edge_node.rb +104 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +136 -0
- data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
- data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
- data/lib/capybara/selenium/patches/action_pauser.rb +26 -0
- data/lib/capybara/selenium/patches/atoms.rb +18 -0
- data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
- data/lib/capybara/selenium/patches/logs.rb +45 -0
- data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
- data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
- data/lib/capybara/server/animation_disabler.rb +63 -0
- data/lib/capybara/server/checker.rb +44 -0
- data/lib/capybara/server/middleware.rb +71 -0
- data/lib/capybara/server.rb +74 -71
- data/lib/capybara/session/config.rb +126 -0
- data/lib/capybara/session/matchers.rb +44 -27
- data/lib/capybara/session.rb +500 -297
- data/lib/capybara/spec/fixtures/no_extension +1 -0
- data/lib/capybara/spec/public/jquery.js +5 -5
- data/lib/capybara/spec/public/offset.js +6 -0
- data/lib/capybara/spec/public/test.js +168 -14
- data/lib/capybara/spec/session/accept_alert_spec.rb +37 -14
- data/lib/capybara/spec/session/accept_confirm_spec.rb +7 -6
- data/lib/capybara/spec/session/accept_prompt_spec.rb +38 -10
- data/lib/capybara/spec/session/all_spec.rb +179 -59
- data/lib/capybara/spec/session/ancestor_spec.rb +88 -0
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +140 -0
- data/lib/capybara/spec/session/assert_current_path_spec.rb +75 -0
- data/lib/capybara/spec/session/assert_selector_spec.rb +143 -0
- data/lib/capybara/spec/session/assert_style_spec.rb +26 -0
- data/lib/capybara/spec/session/assert_text_spec.rb +258 -0
- data/lib/capybara/spec/session/assert_title_spec.rb +93 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +154 -48
- data/lib/capybara/spec/session/body_spec.rb +12 -13
- data/lib/capybara/spec/session/check_spec.rb +168 -41
- data/lib/capybara/spec/session/choose_spec.rb +75 -23
- data/lib/capybara/spec/session/click_button_spec.rb +243 -175
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +57 -32
- data/lib/capybara/spec/session/click_link_spec.rb +100 -53
- data/lib/capybara/spec/session/current_scope_spec.rb +11 -10
- data/lib/capybara/spec/session/current_url_spec.rb +61 -35
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +7 -7
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +5 -4
- data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +13 -6
- data/lib/capybara/spec/session/element/match_css_spec.rb +21 -7
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +9 -7
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +91 -34
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +23 -0
- data/lib/capybara/spec/session/evaluate_script_spec.rb +45 -3
- data/lib/capybara/spec/session/execute_script_spec.rb +24 -4
- data/lib/capybara/spec/session/fill_in_spec.rb +166 -64
- data/lib/capybara/spec/session/find_button_spec.rb +37 -18
- data/lib/capybara/spec/session/find_by_id_spec.rb +10 -9
- data/lib/capybara/spec/session/find_field_spec.rb +57 -34
- data/lib/capybara/spec/session/find_link_spec.rb +47 -10
- data/lib/capybara/spec/session/find_spec.rb +290 -144
- data/lib/capybara/spec/session/first_spec.rb +91 -48
- data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +116 -0
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +112 -0
- data/lib/capybara/spec/session/go_back_spec.rb +3 -2
- data/lib/capybara/spec/session/go_forward_spec.rb +3 -2
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
- data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +25 -0
- data/lib/capybara/spec/session/has_button_spec.rb +76 -19
- data/lib/capybara/spec/session/has_css_spec.rb +277 -131
- data/lib/capybara/spec/session/has_current_path_spec.rb +98 -26
- data/lib/capybara/spec/session/has_field_spec.rb +177 -107
- data/lib/capybara/spec/session/has_link_spec.rb +13 -12
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +78 -0
- data/lib/capybara/spec/session/has_select_spec.rb +191 -95
- data/lib/capybara/spec/session/has_selector_spec.rb +128 -64
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +172 -5
- data/lib/capybara/spec/session/has_text_spec.rb +126 -60
- data/lib/capybara/spec/session/has_title_spec.rb +35 -12
- data/lib/capybara/spec/session/has_xpath_spec.rb +74 -53
- data/lib/capybara/spec/session/{headers.rb → headers_spec.rb} +3 -2
- data/lib/capybara/spec/session/html_spec.rb +14 -6
- data/lib/capybara/spec/session/matches_style_spec.rb +35 -0
- data/lib/capybara/spec/session/node_spec.rb +1028 -131
- data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
- data/lib/capybara/spec/session/refresh_spec.rb +34 -0
- data/lib/capybara/spec/session/reset_session_spec.rb +75 -34
- data/lib/capybara/spec/session/{response_code.rb → response_code_spec.rb} +2 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +3 -2
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +11 -15
- data/lib/capybara/spec/session/save_page_spec.rb +42 -55
- data/lib/capybara/spec/session/save_screenshot_spec.rb +16 -14
- data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/scroll_spec.rb +117 -0
- data/lib/capybara/spec/session/select_spec.rb +112 -85
- data/lib/capybara/spec/session/selectors_spec.rb +71 -8
- data/lib/capybara/spec/session/sibling_spec.rb +52 -0
- data/lib/capybara/spec/session/text_spec.rb +38 -23
- data/lib/capybara/spec/session/title_spec.rb +17 -5
- data/lib/capybara/spec/session/uncheck_spec.rb +71 -12
- data/lib/capybara/spec/session/unselect_spec.rb +44 -43
- data/lib/capybara/spec/session/visit_spec.rb +99 -32
- data/lib/capybara/spec/session/window/become_closed_spec.rb +33 -29
- data/lib/capybara/spec/session/window/current_window_spec.rb +5 -3
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +5 -3
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +39 -30
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +17 -10
- data/lib/capybara/spec/session/window/window_spec.rb +121 -73
- data/lib/capybara/spec/session/window/windows_spec.rb +12 -10
- data/lib/capybara/spec/session/window/within_window_spec.rb +52 -82
- data/lib/capybara/spec/session/within_spec.rb +76 -43
- data/lib/capybara/spec/spec_helper.rb +67 -33
- data/lib/capybara/spec/test_app.rb +85 -36
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/buttons.erb +1 -1
- data/lib/capybara/spec/views/fieldsets.erb +1 -1
- data/lib/capybara/spec/views/form.erb +227 -20
- data/lib/capybara/spec/views/frame_child.erb +10 -2
- data/lib/capybara/spec/views/frame_one.erb +2 -1
- data/lib/capybara/spec/views/frame_parent.erb +2 -2
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/header_links.erb +1 -1
- data/lib/capybara/spec/views/host_links.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +47 -0
- data/lib/capybara/spec/views/offset.erb +32 -0
- data/lib/capybara/spec/views/path.erb +1 -1
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/postback.erb +1 -1
- data/lib/capybara/spec/views/react.erb +45 -0
- data/lib/capybara/spec/views/scroll.erb +20 -0
- data/lib/capybara/spec/views/spatial.erb +31 -0
- data/lib/capybara/spec/views/tables.erb +69 -2
- data/lib/capybara/spec/views/with_animation.erb +82 -0
- data/lib/capybara/spec/views/with_base_tag.erb +1 -1
- data/lib/capybara/spec/views/with_count.erb +1 -1
- data/lib/capybara/spec/views/with_dragula.erb +24 -0
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
- data/lib/capybara/spec/views/with_hover.erb +7 -1
- data/lib/capybara/spec/views/with_hover1.erb +10 -0
- data/lib/capybara/spec/views/with_html.erb +100 -10
- data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
- data/lib/capybara/spec/views/with_html_entities.erb +1 -1
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +49 -3
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_namespace.erb +20 -0
- data/lib/capybara/spec/views/with_scope.erb +1 -1
- data/lib/capybara/spec/views/with_scope_other.erb +6 -0
- data/lib/capybara/spec/views/with_simple_html.erb +1 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
- data/lib/capybara/spec/views/with_title.erb +1 -1
- data/lib/capybara/spec/views/with_unload_alert.erb +3 -1
- data/lib/capybara/spec/views/with_windows.erb +7 -1
- data/lib/capybara/spec/views/within_frames.erb +6 -3
- data/lib/capybara/version.rb +2 -1
- data/lib/capybara/window.rb +39 -21
- data/lib/capybara.rb +208 -186
- data/spec/basic_node_spec.rb +52 -39
- data/spec/capybara_spec.rb +72 -50
- data/spec/css_builder_spec.rb +101 -0
- data/spec/css_splitter_spec.rb +38 -0
- data/spec/dsl_spec.rb +81 -61
- data/spec/filter_set_spec.rb +46 -0
- data/spec/fixtures/capybara.csv +1 -0
- data/spec/fixtures/certificate.pem +25 -0
- data/spec/fixtures/key.pem +27 -0
- data/spec/fixtures/selenium_driver_rspec_failure.rb +7 -3
- data/spec/fixtures/selenium_driver_rspec_success.rb +7 -3
- data/spec/minitest_spec.rb +164 -0
- data/spec/minitest_spec_spec.rb +162 -0
- data/spec/per_session_config_spec.rb +68 -0
- data/spec/rack_test_spec.rb +189 -96
- data/spec/regexp_dissassembler_spec.rb +250 -0
- data/spec/result_spec.rb +143 -13
- data/spec/rspec/features_spec.rb +38 -32
- data/spec/rspec/scenarios_spec.rb +9 -7
- data/spec/rspec/shared_spec_matchers.rb +959 -0
- data/spec/rspec/views_spec.rb +9 -3
- data/spec/rspec_matchers_spec.rb +62 -0
- data/spec/rspec_spec.rb +127 -30
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +458 -37
- data/spec/selenium_spec_chrome.rb +196 -9
- data/spec/selenium_spec_chrome_remote.rb +100 -0
- data/spec/selenium_spec_edge.rb +47 -0
- data/spec/selenium_spec_firefox.rb +210 -0
- data/spec/selenium_spec_firefox_remote.rb +80 -0
- data/spec/selenium_spec_ie.rb +150 -0
- data/spec/selenium_spec_safari.rb +148 -0
- data/spec/server_spec.rb +200 -101
- data/spec/session_spec.rb +91 -0
- data/spec/shared_selenium_node.rb +83 -0
- data/spec/shared_selenium_session.rb +558 -0
- data/spec/spec_helper.rb +94 -2
- data/spec/xpath_builder_spec.rb +93 -0
- metadata +420 -60
- data/lib/capybara/query.rb +0 -7
- data/lib/capybara/spec/session/assert_current_path.rb +0 -60
- data/lib/capybara/spec/session/assert_selector.rb +0 -148
- data/lib/capybara/spec/session/assert_text.rb +0 -196
- data/lib/capybara/spec/session/assert_title.rb +0 -70
- data/lib/capybara/spec/session/source_spec.rb +0 -0
- data/lib/capybara/spec/session/within_frame_spec.rb +0 -53
- data/spec/rspec/matchers_spec.rb +0 -827
- data/spec/selenium_spec.rb +0 -151
data/License.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
# Capybara
|
|
2
2
|
|
|
3
|
-
[](https://travis-ci.org/teamcapybara/capybara)
|
|
4
|
+
[](https://ci.appveyor.com/api/projects/github/teamcapybara/capybara)
|
|
5
|
+
[](https://codeclimate.com/github/teamcapybara/capybara)
|
|
6
|
+
[](https://coveralls.io/github/teamcapybara/capybara?branch=master)
|
|
7
|
+
[](https://gitter.im/jnicklas/capybara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
8
|
+
[](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.
|