capybara 3.13.2 → 3.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/History.md +587 -16
- data/README.md +240 -90
- data/lib/capybara/config.rb +24 -11
- data/lib/capybara/cucumber.rb +1 -1
- data/lib/capybara/driver/base.rb +8 -0
- data/lib/capybara/driver/node.rb +20 -4
- data/lib/capybara/dsl.rb +5 -3
- data/lib/capybara/helpers.rb +25 -4
- data/lib/capybara/minitest/spec.rb +174 -90
- data/lib/capybara/minitest.rb +256 -142
- data/lib/capybara/node/actions.rb +123 -77
- data/lib/capybara/node/base.rb +20 -12
- data/lib/capybara/node/document.rb +2 -2
- data/lib/capybara/node/document_matchers.rb +3 -3
- data/lib/capybara/node/element.rb +223 -117
- data/lib/capybara/node/finders.rb +81 -71
- data/lib/capybara/node/matchers.rb +271 -134
- data/lib/capybara/node/simple.rb +18 -5
- data/lib/capybara/node/whitespace_normalizer.rb +81 -0
- data/lib/capybara/queries/active_element_query.rb +18 -0
- data/lib/capybara/queries/ancestor_query.rb +8 -9
- data/lib/capybara/queries/base_query.rb +3 -2
- data/lib/capybara/queries/current_path_query.rb +15 -5
- data/lib/capybara/queries/selector_query.rb +364 -54
- data/lib/capybara/queries/sibling_query.rb +8 -6
- data/lib/capybara/queries/style_query.rb +2 -2
- data/lib/capybara/queries/text_query.rb +13 -1
- data/lib/capybara/queries/title_query.rb +1 -1
- data/lib/capybara/rack_test/browser.rb +76 -11
- data/lib/capybara/rack_test/driver.rb +10 -5
- data/lib/capybara/rack_test/errors.rb +6 -0
- data/lib/capybara/rack_test/form.rb +31 -9
- data/lib/capybara/rack_test/node.rb +74 -23
- data/lib/capybara/registration_container.rb +41 -0
- data/lib/capybara/registrations/drivers.rb +42 -0
- data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
- data/lib/capybara/registrations/servers.rb +66 -0
- data/lib/capybara/result.rb +44 -20
- data/lib/capybara/rspec/matcher_proxies.rb +13 -11
- data/lib/capybara/rspec/matchers/base.rb +31 -16
- data/lib/capybara/rspec/matchers/compound.rb +1 -1
- 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 +2 -2
- data/lib/capybara/rspec/matchers/have_selector.rb +21 -21
- data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
- data/lib/capybara/rspec/matchers/have_text.rb +4 -4
- data/lib/capybara/rspec/matchers/have_title.rb +2 -2
- data/lib/capybara/rspec/matchers/match_selector.rb +3 -3
- data/lib/capybara/rspec/matchers/match_style.rb +7 -2
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
- data/lib/capybara/rspec/matchers.rb +111 -68
- data/lib/capybara/rspec.rb +2 -0
- data/lib/capybara/selector/builders/css_builder.rb +11 -7
- data/lib/capybara/selector/builders/xpath_builder.rb +5 -3
- data/lib/capybara/selector/css.rb +11 -9
- data/lib/capybara/selector/definition/button.rb +68 -0
- data/lib/capybara/selector/definition/checkbox.rb +26 -0
- data/lib/capybara/selector/definition/css.rb +10 -0
- data/lib/capybara/selector/definition/datalist_input.rb +35 -0
- data/lib/capybara/selector/definition/datalist_option.rb +25 -0
- data/lib/capybara/selector/definition/element.rb +28 -0
- data/lib/capybara/selector/definition/field.rb +40 -0
- data/lib/capybara/selector/definition/fieldset.rb +14 -0
- data/lib/capybara/selector/definition/file_field.rb +13 -0
- data/lib/capybara/selector/definition/fillable_field.rb +33 -0
- data/lib/capybara/selector/definition/frame.rb +17 -0
- data/lib/capybara/selector/definition/id.rb +6 -0
- data/lib/capybara/selector/definition/label.rb +62 -0
- data/lib/capybara/selector/definition/link.rb +55 -0
- data/lib/capybara/selector/definition/link_or_button.rb +16 -0
- data/lib/capybara/selector/definition/option.rb +27 -0
- data/lib/capybara/selector/definition/radio_button.rb +27 -0
- data/lib/capybara/selector/definition/select.rb +81 -0
- data/lib/capybara/selector/definition/table.rb +109 -0
- data/lib/capybara/selector/definition/table_row.rb +21 -0
- data/lib/capybara/selector/definition/xpath.rb +5 -0
- data/lib/capybara/selector/definition.rb +280 -0
- data/lib/capybara/selector/filter_set.rb +19 -18
- data/lib/capybara/selector/filters/base.rb +11 -2
- data/lib/capybara/selector/filters/locator_filter.rb +13 -3
- data/lib/capybara/selector/regexp_disassembler.rb +11 -7
- data/lib/capybara/selector/selector.rb +50 -440
- data/lib/capybara/selector/xpath_extensions.rb +17 -0
- data/lib/capybara/selector.rb +473 -482
- 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 +174 -62
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +74 -18
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +37 -3
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +14 -1
- 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 +68 -45
- data/lib/capybara/selenium/extensions/html5_drag.rb +192 -22
- data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
- data/lib/capybara/selenium/extensions/scroll.rb +8 -10
- data/lib/capybara/selenium/node.rb +268 -72
- data/lib/capybara/selenium/nodes/chrome_node.rb +105 -9
- data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
- data/lib/capybara/selenium/nodes/firefox_node.rb +51 -61
- data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
- data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
- data/lib/capybara/selenium/patches/atoms.rb +18 -0
- data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
- data/lib/capybara/selenium/patches/logs.rb +45 -0
- data/lib/capybara/selenium/patches/pause_duration_fix.rb +1 -1
- data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
- data/lib/capybara/server/animation_disabler.rb +43 -21
- data/lib/capybara/server/checker.rb +6 -2
- data/lib/capybara/server/middleware.rb +25 -13
- data/lib/capybara/server.rb +20 -4
- data/lib/capybara/session/config.rb +15 -11
- data/lib/capybara/session/matchers.rb +11 -11
- data/lib/capybara/session.rb +162 -131
- data/lib/capybara/spec/public/offset.js +6 -0
- data/lib/capybara/spec/public/test.js +105 -6
- data/lib/capybara/spec/session/accept_alert_spec.rb +1 -1
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +89 -15
- data/lib/capybara/spec/session/ancestor_spec.rb +5 -0
- data/lib/capybara/spec/session/assert_current_path_spec.rb +5 -2
- data/lib/capybara/spec/session/assert_text_spec.rb +26 -22
- data/lib/capybara/spec/session/attach_file_spec.rb +64 -31
- data/lib/capybara/spec/session/check_spec.rb +26 -4
- data/lib/capybara/spec/session/choose_spec.rb +14 -2
- data/lib/capybara/spec/session/click_button_spec.rb +109 -61
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +9 -0
- data/lib/capybara/spec/session/click_link_spec.rb +23 -1
- data/lib/capybara/spec/session/current_scope_spec.rb +1 -1
- data/lib/capybara/spec/session/current_url_spec.rb +11 -1
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +40 -39
- data/lib/capybara/spec/session/evaluate_script_spec.rb +12 -0
- data/lib/capybara/spec/session/fill_in_spec.rb +46 -5
- data/lib/capybara/spec/session/find_link_spec.rb +10 -0
- data/lib/capybara/spec/session/find_spec.rb +80 -7
- data/lib/capybara/spec/session/first_spec.rb +2 -2
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +14 -1
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +14 -1
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +5 -5
- data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +6 -2
- data/lib/capybara/spec/session/has_button_spec.rb +81 -0
- data/lib/capybara/spec/session/has_css_spec.rb +45 -8
- data/lib/capybara/spec/session/has_current_path_spec.rb +22 -7
- data/lib/capybara/spec/session/has_element_spec.rb +47 -0
- data/lib/capybara/spec/session/has_field_spec.rb +59 -1
- data/lib/capybara/spec/session/has_link_spec.rb +40 -0
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +7 -7
- data/lib/capybara/spec/session/has_select_spec.rb +42 -8
- data/lib/capybara/spec/session/has_selector_spec.rb +19 -4
- data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
- data/lib/capybara/spec/session/has_table_spec.rb +177 -0
- data/lib/capybara/spec/session/has_text_spec.rb +31 -3
- data/lib/capybara/spec/session/html_spec.rb +1 -1
- data/lib/capybara/spec/session/matches_style_spec.rb +6 -4
- data/lib/capybara/spec/session/node_spec.rb +697 -23
- data/lib/capybara/spec/session/node_wrapper_spec.rb +1 -1
- data/lib/capybara/spec/session/refresh_spec.rb +2 -1
- data/lib/capybara/spec/session/reset_session_spec.rb +21 -7
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
- data/lib/capybara/spec/session/save_page_spec.rb +4 -4
- data/lib/capybara/spec/session/save_screenshot_spec.rb +4 -4
- data/lib/capybara/spec/session/scroll_spec.rb +9 -7
- data/lib/capybara/spec/session/select_spec.rb +5 -10
- data/lib/capybara/spec/session/selectors_spec.rb +24 -3
- data/lib/capybara/spec/session/uncheck_spec.rb +3 -3
- data/lib/capybara/spec/session/unselect_spec.rb +1 -1
- data/lib/capybara/spec/session/visit_spec.rb +20 -0
- data/lib/capybara/spec/session/window/become_closed_spec.rb +20 -17
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +1 -1
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +1 -1
- data/lib/capybara/spec/session/window/window_spec.rb +54 -57
- data/lib/capybara/spec/session/window/windows_spec.rb +2 -2
- data/lib/capybara/spec/session/within_spec.rb +36 -0
- data/lib/capybara/spec/spec_helper.rb +30 -19
- data/lib/capybara/spec/test_app.rb +122 -34
- data/lib/capybara/spec/views/animated.erb +49 -0
- data/lib/capybara/spec/views/form.erb +86 -8
- data/lib/capybara/spec/views/frame_child.erb +3 -2
- data/lib/capybara/spec/views/frame_one.erb +2 -1
- data/lib/capybara/spec/views/frame_parent.erb +1 -1
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +2 -1
- data/lib/capybara/spec/views/layout.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +10 -10
- data/lib/capybara/spec/views/offset.erb +33 -0
- data/lib/capybara/spec/views/path.erb +2 -2
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/react.erb +45 -0
- data/lib/capybara/spec/views/scroll.erb +2 -1
- data/lib/capybara/spec/views/spatial.erb +31 -0
- data/lib/capybara/spec/views/tables.erb +67 -0
- data/lib/capybara/spec/views/with_animation.erb +39 -4
- data/lib/capybara/spec/views/with_base_tag.erb +2 -2
- data/lib/capybara/spec/views/with_dragula.erb +24 -0
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
- data/lib/capybara/spec/views/with_hover.erb +3 -2
- data/lib/capybara/spec/views/with_hover1.erb +10 -0
- data/lib/capybara/spec/views/with_html.erb +34 -6
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +7 -4
- data/lib/capybara/spec/views/with_jstree.erb +26 -0
- data/lib/capybara/spec/views/with_namespace.erb +1 -0
- data/lib/capybara/spec/views/with_scope.erb +2 -2
- data/lib/capybara/spec/views/with_scope_other.erb +6 -0
- data/lib/capybara/spec/views/with_shadow.erb +31 -0
- data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
- data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
- data/lib/capybara/spec/views/with_windows.erb +1 -1
- data/lib/capybara/spec/views/within_frames.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +14 -18
- data/lib/capybara.rb +91 -126
- data/spec/basic_node_spec.rb +30 -16
- data/spec/capybara_spec.rb +40 -28
- data/spec/counter_spec.rb +35 -0
- data/spec/css_builder_spec.rb +3 -1
- data/spec/css_splitter_spec.rb +1 -1
- data/spec/dsl_spec.rb +33 -22
- data/spec/filter_set_spec.rb +5 -5
- data/spec/fixtures/selenium_driver_rspec_failure.rb +3 -3
- data/spec/fixtures/selenium_driver_rspec_success.rb +3 -3
- data/spec/minitest_spec.rb +24 -2
- data/spec/minitest_spec_spec.rb +60 -45
- data/spec/per_session_config_spec.rb +1 -1
- data/spec/rack_test_spec.rb +131 -98
- data/spec/regexp_dissassembler_spec.rb +53 -39
- data/spec/result_spec.rb +68 -66
- data/spec/rspec/features_spec.rb +9 -4
- data/spec/rspec/scenarios_spec.rb +6 -2
- data/spec/rspec/shared_spec_matchers.rb +137 -98
- data/spec/rspec_matchers_spec.rb +25 -0
- data/spec/rspec_spec.rb +23 -21
- data/spec/sauce_spec_chrome.rb +43 -0
- data/spec/selector_spec.rb +77 -21
- data/spec/selenium_spec_chrome.rb +141 -39
- data/spec/selenium_spec_chrome_remote.rb +32 -17
- data/spec/selenium_spec_edge.rb +36 -8
- data/spec/selenium_spec_firefox.rb +110 -68
- data/spec/selenium_spec_firefox_remote.rb +22 -15
- data/spec/selenium_spec_ie.rb +29 -22
- data/spec/selenium_spec_safari.rb +162 -0
- data/spec/server_spec.rb +153 -81
- data/spec/session_spec.rb +11 -4
- data/spec/shared_selenium_node.rb +79 -0
- data/spec/shared_selenium_session.rb +179 -74
- data/spec/spec_helper.rb +80 -5
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +3 -1
- metadata +218 -30
- data/lib/capybara/spec/session/source_spec.rb +0 -0
- data/lib/capybara/spec/views/with_title.erb +0 -5
data/README.md
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
# Capybara
|
|
2
2
|
|
|
3
|
-
[](https://ci.appveyor.com/api/projects/github/teamcapybara/capybara)
|
|
3
|
+
[](https://github.com/teamcapybara/capybara/actions/workflows/build.yml)
|
|
5
4
|
[](https://codeclimate.com/github/teamcapybara/capybara)
|
|
6
|
-
[](https://dependabot.com/compatibility-score.html?dependency-name=capybara&package-manager=bundler&version-scheme=semver)
|
|
8
|
-
|
|
9
|
-
**Note** You are viewing the README for the version 3.13.x of Capybara.
|
|
5
|
+
[](https://coveralls.io/github/teamcapybara/capybara?branch=master)
|
|
10
6
|
|
|
11
7
|
Capybara helps you test web applications by simulating how a real user would
|
|
12
8
|
interact with your app. It is agnostic about the driver running your tests and
|
|
@@ -19,8 +15,7 @@ If you and/or your company find value in Capybara and would like to contribute f
|
|
|
19
15
|
<a href="https://www.patreon.com/capybara">Patreon</a>
|
|
20
16
|
|
|
21
17
|
|
|
22
|
-
**Need help?** Ask on the
|
|
23
|
-
GitHub): http://groups.google.com/group/ruby-capybara
|
|
18
|
+
**Need help?** Ask on the discussions (please do not open an issue): https://github.com/orgs/teamcapybara/discussions/categories/q-a
|
|
24
19
|
|
|
25
20
|
## Table of contents
|
|
26
21
|
|
|
@@ -35,9 +30,6 @@ GitHub): http://groups.google.com/group/ruby-capybara
|
|
|
35
30
|
- [Selecting the Driver](#selecting-the-driver)
|
|
36
31
|
- [RackTest](#racktest)
|
|
37
32
|
- [Selenium](#selenium)
|
|
38
|
-
- [Apparition](#apparition)
|
|
39
|
-
- [Capybara-webkit](#capybara-webkit)
|
|
40
|
-
- [Poltergeist](#poltergeist)
|
|
41
33
|
- [The DSL](#the-dsl)
|
|
42
34
|
- [Navigating](#navigating)
|
|
43
35
|
- [Clicking links and buttons](#clicking-links-and-buttons)
|
|
@@ -49,6 +41,10 @@ GitHub): http://groups.google.com/group/ruby-capybara
|
|
|
49
41
|
- [Scripting](#scripting)
|
|
50
42
|
- [Modals](#modals)
|
|
51
43
|
- [Debugging](#debugging)
|
|
44
|
+
- [Selectors](#selectors)
|
|
45
|
+
- [Name](#selectors-name)
|
|
46
|
+
- [Locator](#selectors-locator)
|
|
47
|
+
- [Filters](#selectors-filters)
|
|
52
48
|
- [Matching](#matching)
|
|
53
49
|
- [Exactness](#exactness)
|
|
54
50
|
- [Strategy](#strategy)
|
|
@@ -57,11 +53,13 @@ GitHub): http://groups.google.com/group/ruby-capybara
|
|
|
57
53
|
- [Using the DSL elsewhere](#using-the-dsl-elsewhere)
|
|
58
54
|
- [Calling remote servers](#calling-remote-servers)
|
|
59
55
|
- [Using sessions](#using-sessions)
|
|
56
|
+
- [Named sessions](#named-sessions)
|
|
57
|
+
- [Using sessions manually](#using-sessions-manually)
|
|
60
58
|
- [XPath, CSS and selectors](#xpath-css-and-selectors)
|
|
61
59
|
- [Beware the XPath // trap](#beware-the-xpath--trap)
|
|
62
60
|
- [Configuring and adding drivers](#configuring-and-adding-drivers)
|
|
63
61
|
- [Gotchas:](#gotchas)
|
|
64
|
-
- ["Threadsafe" mode](#threadsafe)
|
|
62
|
+
- ["Threadsafe" mode](#threadsafe-mode)
|
|
65
63
|
- [Development](#development)
|
|
66
64
|
|
|
67
65
|
## <a name="key-benefits"></a>Key benefits
|
|
@@ -75,7 +73,7 @@ GitHub): http://groups.google.com/group/ruby-capybara
|
|
|
75
73
|
|
|
76
74
|
## <a name="setup"></a>Setup
|
|
77
75
|
|
|
78
|
-
Capybara requires Ruby
|
|
76
|
+
Capybara requires Ruby 3.0.0 or later. To install, add this line to your
|
|
79
77
|
`Gemfile` and run `bundle install`:
|
|
80
78
|
|
|
81
79
|
```ruby
|
|
@@ -146,11 +144,13 @@ Load RSpec 3.5+ support by adding the following line (typically to your
|
|
|
146
144
|
require 'capybara/rspec'
|
|
147
145
|
```
|
|
148
146
|
|
|
149
|
-
If you are using Rails, put your Capybara specs in `spec/features` or `spec/system` (only works
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
147
|
+
If you are using Rails, put your Capybara specs in `spec/features` or `spec/system` (only works if
|
|
148
|
+
[you have it configured in RSpec](https://rspec.info/features/6-0/rspec-rails/directory-structure/))
|
|
149
|
+
and if you have your Capybara specs in a different directory, then tag the example groups with
|
|
150
|
+
`type: :feature` or `type: :system` depending on which type of test you're writing.
|
|
151
|
+
|
|
152
|
+
If you are using Rails system specs please see [their documentation](https://rspec.info/features/6-0/rspec-rails/system-specs/system-specs)
|
|
153
|
+
for selecting the driver you wish to use.
|
|
154
154
|
|
|
155
155
|
If you are not using Rails, tag all the example groups in which you want to use
|
|
156
156
|
Capybara with `type: :feature`.
|
|
@@ -160,7 +160,7 @@ You can now write your specs like so:
|
|
|
160
160
|
```ruby
|
|
161
161
|
describe "the signin process", type: :feature do
|
|
162
162
|
before :each do
|
|
163
|
-
User.
|
|
163
|
+
User.create(email: 'user@example.com', password: 'password')
|
|
164
164
|
end
|
|
165
165
|
|
|
166
166
|
it "signs me in" do
|
|
@@ -182,7 +182,7 @@ to one specific driver. For example:
|
|
|
182
182
|
```ruby
|
|
183
183
|
describe 'some stuff which requires js', js: true do
|
|
184
184
|
it 'will use the default js driver'
|
|
185
|
-
it 'will switch to one specific driver', driver: :
|
|
185
|
+
it 'will switch to one specific driver', driver: :selenium
|
|
186
186
|
end
|
|
187
187
|
```
|
|
188
188
|
|
|
@@ -191,7 +191,7 @@ Capybara also comes with a built in DSL for creating descriptive acceptance test
|
|
|
191
191
|
```ruby
|
|
192
192
|
feature "Signing in" do
|
|
193
193
|
background do
|
|
194
|
-
User.
|
|
194
|
+
User.create(email: 'user@example.com', password: 'caplin')
|
|
195
195
|
end
|
|
196
196
|
|
|
197
197
|
scenario "Signing in with correct credentials" do
|
|
@@ -204,7 +204,7 @@ feature "Signing in" do
|
|
|
204
204
|
expect(page).to have_content 'Success'
|
|
205
205
|
end
|
|
206
206
|
|
|
207
|
-
given(:other_user) { User.
|
|
207
|
+
given(:other_user) { User.create(email: 'other@example.com', password: 'rous') }
|
|
208
208
|
|
|
209
209
|
scenario "Signing in as another user" do
|
|
210
210
|
visit '/sessions/new'
|
|
@@ -259,7 +259,9 @@ end
|
|
|
259
259
|
|
|
260
260
|
## <a name="using-capybara-with-minitest"></a>Using Capybara with Minitest
|
|
261
261
|
|
|
262
|
-
* If you are using Rails
|
|
262
|
+
* If you are using Rails system tests please see their documentation for information on selecting the driver you wish to use.
|
|
263
|
+
|
|
264
|
+
* If you are using Rails, but not using Rails system tests, add the following code in your `test_helper.rb`
|
|
263
265
|
file to make Capybara available in all test cases deriving from
|
|
264
266
|
`ActionDispatch::IntegrationTest`:
|
|
265
267
|
|
|
@@ -274,8 +276,7 @@ end
|
|
|
274
276
|
include Capybara::Minitest::Assertions
|
|
275
277
|
|
|
276
278
|
# Reset sessions and driver between tests
|
|
277
|
-
|
|
278
|
-
def teardown
|
|
279
|
+
teardown do
|
|
279
280
|
Capybara.reset_sessions!
|
|
280
281
|
Capybara.use_default_driver
|
|
281
282
|
end
|
|
@@ -334,15 +335,15 @@ By default, Capybara uses the `:rack_test` driver, which is fast but limited: it
|
|
|
334
335
|
does not support JavaScript, nor is it able to access HTTP resources outside of
|
|
335
336
|
your Rack application, such as remote APIs and OAuth services. To get around
|
|
336
337
|
these limitations, you can set up a different default driver for your features.
|
|
337
|
-
For example if you'd prefer to run everything in Selenium, you could do:
|
|
338
|
+
For example, if you'd prefer to run everything in Selenium, you could do:
|
|
338
339
|
|
|
339
340
|
```ruby
|
|
340
341
|
Capybara.default_driver = :selenium # :selenium_chrome and :selenium_chrome_headless are also registered
|
|
341
342
|
```
|
|
342
343
|
|
|
343
|
-
However, if you are using RSpec or Cucumber
|
|
344
|
-
leaving the faster `:rack_test` as the __default_driver__, and
|
|
345
|
-
tests that require a JavaScript-capable driver using `js: true` or
|
|
344
|
+
However, if you are using RSpec or Cucumber (and your app runs correctly without JS),
|
|
345
|
+
you may instead want to consider leaving the faster `:rack_test` as the __default_driver__, and
|
|
346
|
+
marking only those tests that require a JavaScript-capable driver using `js: true` or
|
|
346
347
|
`@javascript`, respectively. By default, JavaScript tests are run using the
|
|
347
348
|
`:selenium` driver. You can change this by setting
|
|
348
349
|
`Capybara.javascript_driver`.
|
|
@@ -351,7 +352,7 @@ You can also change the driver temporarily (typically in the Before/setup and
|
|
|
351
352
|
After/teardown blocks):
|
|
352
353
|
|
|
353
354
|
```ruby
|
|
354
|
-
Capybara.current_driver = :
|
|
355
|
+
Capybara.current_driver = :selenium # temporarily select different driver
|
|
355
356
|
# tests here
|
|
356
357
|
Capybara.use_default_driver # switch back to default driver
|
|
357
358
|
```
|
|
@@ -391,7 +392,7 @@ Capybara supports [Selenium 3.5+
|
|
|
391
392
|
In order to use Selenium, you'll need to install the `selenium-webdriver` gem,
|
|
392
393
|
and add it to your Gemfile if you're using bundler.
|
|
393
394
|
|
|
394
|
-
Capybara pre-registers a number of named
|
|
395
|
+
Capybara pre-registers a number of named drivers that use Selenium - they are:
|
|
395
396
|
|
|
396
397
|
* :selenium => Selenium driving Firefox
|
|
397
398
|
* :selenium_headless => Selenium driving Firefox in a headless configuration
|
|
@@ -407,45 +408,6 @@ to the browsers. See the section on adding and configuring drivers.
|
|
|
407
408
|
same transaction as your tests, causing data not to be shared between your test
|
|
408
409
|
and test server, see [Transactions and database setup](#transactions-and-database-setup) below.
|
|
409
410
|
|
|
410
|
-
### <a name="apparition"></a>Apparition
|
|
411
|
-
|
|
412
|
-
The [apparition driver](https://github.com/twalpole/apparition) in a new driver thatallows you to run tests using Chrome in a headless
|
|
413
|
-
or headed configuration. It attempts to provide backwards compatibility with the [Poltergeist driver API](https://github.com/teampoltergeist/poltergeist)
|
|
414
|
-
while allowing for the use of modern JS/CSS. It uses CDP to communicate with Chrome, thereby obviating the need for chromedriver.
|
|
415
|
-
A compatibility layer for capybara-webkit is planned, although has not yet been started. This driver is being developed by the
|
|
416
|
-
maintainer of Capybara and will attempt to keep up to date with new Capybara releases. It will probably be moved into the
|
|
417
|
-
teamcapybara repo once completely stable.
|
|
418
|
-
|
|
419
|
-
### <a name="capybara-webkit"></a>Capybara-webkit
|
|
420
|
-
|
|
421
|
-
Note: `capybara-webkit` depends on QtWebkit which went EOL quite some time ago. There has been an attempt to revive the project but `capybara-webkit` is not yet (AFAIK) compatible with the revived version of QtWebKit (could be a good OSS project for someone) and as such is still limited to an old version of QtWebKit. This means its support for modern JS and CSS is severely limited.
|
|
422
|
-
|
|
423
|
-
The [capybara-webkit driver](https://github.com/thoughtbot/capybara-webkit) is for true headless
|
|
424
|
-
testing. It uses QtWebKit to start a rendering engine process. It can execute JavaScript as well.
|
|
425
|
-
It is significantly faster than drivers like Selenium since it does not load an entire browser.
|
|
426
|
-
|
|
427
|
-
You can install it with:
|
|
428
|
-
|
|
429
|
-
```bash
|
|
430
|
-
gem install capybara-webkit
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
And you can use it by:
|
|
434
|
-
|
|
435
|
-
```ruby
|
|
436
|
-
Capybara.javascript_driver = :webkit
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
### <a name="poltergeist"></a>Poltergeist
|
|
440
|
-
|
|
441
|
-
Note: `poltergeist` depends on PhantomJS for which active development ended quite some time ago (2.1.1). As such it is roughly equivalent to a 6-7 year old version of Safari, meaning lack of support for modern JS and CSS. If any effort to update PhantomJS succeeds in the future this situation could change.
|
|
442
|
-
|
|
443
|
-
[Poltergeist](https://github.com/teampoltergeist/poltergeist) is another
|
|
444
|
-
headless driver which integrates Capybara with
|
|
445
|
-
[PhantomJS](http://phantomjs.org/). It is truly headless, so doesn't
|
|
446
|
-
require Xvfb to run on your CI server. It will also detect and report
|
|
447
|
-
any Javascript errors that happen within the page.
|
|
448
|
-
|
|
449
411
|
## <a name="the-dsl"></a>The DSL
|
|
450
412
|
|
|
451
413
|
*A complete reference is available at
|
|
@@ -639,21 +601,31 @@ In drivers which support it, you can easily execute JavaScript:
|
|
|
639
601
|
page.execute_script("$('body').empty()")
|
|
640
602
|
```
|
|
641
603
|
|
|
642
|
-
For simple expressions, you can return the result of the script.
|
|
643
|
-
that this may break with more complicated expressions:
|
|
604
|
+
For simple expressions, you can return the result of the script.
|
|
644
605
|
|
|
645
606
|
```ruby
|
|
646
607
|
result = page.evaluate_script('4 + 4');
|
|
647
608
|
```
|
|
648
609
|
|
|
610
|
+
For more complicated scripts you'll need to write them as one expression.
|
|
611
|
+
|
|
612
|
+
```ruby
|
|
613
|
+
result = page.evaluate_script(<<~JS, 3, element)
|
|
614
|
+
(function(n, el){
|
|
615
|
+
var val = parseInt(el.value, 10);
|
|
616
|
+
return n+val;
|
|
617
|
+
})(arguments[0], arguments[1])
|
|
618
|
+
JS
|
|
619
|
+
```
|
|
620
|
+
|
|
649
621
|
### <a name="modals"></a>Modals
|
|
650
622
|
|
|
651
|
-
In drivers which support it, you can accept, dismiss and respond to alerts, confirms and prompts.
|
|
623
|
+
In drivers which support it, you can accept, dismiss and respond to alerts, confirms, and prompts.
|
|
652
624
|
|
|
653
|
-
You can accept
|
|
625
|
+
You can accept alert messages by wrapping the code that produces an alert in a block:
|
|
654
626
|
|
|
655
627
|
```ruby
|
|
656
|
-
accept_alert do
|
|
628
|
+
accept_alert 'optional text or regex' do
|
|
657
629
|
click_link('Show Alert')
|
|
658
630
|
end
|
|
659
631
|
```
|
|
@@ -661,7 +633,13 @@ end
|
|
|
661
633
|
You can accept or dismiss a confirmation by wrapping it in a block, as well:
|
|
662
634
|
|
|
663
635
|
```ruby
|
|
664
|
-
|
|
636
|
+
accept_confirm 'optional text' do
|
|
637
|
+
click_link('Show Confirm')
|
|
638
|
+
end
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
```ruby
|
|
642
|
+
dismiss_confirm 'optional text' do
|
|
665
643
|
click_link('Show Confirm')
|
|
666
644
|
end
|
|
667
645
|
```
|
|
@@ -669,7 +647,13 @@ end
|
|
|
669
647
|
You can accept or dismiss prompts as well, and also provide text to fill in for the response:
|
|
670
648
|
|
|
671
649
|
```ruby
|
|
672
|
-
accept_prompt(with: 'Linus Torvalds') do
|
|
650
|
+
accept_prompt('optional text', with: 'Linus Torvalds') do
|
|
651
|
+
click_link('Show Prompt About Linux')
|
|
652
|
+
end
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
```ruby
|
|
656
|
+
dismiss_prompt('optional text') do
|
|
673
657
|
click_link('Show Prompt About Linux')
|
|
674
658
|
end
|
|
675
659
|
```
|
|
@@ -719,6 +703,148 @@ Screenshots are saved to `Capybara.save_path`, relative to the app directory.
|
|
|
719
703
|
If you have required `capybara/rails`, `Capybara.save_path` will default to
|
|
720
704
|
`tmp/capybara`.
|
|
721
705
|
|
|
706
|
+
## <a name="selectors"></a>Selectors
|
|
707
|
+
|
|
708
|
+
Helpers and matchers that accept Selectors share a common method signature that
|
|
709
|
+
includes:
|
|
710
|
+
|
|
711
|
+
1. a positional Name argument
|
|
712
|
+
2. a positional Locator argument
|
|
713
|
+
3. keyword Filter arguments
|
|
714
|
+
4. a predicate Filter block argument
|
|
715
|
+
|
|
716
|
+
These arguments are usually optional in one way or another.
|
|
717
|
+
|
|
718
|
+
### <a name="selectors-name"></a>Name
|
|
719
|
+
|
|
720
|
+
The name argument determines the Selector to use. The argument is optional when
|
|
721
|
+
a helper explicitly conveys the selector name (for example, [`find_field`][]
|
|
722
|
+
uses `:field`, [`find_link`][] uses `:link`, etc):
|
|
723
|
+
|
|
724
|
+
```ruby
|
|
725
|
+
page.html # => '<a href="/">Home</a>'
|
|
726
|
+
|
|
727
|
+
page.find(:link) == page.find_link
|
|
728
|
+
|
|
729
|
+
page.html # => '<input>'
|
|
730
|
+
|
|
731
|
+
page.find(:field) == page.find_field
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
### <a name="selectors-locator"></a>Locator
|
|
735
|
+
|
|
736
|
+
The locator argument usually represents information that can most meaningfully
|
|
737
|
+
distinguish an element that matches the selector from an element that does not:
|
|
738
|
+
|
|
739
|
+
```ruby
|
|
740
|
+
page.html # => '<div id="greeting">Hello world</div>'
|
|
741
|
+
|
|
742
|
+
page.find(:css, 'div').text # => 'Hello world'
|
|
743
|
+
page.find(:xpath, './/div').text # => 'Hello world'
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
General purpose finder methods like [`find`][] and [`all`][] can accept the
|
|
747
|
+
locator as their first positional argument when the method can infer the default
|
|
748
|
+
value from the [`Capybara.default_selector`][] configuration:
|
|
749
|
+
|
|
750
|
+
```ruby
|
|
751
|
+
page.html # => '<div id="greeting">Hello world</div>'
|
|
752
|
+
|
|
753
|
+
Capybara.default_selector = :css
|
|
754
|
+
|
|
755
|
+
page.find('div').text # => 'Hello world'
|
|
756
|
+
|
|
757
|
+
Capybara.default_selector = :xpath
|
|
758
|
+
|
|
759
|
+
page.find('.//div').text # => 'Hello world'
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
The locator argument's semantics are context-specific, and depend on the
|
|
763
|
+
selector. The types of arguments are varied. Some selectors support `String` or
|
|
764
|
+
`Regexp` arguments, while others like `:table_row` support `Array<String>` and
|
|
765
|
+
`Hash<String, String>`:
|
|
766
|
+
|
|
767
|
+
```ruby
|
|
768
|
+
page.html # => '<label for="greeting">Greeting</label>
|
|
769
|
+
<input id="greeting" name="content">'
|
|
770
|
+
|
|
771
|
+
# find by the <input> element's [id] attribute
|
|
772
|
+
page.find(:id, 'greeting') == page.find_by_id('greeting') # => true
|
|
773
|
+
|
|
774
|
+
# find by the <input> element's [id] attribute
|
|
775
|
+
page.find(:field, 'greeting') == page.find_field('greeting') # => true
|
|
776
|
+
|
|
777
|
+
# find by the <input> element's [name] attribute
|
|
778
|
+
page.find(:field, 'content') == page.find_field('content') # => true
|
|
779
|
+
|
|
780
|
+
# find by the <label> element's text
|
|
781
|
+
page.find(:field, 'Greeting') == page.find_field('Greeting') # => true
|
|
782
|
+
|
|
783
|
+
page.html # => '<table>
|
|
784
|
+
<tr>
|
|
785
|
+
<th>A</th>
|
|
786
|
+
<th>B</th>
|
|
787
|
+
</tr>
|
|
788
|
+
<tr>
|
|
789
|
+
<td>1</td>
|
|
790
|
+
<td>2</td>
|
|
791
|
+
</tr>
|
|
792
|
+
</table>'
|
|
793
|
+
|
|
794
|
+
# find by <td> content
|
|
795
|
+
page.find(:table_row, ['1', '2']) == page.find(:css, 'tr:last-of-type') # => true
|
|
796
|
+
|
|
797
|
+
# find by <th> content paired with corresponding <td> content
|
|
798
|
+
page.find(:table_row, 'A' => '1') == page.find(:table_row, 'B' => '2') # => true
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
### <a name="selectors-filters"></a> Filters
|
|
802
|
+
|
|
803
|
+
All filters are optional. The supported set of keys is a mixture of both global
|
|
804
|
+
and context-specific filters.The supported types of values depend on the
|
|
805
|
+
context:
|
|
806
|
+
|
|
807
|
+
```ruby
|
|
808
|
+
page.html # => '<a href="/">Home</a>'
|
|
809
|
+
|
|
810
|
+
# find by the [href] attribute
|
|
811
|
+
page.find_link(href: '/') == page.find_link(text: 'Home') # => true
|
|
812
|
+
|
|
813
|
+
page.html # => '<div id="element" data-attribute="value">Content</div>'
|
|
814
|
+
|
|
815
|
+
# find by the [id] attribute
|
|
816
|
+
page.find(id: 'element') == page.find(text: 'Content') # => true
|
|
817
|
+
|
|
818
|
+
# find by the [data-attribute] attribute
|
|
819
|
+
page.find(:element, 'data-attribute': /value/) == page.find(text: 'Content') # => true
|
|
820
|
+
|
|
821
|
+
page.html # => '<input type="checkbox">'
|
|
822
|
+
|
|
823
|
+
# find by the absence of the [checked] attribute
|
|
824
|
+
page.find_field(checked: false) == page.find_field(unchecked: true) # => true
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
The predicate block is always optional. When there are results for a selector
|
|
828
|
+
query, the block is called with each item in the result set. When the block
|
|
829
|
+
evaluates to true, the item is included from the result set. Otherwise, the item
|
|
830
|
+
is excluded:
|
|
831
|
+
|
|
832
|
+
```ruby
|
|
833
|
+
page.html # => '<input role="switch" type="checkbox" checked>'
|
|
834
|
+
|
|
835
|
+
switch = page.find_field { |input| input["role"] == "switch" }
|
|
836
|
+
field = page.find_field(checked: true)
|
|
837
|
+
|
|
838
|
+
switch == field # => true
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
[`find`]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders:find
|
|
842
|
+
[`all`]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders:all
|
|
843
|
+
[`Capybara.default_selector`]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2Econfigure
|
|
844
|
+
[`find_by_id`]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders:find_by_id
|
|
845
|
+
[`find_field`]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders:find_field
|
|
846
|
+
[`find_link`]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders:find_link
|
|
847
|
+
|
|
722
848
|
## <a name="matching"></a>Matching
|
|
723
849
|
|
|
724
850
|
It is possible to customize how Capybara finds elements. At your disposal
|
|
@@ -799,7 +925,7 @@ expect(page).to have_content('baz')
|
|
|
799
925
|
If clicking on the *foo* link triggers an asynchronous process, such as
|
|
800
926
|
an Ajax request, which, when complete will add the *bar* link to the page,
|
|
801
927
|
clicking on the *bar* link would be expected to fail, since that link doesn't
|
|
802
|
-
exist yet. However Capybara is smart enough to retry finding the link for a
|
|
928
|
+
exist yet. However, Capybara is smart enough to retry finding the link for a
|
|
803
929
|
brief period of time before giving up and throwing an error. The same is true of
|
|
804
930
|
the next line, which looks for the content *baz* on the page; it will retry
|
|
805
931
|
looking for that content for a brief time. You can adjust how long this period
|
|
@@ -813,13 +939,25 @@ Be aware that because of this behaviour, the following two statements are **not*
|
|
|
813
939
|
equivalent, and you should **always** use the latter!
|
|
814
940
|
|
|
815
941
|
```ruby
|
|
816
|
-
|
|
817
|
-
|
|
942
|
+
# Given use of a driver where the page is loaded when visit returns
|
|
943
|
+
# and that Capybara.predicates_wait is `true`
|
|
944
|
+
# consider a page where the `a` tag is removed through AJAX after 1s
|
|
945
|
+
visit(some_path)
|
|
946
|
+
!page.has_xpath?('a') # is false
|
|
947
|
+
page.has_no_xpath?('a') # is true
|
|
818
948
|
```
|
|
819
949
|
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
950
|
+
First expression:
|
|
951
|
+
- `has_xpath?('a')` is called right after `visit` returns. It is `true` because the link has not yet been removed
|
|
952
|
+
- Capybara does not wait upon successful predicates/assertions, therefore **has_xpath? returns `true` immediately**
|
|
953
|
+
- The expression returns `false` (because it is negated with the leading `!`)
|
|
954
|
+
|
|
955
|
+
Second expression:
|
|
956
|
+
- `has_no_xpath?('a')` is called right after `visit` returns. It is `false` because the link has not yet been removed.
|
|
957
|
+
- Capybara waits upon failed predicates/assertions, therefore **has_no_xpath? does not return `false` immediately**
|
|
958
|
+
- Capybara will periodically re-check the predicate/assertion up to the `default_max_wait_time` defined
|
|
959
|
+
- after 1s, the predicate becomes `true` (because the link has been removed)
|
|
960
|
+
- The expression returns `true`
|
|
823
961
|
|
|
824
962
|
Capybara's RSpec matchers, however, are smart enough to handle either form.
|
|
825
963
|
The two following statements are functionally equivalent:
|
|
@@ -954,12 +1092,17 @@ Capybara.default_selector = :xpath
|
|
|
954
1092
|
find('.//ul/li').text
|
|
955
1093
|
```
|
|
956
1094
|
|
|
957
|
-
Capybara
|
|
958
|
-
|
|
1095
|
+
Capybara provides a number of other built-in selector types. The full list, along
|
|
1096
|
+
with applicable filters, can be seen at [built-in selectors](https://www.rubydoc.info/github/teamcapybara/capybara/Capybara/Selector)
|
|
1097
|
+
|
|
1098
|
+
Capybara also allows you to add custom selectors, which can be very useful if you
|
|
1099
|
+
find yourself using the same kinds of selectors very often. The examples below are very
|
|
1100
|
+
simple, and there are many available features not demonstrated. For more in-depth examples
|
|
1101
|
+
please see Capybaras built-in selector definitions.
|
|
959
1102
|
|
|
960
1103
|
```ruby
|
|
961
|
-
Capybara.add_selector(:
|
|
962
|
-
xpath { |id| XPath.descendant[XPath.attr(:
|
|
1104
|
+
Capybara.add_selector(:my_attribute) do
|
|
1105
|
+
xpath { |id| XPath.descendant[XPath.attr(:my_attribute) == id.to_s] }
|
|
963
1106
|
end
|
|
964
1107
|
|
|
965
1108
|
Capybara.add_selector(:row) do
|
|
@@ -976,9 +1119,9 @@ an XPath expression generated through the XPath gem. You can now use these
|
|
|
976
1119
|
selectors like this:
|
|
977
1120
|
|
|
978
1121
|
```ruby
|
|
979
|
-
find(:
|
|
980
|
-
find(:row, 3)
|
|
981
|
-
find(:flash_type, :notice)
|
|
1122
|
+
find(:my_attribute, 'post_123') # find element with matching attribute
|
|
1123
|
+
find(:row, 3) # find 3rd row in table body
|
|
1124
|
+
find(:flash_type, :notice) # find element with id of 'flash' and class of 'notice'
|
|
982
1125
|
```
|
|
983
1126
|
|
|
984
1127
|
## <a name="beware-the-xpath--trap"></a>Beware the XPath // trap
|
|
@@ -1070,6 +1213,13 @@ additional info about how the underlying driver can be configured.
|
|
|
1070
1213
|
are testing for specific server errors and using multiple sessions make sure to test for the
|
|
1071
1214
|
errors using the initial session (usually :default)
|
|
1072
1215
|
|
|
1216
|
+
* If WebMock is enabled, you may encounter a "Too many open files"
|
|
1217
|
+
error. A simple `page.find` call may cause thousands of HTTP requests
|
|
1218
|
+
until the timeout occurs. By default, WebMock will cause each of these
|
|
1219
|
+
requests to spawn a new connection. To work around this problem, you
|
|
1220
|
+
may need to [enable WebMock's `net_http_connect_on_start: true`
|
|
1221
|
+
parameter](https://github.com/bblimke/webmock/blob/master/README.md#connecting-on-nethttpstart).
|
|
1222
|
+
|
|
1073
1223
|
## <a name="threadsafe"></a>"Threadsafe" mode
|
|
1074
1224
|
|
|
1075
1225
|
In normal mode most of Capybara's configuration options are global settings which can cause issues
|
data/lib/capybara/config.rb
CHANGED
|
@@ -7,14 +7,13 @@ module Capybara
|
|
|
7
7
|
class Config
|
|
8
8
|
extend Forwardable
|
|
9
9
|
|
|
10
|
-
OPTIONS = %i[
|
|
11
|
-
|
|
10
|
+
OPTIONS = %i[
|
|
11
|
+
app reuse_server threadsafe server default_driver javascript_driver use_html5_parsing allow_gumbo
|
|
12
|
+
].freeze
|
|
12
13
|
|
|
13
|
-
attr_accessor :app
|
|
14
|
-
attr_reader :reuse_server, :threadsafe
|
|
15
|
-
attr_reader :session_options
|
|
14
|
+
attr_accessor :app, :use_html5_parsing
|
|
15
|
+
attr_reader :reuse_server, :threadsafe, :session_options # rubocop:disable Style/BisectedAttrAccessor
|
|
16
16
|
attr_writer :default_driver, :javascript_driver
|
|
17
|
-
attr_accessor :allow_gumbo
|
|
18
17
|
|
|
19
18
|
SessionConfig::OPTIONS.each do |method|
|
|
20
19
|
def_delegators :session_options, method, "#{method}="
|
|
@@ -25,10 +24,12 @@ module Capybara
|
|
|
25
24
|
@javascript_driver = nil
|
|
26
25
|
end
|
|
27
26
|
|
|
28
|
-
attr_writer :reuse_server
|
|
27
|
+
attr_writer :reuse_server # rubocop:disable Style/BisectedAttrAccessor
|
|
29
28
|
|
|
30
29
|
def threadsafe=(bool)
|
|
31
|
-
|
|
30
|
+
if (bool != threadsafe) && Session.instance_created?
|
|
31
|
+
raise 'Threadsafe setting cannot be changed once a session is created'
|
|
32
|
+
end
|
|
32
33
|
|
|
33
34
|
@threadsafe = bool
|
|
34
35
|
end
|
|
@@ -60,7 +61,7 @@ module Capybara
|
|
|
60
61
|
@server = if name.respond_to? :call
|
|
61
62
|
name
|
|
62
63
|
elsif options
|
|
63
|
-
proc { |app, port, host| Capybara.servers[name.to_sym].call(app, port, host, options) }
|
|
64
|
+
proc { |app, port, host| Capybara.servers[name.to_sym].call(app, port, host, **options) }
|
|
64
65
|
else
|
|
65
66
|
Capybara.servers[name.to_sym]
|
|
66
67
|
end
|
|
@@ -82,10 +83,22 @@ module Capybara
|
|
|
82
83
|
@javascript_driver || :selenium
|
|
83
84
|
end
|
|
84
85
|
|
|
85
|
-
def deprecate(method, alternate_method, once
|
|
86
|
+
def deprecate(method, alternate_method, once: false)
|
|
86
87
|
@deprecation_notified ||= {}
|
|
87
|
-
|
|
88
|
+
unless once && @deprecation_notified[method]
|
|
89
|
+
Capybara::Helpers.warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead: #{Capybara::Helpers.filter_backtrace(caller)}"
|
|
90
|
+
end
|
|
88
91
|
@deprecation_notified[method] = true
|
|
89
92
|
end
|
|
93
|
+
|
|
94
|
+
def allow_gumbo=(val)
|
|
95
|
+
deprecate('allow_gumbo=', 'use_html5_parsing=')
|
|
96
|
+
self.use_html5_parsing = val
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def allow_gumbo
|
|
100
|
+
deprecate('allow_gumbo', 'use_html5_parsing')
|
|
101
|
+
use_html5_parsing
|
|
102
|
+
end
|
|
90
103
|
end
|
|
91
104
|
end
|
data/lib/capybara/cucumber.rb
CHANGED
|
@@ -22,6 +22,6 @@ end
|
|
|
22
22
|
Before do |scenario|
|
|
23
23
|
scenario.source_tag_names.each do |tag|
|
|
24
24
|
driver_name = tag.sub(/^@/, '').to_sym
|
|
25
|
-
Capybara.current_driver = driver_name if Capybara.drivers
|
|
25
|
+
Capybara.current_driver = driver_name if Capybara.drivers[driver_name]
|
|
26
26
|
end
|
|
27
27
|
end
|
data/lib/capybara/driver/base.rb
CHANGED
|
@@ -59,6 +59,14 @@ class Capybara::Driver::Base
|
|
|
59
59
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#status_code'
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
+
def send_keys(*)
|
|
63
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#send_keys'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def active_element
|
|
67
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#active_element'
|
|
68
|
+
end
|
|
69
|
+
|
|
62
70
|
##
|
|
63
71
|
#
|
|
64
72
|
# @param frame [Capybara::Node::Element, :parent, :top] The iframe element to switch to
|