capybara 2.5.0 → 2.18.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 +5 -5
- data/.yard/templates_custom/default/class/html/selectors.erb +38 -0
- data/.yard/templates_custom/default/class/html/setup.rb +17 -0
- data/.yard/yard_extensions.rb +78 -0
- data/.yardopts +1 -0
- data/History.md +413 -10
- data/License.txt +1 -1
- data/README.md +237 -130
- data/lib/capybara/config.rb +132 -0
- data/lib/capybara/cucumber.rb +3 -1
- data/lib/capybara/driver/base.rb +27 -6
- data/lib/capybara/driver/node.rb +14 -5
- data/lib/capybara/dsl.rb +2 -3
- data/lib/capybara/helpers.rb +13 -65
- data/lib/capybara/minitest/spec.rb +177 -0
- data/lib/capybara/minitest.rb +278 -0
- data/lib/capybara/node/actions.rb +180 -24
- data/lib/capybara/node/base.rb +17 -5
- data/lib/capybara/node/document.rb +5 -0
- data/lib/capybara/node/document_matchers.rb +15 -14
- data/lib/capybara/node/element.rb +55 -7
- data/lib/capybara/node/finders.rb +179 -67
- data/lib/capybara/node/matchers.rb +301 -105
- data/lib/capybara/node/simple.rb +15 -4
- data/lib/capybara/queries/ancestor_query.rb +25 -0
- data/lib/capybara/queries/base_query.rb +69 -3
- data/lib/capybara/queries/current_path_query.rb +17 -8
- data/lib/capybara/queries/match_query.rb +19 -0
- data/lib/capybara/queries/selector_query.rb +251 -0
- data/lib/capybara/queries/sibling_query.rb +25 -0
- data/lib/capybara/queries/text_query.rb +67 -16
- data/lib/capybara/queries/title_query.rb +4 -2
- data/lib/capybara/query.rb +3 -131
- data/lib/capybara/rack_test/browser.rb +14 -5
- data/lib/capybara/rack_test/css_handlers.rb +1 -0
- data/lib/capybara/rack_test/driver.rb +15 -8
- data/lib/capybara/rack_test/form.rb +34 -12
- data/lib/capybara/rack_test/node.rb +29 -12
- data/lib/capybara/rails.rb +3 -3
- data/lib/capybara/result.rb +104 -9
- data/lib/capybara/rspec/compound.rb +95 -0
- data/lib/capybara/rspec/features.rb +17 -6
- data/lib/capybara/rspec/matcher_proxies.rb +45 -0
- data/lib/capybara/rspec/matchers.rb +199 -80
- data/lib/capybara/rspec.rb +4 -2
- data/lib/capybara/selector/css.rb +30 -0
- data/lib/capybara/selector/filter.rb +20 -0
- data/lib/capybara/selector/filter_set.rb +74 -0
- data/lib/capybara/selector/filters/base.rb +33 -0
- data/lib/capybara/selector/filters/expression_filter.rb +40 -0
- data/lib/capybara/selector/filters/node_filter.rb +27 -0
- data/lib/capybara/selector/selector.rb +276 -0
- data/lib/capybara/selector.rb +452 -157
- data/lib/capybara/selenium/driver.rb +282 -81
- data/lib/capybara/selenium/node.rb +144 -46
- data/lib/capybara/server.rb +59 -16
- data/lib/capybara/session/config.rb +114 -0
- data/lib/capybara/session/matchers.rb +29 -19
- data/lib/capybara/session.rb +378 -143
- data/lib/capybara/spec/fixtures/no_extension +1 -0
- data/lib/capybara/spec/public/jquery-ui.js +13 -791
- data/lib/capybara/spec/public/jquery.js +4 -9045
- data/lib/capybara/spec/public/test.js +45 -11
- data/lib/capybara/spec/session/accept_alert_spec.rb +30 -7
- data/lib/capybara/spec/session/accept_confirm_spec.rb +14 -2
- data/lib/capybara/spec/session/accept_prompt_spec.rb +35 -6
- data/lib/capybara/spec/session/all_spec.rb +45 -32
- data/lib/capybara/spec/session/ancestor_spec.rb +85 -0
- data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +110 -0
- data/lib/capybara/spec/session/assert_current_path.rb +15 -2
- data/lib/capybara/spec/session/assert_selector.rb +29 -28
- data/lib/capybara/spec/session/assert_text.rb +59 -20
- data/lib/capybara/spec/session/assert_title.rb +25 -11
- data/lib/capybara/spec/session/attach_file_spec.rb +42 -4
- data/lib/capybara/spec/session/body_spec.rb +1 -0
- data/lib/capybara/spec/session/check_spec.rb +90 -14
- data/lib/capybara/spec/session/choose_spec.rb +31 -5
- data/lib/capybara/spec/session/click_button_spec.rb +20 -9
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +15 -9
- data/lib/capybara/spec/session/click_link_spec.rb +39 -15
- data/lib/capybara/spec/session/current_scope_spec.rb +2 -1
- data/lib/capybara/spec/session/current_url_spec.rb +12 -3
- data/lib/capybara/spec/session/dismiss_confirm_spec.rb +6 -5
- data/lib/capybara/spec/session/dismiss_prompt_spec.rb +4 -3
- data/lib/capybara/spec/session/element/assert_match_selector.rb +36 -0
- data/lib/capybara/spec/session/element/match_css_spec.rb +23 -0
- data/lib/capybara/spec/session/element/match_xpath_spec.rb +23 -0
- data/lib/capybara/spec/session/element/matches_selector_spec.rb +106 -0
- data/lib/capybara/spec/session/evaluate_async_script_spec.rb +22 -0
- data/lib/capybara/spec/session/evaluate_script_spec.rb +23 -1
- data/lib/capybara/spec/session/execute_script_spec.rb +22 -3
- data/lib/capybara/spec/session/fill_in_spec.rb +50 -32
- data/lib/capybara/spec/session/find_button_spec.rb +43 -2
- data/lib/capybara/spec/session/find_by_id_spec.rb +3 -2
- data/lib/capybara/spec/session/find_field_spec.rb +42 -6
- data/lib/capybara/spec/session/find_link_spec.rb +22 -3
- data/lib/capybara/spec/session/find_spec.rb +103 -57
- data/lib/capybara/spec/session/first_spec.rb +34 -18
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +103 -0
- data/lib/capybara/spec/session/{within_frame_spec.rb → frame/within_frame_spec.rb} +44 -2
- data/lib/capybara/spec/session/go_back_spec.rb +2 -1
- data/lib/capybara/spec/session/go_forward_spec.rb +2 -1
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
- data/lib/capybara/spec/session/has_button_spec.rb +17 -8
- data/lib/capybara/spec/session/has_css_spec.rb +85 -73
- data/lib/capybara/spec/session/has_current_path_spec.rb +91 -7
- data/lib/capybara/spec/session/has_field_spec.rb +93 -58
- data/lib/capybara/spec/session/has_link_spec.rb +9 -8
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +76 -0
- data/lib/capybara/spec/session/has_select_spec.rb +159 -59
- data/lib/capybara/spec/session/has_selector_spec.rb +64 -28
- data/lib/capybara/spec/session/has_table_spec.rb +1 -0
- data/lib/capybara/spec/session/has_text_spec.rb +27 -12
- data/lib/capybara/spec/session/has_title_spec.rb +22 -4
- data/lib/capybara/spec/session/has_xpath_spec.rb +32 -29
- data/lib/capybara/spec/session/headers.rb +2 -1
- data/lib/capybara/spec/session/html_spec.rb +4 -3
- data/lib/capybara/spec/session/node_spec.rb +198 -38
- data/lib/capybara/spec/session/refresh_spec.rb +28 -0
- data/lib/capybara/spec/session/reset_session_spec.rb +46 -5
- data/lib/capybara/spec/session/response_code.rb +2 -1
- data/lib/capybara/spec/session/save_and_open_page_spec.rb +1 -0
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +6 -5
- data/lib/capybara/spec/session/save_page_spec.rb +34 -2
- data/lib/capybara/spec/session/save_screenshot_spec.rb +31 -1
- data/lib/capybara/spec/session/screenshot_spec.rb +4 -2
- data/lib/capybara/spec/session/select_spec.rb +34 -32
- data/lib/capybara/spec/session/selectors_spec.rb +65 -0
- data/lib/capybara/spec/session/sibling_spec.rb +52 -0
- data/lib/capybara/spec/session/text_spec.rb +4 -4
- data/lib/capybara/spec/session/title_spec.rb +2 -1
- data/lib/capybara/spec/session/uncheck_spec.rb +42 -2
- data/lib/capybara/spec/session/unselect_spec.rb +17 -16
- data/lib/capybara/spec/session/visit_spec.rb +77 -2
- data/lib/capybara/spec/session/window/become_closed_spec.rb +12 -11
- data/lib/capybara/spec/session/window/current_window_spec.rb +1 -0
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +1 -0
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +16 -11
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +7 -4
- data/lib/capybara/spec/session/window/window_spec.rb +36 -29
- data/lib/capybara/spec/session/window/windows_spec.rb +1 -0
- data/lib/capybara/spec/session/window/within_window_spec.rb +31 -7
- data/lib/capybara/spec/session/within_spec.rb +14 -6
- data/lib/capybara/spec/spec_helper.rb +37 -4
- data/lib/capybara/spec/test_app.rb +15 -3
- data/lib/capybara/spec/views/buttons.erb +1 -0
- data/lib/capybara/spec/views/fieldsets.erb +2 -1
- data/lib/capybara/spec/views/form.erb +169 -9
- 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 +3 -2
- data/lib/capybara/spec/views/frame_two.erb +2 -1
- data/lib/capybara/spec/views/header_links.erb +1 -0
- data/lib/capybara/spec/views/host_links.erb +1 -0
- data/lib/capybara/spec/views/initial_alert.erb +10 -0
- data/lib/capybara/spec/views/path.erb +1 -0
- data/lib/capybara/spec/views/popup_one.erb +1 -0
- data/lib/capybara/spec/views/popup_two.erb +1 -0
- data/lib/capybara/spec/views/postback.erb +2 -1
- data/lib/capybara/spec/views/tables.erb +1 -0
- data/lib/capybara/spec/views/with_base_tag.erb +1 -0
- data/lib/capybara/spec/views/with_count.erb +2 -1
- 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_html.erb +40 -2
- data/lib/capybara/spec/views/with_html_entities.erb +1 -0
- data/lib/capybara/spec/views/with_js.erb +32 -1
- data/lib/capybara/spec/views/with_scope.erb +1 -0
- data/lib/capybara/spec/views/with_simple_html.erb +2 -1
- data/lib/capybara/spec/views/with_slow_unload.erb +17 -0
- data/lib/capybara/spec/views/with_title.erb +2 -1
- data/lib/capybara/spec/views/with_unload_alert.erb +14 -0
- data/lib/capybara/spec/views/with_windows.erb +7 -0
- data/lib/capybara/spec/views/within_frames.erb +3 -2
- data/lib/capybara/version.rb +2 -1
- data/lib/capybara/window.rb +20 -3
- data/lib/capybara.rb +189 -93
- data/spec/basic_node_spec.rb +7 -6
- data/spec/capybara_spec.rb +90 -4
- data/spec/dsl_spec.rb +3 -1
- data/spec/filter_set_spec.rb +28 -0
- data/spec/fixtures/capybara.csv +1 -0
- data/spec/fixtures/selenium_driver_rspec_failure.rb +5 -1
- data/spec/fixtures/selenium_driver_rspec_success.rb +5 -1
- data/spec/minitest_spec.rb +130 -0
- data/spec/minitest_spec_spec.rb +135 -0
- data/spec/per_session_config_spec.rb +67 -0
- data/spec/rack_test_spec.rb +50 -7
- data/spec/result_spec.rb +76 -0
- data/spec/rspec/features_spec.rb +21 -8
- data/spec/rspec/scenarios_spec.rb +21 -0
- data/spec/rspec/{matchers_spec.rb → shared_spec_matchers.rb} +160 -54
- data/spec/rspec/views_spec.rb +5 -0
- data/spec/rspec_matchers_spec.rb +46 -0
- data/spec/rspec_spec.rb +79 -1
- data/spec/selector_spec.rb +199 -0
- data/spec/selenium_spec_chrome.rb +54 -9
- data/spec/selenium_spec_firefox.rb +68 -0
- data/spec/selenium_spec_marionette.rb +127 -0
- data/spec/server_spec.rb +102 -14
- data/spec/session_spec.rb +54 -0
- data/spec/shared_selenium_session.rb +215 -0
- data/spec/spec_helper.rb +7 -0
- metadata +140 -15
- data/spec/selenium_spec.rb +0 -128
data/README.md
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
# Capybara
|
|
2
2
|
|
|
3
|
-
[](https://travis-ci.org/teamcapybara/capybara)
|
|
4
|
+
[](https://gemnasium.com/teamcapybara/capybara)
|
|
5
|
+
[](https://codeclimate.com/github/teamcapybara/capybara)
|
|
6
|
+
[](https://gitter.im/jnicklas/capybara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
6
7
|
|
|
7
8
|
Capybara helps you test web applications by simulating how a real user would
|
|
8
9
|
interact with your app. It is agnostic about the driver running your tests and
|
|
9
10
|
comes with Rack::Test and Selenium support built in. WebKit is supported
|
|
10
11
|
through an external gem.
|
|
11
12
|
|
|
13
|
+
## Support Capybara
|
|
14
|
+
|
|
15
|
+
If you and/or your company find value in Capybara and would like to contribute financially to its ongoing maintenance and development, please visit
|
|
16
|
+
<a href="https://www.patreon.com/capybara">Patreon</a>
|
|
17
|
+
|
|
18
|
+
|
|
12
19
|
**Need help?** Ask on the mailing list (please do not open an issue on
|
|
13
20
|
GitHub): http://groups.google.com/group/ruby-capybara
|
|
14
21
|
|
|
@@ -19,7 +26,8 @@ GitHub): http://groups.google.com/group/ruby-capybara
|
|
|
19
26
|
- [Using Capybara with Cucumber](#using-capybara-with-cucumber)
|
|
20
27
|
- [Using Capybara with RSpec](#using-capybara-with-rspec)
|
|
21
28
|
- [Using Capybara with Test::Unit](#using-capybara-with-testunit)
|
|
22
|
-
- [Using Capybara with
|
|
29
|
+
- [Using Capybara with Minitest](#using-capybara-with-minitest)
|
|
30
|
+
- [Using Capybara with Minitest::Spec](#using-capybara-with-minitestspec)
|
|
23
31
|
- [Drivers](#drivers)
|
|
24
32
|
- [Selecting the Driver](#selecting-the-driver)
|
|
25
33
|
- [RackTest](#racktest)
|
|
@@ -44,14 +52,15 @@ GitHub): http://groups.google.com/group/ruby-capybara
|
|
|
44
52
|
- [Asynchronous JavaScript (Ajax and friends)](#asynchronous-javascript-ajax-and-friends)
|
|
45
53
|
- [Using the DSL elsewhere](#using-the-dsl-elsewhere)
|
|
46
54
|
- [Calling remote servers](#calling-remote-servers)
|
|
47
|
-
- [Using
|
|
55
|
+
- [Using sessions](#using-sessions)
|
|
48
56
|
- [XPath, CSS and selectors](#xpath-css-and-selectors)
|
|
49
57
|
- [Beware the XPath // trap](#beware-the-xpath--trap)
|
|
50
58
|
- [Configuring and adding drivers](#configuring-and-adding-drivers)
|
|
51
59
|
- [Gotchas:](#gotchas)
|
|
60
|
+
- ["Threadsafe" mode](#threadsafe)
|
|
52
61
|
- [Development](#development)
|
|
53
62
|
|
|
54
|
-
## Key benefits
|
|
63
|
+
## <a name="key-benefits"></a>Key benefits
|
|
55
64
|
|
|
56
65
|
- **No setup** necessary for Rails and Rack application. Works out of the box.
|
|
57
66
|
- **Intuitive API** which mimics the language an actual user would use.
|
|
@@ -60,7 +69,7 @@ GitHub): http://groups.google.com/group/ruby-capybara
|
|
|
60
69
|
- **Powerful synchronization** features mean you never have to manually wait
|
|
61
70
|
for asynchronous processes to complete.
|
|
62
71
|
|
|
63
|
-
## Setup
|
|
72
|
+
## <a name="setup"></a>Setup
|
|
64
73
|
|
|
65
74
|
Capybara requires Ruby 1.9.3 or later. To install, add this line to your
|
|
66
75
|
`Gemfile` and run `bundle install`:
|
|
@@ -69,6 +78,8 @@ Capybara requires Ruby 1.9.3 or later. To install, add this line to your
|
|
|
69
78
|
gem 'capybara'
|
|
70
79
|
```
|
|
71
80
|
|
|
81
|
+
**Note:** If using Ruby < 2.0 you will also need to limit the version of rack to < 2.0
|
|
82
|
+
|
|
72
83
|
If the application that you are testing is a Rails app, add this line to your test helper file:
|
|
73
84
|
|
|
74
85
|
```ruby
|
|
@@ -85,9 +96,15 @@ Capybara.app = MyRackApp
|
|
|
85
96
|
```
|
|
86
97
|
|
|
87
98
|
If you need to test JavaScript, or if your app interacts with (or is located at)
|
|
88
|
-
a remote URL, you'll need to [use a different driver](#drivers).
|
|
99
|
+
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
|
|
100
|
+
want to swap the "server" used to launch your app to Puma in order to match Rails defaults.
|
|
89
101
|
|
|
90
|
-
|
|
102
|
+
```ruby
|
|
103
|
+
Capybara.server = :puma # Until your setup is working
|
|
104
|
+
Capybara.server = :puma, { Silent: true } # To clean up your test output
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## <a name="using-capybara-with-cucumber"></a>Using Capybara with Cucumber
|
|
91
108
|
|
|
92
109
|
The `cucumber-rails` gem comes with Capybara support built-in. If you
|
|
93
110
|
are not using Rails, manually load the `capybara/cucumber` module:
|
|
@@ -102,8 +119,8 @@ You can use the Capybara DSL in your steps, like so:
|
|
|
102
119
|
```ruby
|
|
103
120
|
When /I sign in/ do
|
|
104
121
|
within("#session") do
|
|
105
|
-
fill_in 'Email', :
|
|
106
|
-
fill_in 'Password', :
|
|
122
|
+
fill_in 'Email', with: 'user@example.com'
|
|
123
|
+
fill_in 'Password', with: 'password'
|
|
107
124
|
end
|
|
108
125
|
click_button 'Sign in'
|
|
109
126
|
end
|
|
@@ -119,19 +136,22 @@ Scenario: do something Ajaxy
|
|
|
119
136
|
...
|
|
120
137
|
```
|
|
121
138
|
|
|
122
|
-
There are also explicit `@selenium
|
|
123
|
-
tags set up for you.
|
|
139
|
+
There are also explicit tags for each registered driver set up for you (`@selenium`, `@rack_test`, etc).
|
|
124
140
|
|
|
125
|
-
## Using Capybara with RSpec
|
|
141
|
+
## <a name="using-capybara-with-rspec"></a>Using Capybara with RSpec
|
|
126
142
|
|
|
127
|
-
Load RSpec 2
|
|
143
|
+
Load RSpec 2+ support by adding the following line (typically to your
|
|
128
144
|
`spec_helper.rb` file):
|
|
129
145
|
|
|
130
146
|
```ruby
|
|
131
147
|
require 'capybara/rspec'
|
|
132
148
|
```
|
|
133
149
|
|
|
134
|
-
If you are using Rails, put your Capybara specs in `spec/features
|
|
150
|
+
If you are using Rails, put your Capybara specs in `spec/features` (only works
|
|
151
|
+
if [you have it configured in
|
|
152
|
+
RSpec](https://www.relishapp.com/rspec/rspec-rails/docs/upgrade#file-type-inference-disabled))
|
|
153
|
+
and if you have your Capybara specs in a different directory, then tag the
|
|
154
|
+
example groups with `:type => :feature`.
|
|
135
155
|
|
|
136
156
|
If you are not using Rails, tag all the example groups in which you want to use
|
|
137
157
|
Capybara with `:type => :feature`.
|
|
@@ -141,14 +161,14 @@ You can now write your specs like so:
|
|
|
141
161
|
```ruby
|
|
142
162
|
describe "the signin process", :type => :feature do
|
|
143
163
|
before :each do
|
|
144
|
-
User.make(:
|
|
164
|
+
User.make(email: 'user@example.com', password: 'password')
|
|
145
165
|
end
|
|
146
166
|
|
|
147
167
|
it "signs me in" do
|
|
148
168
|
visit '/sessions/new'
|
|
149
169
|
within("#session") do
|
|
150
|
-
fill_in 'Email', :
|
|
151
|
-
fill_in 'Password', :
|
|
170
|
+
fill_in 'Email', with: 'user@example.com'
|
|
171
|
+
fill_in 'Password', with: 'password'
|
|
152
172
|
end
|
|
153
173
|
click_button 'Sign in'
|
|
154
174
|
expect(page).to have_content 'Success'
|
|
@@ -156,12 +176,12 @@ describe "the signin process", :type => :feature do
|
|
|
156
176
|
end
|
|
157
177
|
```
|
|
158
178
|
|
|
159
|
-
Use
|
|
179
|
+
Use `js: true` to switch to the `Capybara.javascript_driver`
|
|
160
180
|
(`:selenium` by default), or provide a `:driver` option to switch
|
|
161
181
|
to one specific driver. For example:
|
|
162
182
|
|
|
163
183
|
```ruby
|
|
164
|
-
describe 'some stuff which requires js', :
|
|
184
|
+
describe 'some stuff which requires js', js: true do
|
|
165
185
|
it 'will use the default js driver'
|
|
166
186
|
it 'will switch to one specific driver', :driver => :webkit
|
|
167
187
|
end
|
|
@@ -172,26 +192,26 @@ Capybara also comes with a built in DSL for creating descriptive acceptance test
|
|
|
172
192
|
```ruby
|
|
173
193
|
feature "Signing in" do
|
|
174
194
|
background do
|
|
175
|
-
User.make(:
|
|
195
|
+
User.make(email: 'user@example.com', password: 'caplin')
|
|
176
196
|
end
|
|
177
197
|
|
|
178
198
|
scenario "Signing in with correct credentials" do
|
|
179
199
|
visit '/sessions/new'
|
|
180
200
|
within("#session") do
|
|
181
|
-
fill_in 'Email', :
|
|
182
|
-
fill_in 'Password', :
|
|
201
|
+
fill_in 'Email', with: 'user@example.com'
|
|
202
|
+
fill_in 'Password', with: 'caplin'
|
|
183
203
|
end
|
|
184
204
|
click_button 'Sign in'
|
|
185
205
|
expect(page).to have_content 'Success'
|
|
186
206
|
end
|
|
187
207
|
|
|
188
|
-
given(:other_user) { User.make(:
|
|
208
|
+
given(:other_user) { User.make(email: 'other@example.com', password: 'rous') }
|
|
189
209
|
|
|
190
210
|
scenario "Signing in as another user" do
|
|
191
211
|
visit '/sessions/new'
|
|
192
212
|
within("#session") do
|
|
193
|
-
fill_in 'Email', :
|
|
194
|
-
fill_in 'Password', :
|
|
213
|
+
fill_in 'Email', with: other_user.email
|
|
214
|
+
fill_in 'Password', with: other_user.password
|
|
195
215
|
end
|
|
196
216
|
click_button 'Sign in'
|
|
197
217
|
expect(page).to have_content 'Invalid email or password'
|
|
@@ -217,16 +237,49 @@ RSpec.describe "todos/show.html.erb", type: :view do
|
|
|
217
237
|
end
|
|
218
238
|
```
|
|
219
239
|
|
|
220
|
-
|
|
240
|
+
**Note: When you require 'capybara/rspec' proxy methods are installed to work around name collisions between Capybara::DSL methods
|
|
241
|
+
`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'**
|
|
242
|
+
|
|
243
|
+
## <a name="using-capybara-with-testunit"></a>Using Capybara with Test::Unit
|
|
244
|
+
|
|
245
|
+
* If you are using `Test::Unit`, define a base class for your Capybara tests
|
|
246
|
+
like so:
|
|
247
|
+
|
|
248
|
+
```ruby
|
|
249
|
+
require 'capybara/dsl'
|
|
250
|
+
|
|
251
|
+
class CapybaraTestCase < Test::Unit::TestCase
|
|
252
|
+
include Capybara::DSL
|
|
253
|
+
|
|
254
|
+
def teardown
|
|
255
|
+
Capybara.reset_sessions!
|
|
256
|
+
Capybara.use_default_driver
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## <a name="using-capybara-with-minitest"></a>Using Capybara with Minitest
|
|
221
262
|
|
|
222
263
|
* If you are using Rails, add the following code in your `test_helper.rb`
|
|
223
264
|
file to make Capybara available in all test cases deriving from
|
|
224
265
|
`ActionDispatch::IntegrationTest`:
|
|
225
266
|
|
|
226
267
|
```ruby
|
|
268
|
+
require 'capybara/rails'
|
|
269
|
+
require 'capybara/minitest'
|
|
270
|
+
|
|
227
271
|
class ActionDispatch::IntegrationTest
|
|
228
272
|
# Make the Capybara DSL available in all integration tests
|
|
229
273
|
include Capybara::DSL
|
|
274
|
+
# Make `assert_*` methods behave like Minitest assertions
|
|
275
|
+
include Capybara::Minitest::Assertions
|
|
276
|
+
|
|
277
|
+
# Reset sessions and driver between tests
|
|
278
|
+
# Use super wherever this method is redefined in your individual test classes
|
|
279
|
+
def teardown
|
|
280
|
+
Capybara.reset_sessions!
|
|
281
|
+
Capybara.use_default_driver
|
|
282
|
+
end
|
|
230
283
|
end
|
|
231
284
|
```
|
|
232
285
|
|
|
@@ -234,8 +287,11 @@ end
|
|
|
234
287
|
so:
|
|
235
288
|
|
|
236
289
|
```ruby
|
|
237
|
-
|
|
290
|
+
require 'capybara/minitest'
|
|
291
|
+
|
|
292
|
+
class CapybaraTestCase < Minitest::Test
|
|
238
293
|
include Capybara::DSL
|
|
294
|
+
include Capybara::Minitest::Assertions
|
|
239
295
|
|
|
240
296
|
def teardown
|
|
241
297
|
Capybara.reset_sessions!
|
|
@@ -261,24 +317,19 @@ class BlogTest < ActionDispatch::IntegrationTest
|
|
|
261
317
|
end
|
|
262
318
|
```
|
|
263
319
|
|
|
264
|
-
## Using Capybara with
|
|
320
|
+
## <a name="using-capybara-with-minitestspec"></a>Using Capybara with Minitest::Spec
|
|
265
321
|
|
|
266
|
-
|
|
267
|
-
could be something other than ActionDispatch::IntegrationTest.)
|
|
268
|
-
|
|
269
|
-
The capybara_minitest_spec gem ([GitHub](https://github.com/ordinaryzelig/capybara_minitest_spec),
|
|
270
|
-
[rubygems.org](https://rubygems.org/gems/capybara_minitest_spec)) provides MiniTest::Spec
|
|
271
|
-
expectations for Capybara. For example:
|
|
322
|
+
Follow the above instructions for Minitest and additionally require capybara/minitest/spec
|
|
272
323
|
|
|
273
324
|
```ruby
|
|
274
325
|
page.must_have_content('Important!')
|
|
275
326
|
```
|
|
276
327
|
|
|
277
|
-
## Drivers
|
|
328
|
+
## <a name="drivers"></a>Drivers
|
|
278
329
|
|
|
279
330
|
Capybara uses the same DSL to drive a variety of browser and headless drivers.
|
|
280
331
|
|
|
281
|
-
### Selecting the Driver
|
|
332
|
+
### <a name="selecting-the-driver"></a>Selecting the Driver
|
|
282
333
|
|
|
283
334
|
By default, Capybara uses the `:rack_test` driver, which is fast but limited: it
|
|
284
335
|
does not support JavaScript, nor is it able to access HTTP resources outside of
|
|
@@ -287,12 +338,12 @@ these limitations, you can set up a different default driver for your features.
|
|
|
287
338
|
For example if you'd prefer to run everything in Selenium, you could do:
|
|
288
339
|
|
|
289
340
|
```ruby
|
|
290
|
-
Capybara.default_driver = :selenium
|
|
341
|
+
Capybara.default_driver = :selenium # :selenium_chrome and :selenium_chrome_headless are also registered
|
|
291
342
|
```
|
|
292
343
|
|
|
293
344
|
However, if you are using RSpec or Cucumber, you may instead want to consider
|
|
294
345
|
leaving the faster `:rack_test` as the __default_driver__, and marking only those
|
|
295
|
-
tests that require a JavaScript-capable driver using
|
|
346
|
+
tests that require a JavaScript-capable driver using `js: true` or
|
|
296
347
|
`@javascript`, respectively. By default, JavaScript tests are run using the
|
|
297
348
|
`:selenium` driver. You can change this by setting
|
|
298
349
|
`Capybara.javascript_driver`.
|
|
@@ -309,7 +360,7 @@ Capybara.use_default_driver # switch back to default driver
|
|
|
309
360
|
**Note**: switching the driver creates a new session, so you may not be able to
|
|
310
361
|
switch in the middle of a test.
|
|
311
362
|
|
|
312
|
-
### RackTest
|
|
363
|
+
### <a name="racktest"></a>RackTest
|
|
313
364
|
|
|
314
365
|
RackTest is Capybara's default driver. It is written in pure Ruby and does not
|
|
315
366
|
have any support for executing JavaScript. Since the RackTest driver interacts
|
|
@@ -328,15 +379,15 @@ RackTest can be configured with a set of headers like this:
|
|
|
328
379
|
|
|
329
380
|
```ruby
|
|
330
381
|
Capybara.register_driver :rack_test do |app|
|
|
331
|
-
Capybara::RackTest::Driver.new(app, :
|
|
382
|
+
Capybara::RackTest::Driver.new(app, headers: { 'HTTP_USER_AGENT' => 'Capybara' })
|
|
332
383
|
end
|
|
333
384
|
```
|
|
334
385
|
|
|
335
386
|
See the section on adding and configuring drivers.
|
|
336
387
|
|
|
337
|
-
### Selenium
|
|
388
|
+
### <a name="selenium"></a>Selenium
|
|
338
389
|
|
|
339
|
-
At the moment, Capybara supports [Selenium 2.0
|
|
390
|
+
At the moment, Capybara supports [Selenium 2.0+
|
|
340
391
|
(Webdriver)](http://seleniumhq.org/docs/01_introducing_selenium.html#selenium-2-aka-selenium-webdriver),
|
|
341
392
|
*not* Selenium RC. In order to use Selenium, you'll need to install the
|
|
342
393
|
`selenium-webdriver` gem, and add it to your Gemfile if you're using bundler.
|
|
@@ -347,7 +398,7 @@ able to start using Selenium right away.
|
|
|
347
398
|
same transaction as your tests, causing data not to be shared between your test
|
|
348
399
|
and test server, see "Transactions and database setup" below.
|
|
349
400
|
|
|
350
|
-
### Capybara-webkit
|
|
401
|
+
### <a name="capybara-webkit"></a>Capybara-webkit
|
|
351
402
|
|
|
352
403
|
The [capybara-webkit driver](https://github.com/thoughtbot/capybara-webkit) is for true headless
|
|
353
404
|
testing. It uses QtWebKit to start a rendering engine process. It can execute JavaScript as well.
|
|
@@ -365,18 +416,18 @@ And you can use it by:
|
|
|
365
416
|
Capybara.javascript_driver = :webkit
|
|
366
417
|
```
|
|
367
418
|
|
|
368
|
-
### Poltergeist
|
|
419
|
+
### <a name="poltergeist"></a>Poltergeist
|
|
369
420
|
|
|
370
|
-
[Poltergeist](https://github.com/
|
|
421
|
+
[Poltergeist](https://github.com/teampoltergeist/poltergeist) is another
|
|
371
422
|
headless driver which integrates Capybara with
|
|
372
423
|
[PhantomJS](http://phantomjs.org/). It is truly headless, so doesn't
|
|
373
424
|
require Xvfb to run on your CI server. It will also detect and report
|
|
374
425
|
any Javascript errors that happen within the page.
|
|
375
426
|
|
|
376
|
-
## The DSL
|
|
427
|
+
## <a name="the-dsl"></a>The DSL
|
|
377
428
|
|
|
378
429
|
*A complete reference is available at
|
|
379
|
-
[rubydoc.info](http://rubydoc.info/github/
|
|
430
|
+
[rubydoc.info](http://rubydoc.info/github/teamcapybara/capybara/master)*.
|
|
380
431
|
|
|
381
432
|
**Note: By default Capybara will only locate visible elements. This is because
|
|
382
433
|
a real user would not be able to interact with non-visible elements.**
|
|
@@ -384,10 +435,10 @@ any Javascript errors that happen within the page.
|
|
|
384
435
|
**Note**: All searches in Capybara are *case sensitive*. This is because
|
|
385
436
|
Capybara heavily uses XPath, which doesn't support case insensitivity.
|
|
386
437
|
|
|
387
|
-
### Navigating
|
|
438
|
+
### <a name="navigating"></a>Navigating
|
|
388
439
|
|
|
389
440
|
You can use the
|
|
390
|
-
<tt>[visit](http://rubydoc.info/github/
|
|
441
|
+
<tt>[visit](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session#visit-instance_method)</tt>
|
|
391
442
|
method to navigate to other pages:
|
|
392
443
|
|
|
393
444
|
```ruby
|
|
@@ -398,16 +449,21 @@ visit(post_comments_path(post))
|
|
|
398
449
|
The visit method only takes a single parameter, the request method is **always**
|
|
399
450
|
GET.
|
|
400
451
|
|
|
401
|
-
You can get the [current path](http://rubydoc.info/github/
|
|
402
|
-
of the browsing session
|
|
452
|
+
You can get the [current path](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session#current_path-instance_method)
|
|
453
|
+
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:
|
|
403
454
|
|
|
404
455
|
```ruby
|
|
405
|
-
expect(
|
|
456
|
+
expect(page).to have_current_path(post_comments_path(post))
|
|
406
457
|
```
|
|
407
458
|
|
|
408
|
-
|
|
459
|
+
**Note**: You can also assert the current path by testing the value of
|
|
460
|
+
`current_path` directly. However, using the `have_current_path` matcher is
|
|
461
|
+
safer since it uses Capybara's [waiting behaviour](#asynchronous-javascript-ajax-and-friends)
|
|
462
|
+
to ensure that preceding actions (such as a `click_link`) have completed.
|
|
463
|
+
|
|
464
|
+
### <a name="clicking-links-and-buttons"></a>Clicking links and buttons
|
|
409
465
|
|
|
410
|
-
*Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/
|
|
466
|
+
*Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions)*
|
|
411
467
|
|
|
412
468
|
You can interact with the webapp by following links and buttons. Capybara
|
|
413
469
|
automatically follows any redirects, and submits forms associated with buttons.
|
|
@@ -420,35 +476,35 @@ click_on('Link Text') # clicks on either links or buttons
|
|
|
420
476
|
click_on('Button Value')
|
|
421
477
|
```
|
|
422
478
|
|
|
423
|
-
### Interacting with forms
|
|
479
|
+
### <a name="interacting-with-forms"></a>Interacting with forms
|
|
424
480
|
|
|
425
|
-
*Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/
|
|
481
|
+
*Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions)*
|
|
426
482
|
|
|
427
483
|
There are a number of tools for interacting with form elements:
|
|
428
484
|
|
|
429
485
|
```ruby
|
|
430
|
-
fill_in('First Name', :
|
|
431
|
-
fill_in('Password', :
|
|
432
|
-
fill_in('Description', :
|
|
486
|
+
fill_in('First Name', with: 'John')
|
|
487
|
+
fill_in('Password', with: 'Seekrit')
|
|
488
|
+
fill_in('Description', with: 'Really Long Text...')
|
|
433
489
|
choose('A Radio Button')
|
|
434
490
|
check('A Checkbox')
|
|
435
491
|
uncheck('A Checkbox')
|
|
436
492
|
attach_file('Image', '/path/to/image.jpg')
|
|
437
|
-
select('Option', :
|
|
493
|
+
select('Option', from: 'Select Box')
|
|
438
494
|
```
|
|
439
495
|
|
|
440
|
-
### Querying
|
|
496
|
+
### <a name="querying"></a>Querying
|
|
441
497
|
|
|
442
|
-
*Full reference: [Capybara::Node::Matchers](http://rubydoc.info/github/
|
|
498
|
+
*Full reference: [Capybara::Node::Matchers](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Matchers)*
|
|
443
499
|
|
|
444
500
|
Capybara has a rich set of options for querying the page for the existence of
|
|
445
501
|
certain elements, and working with and manipulating those elements.
|
|
446
502
|
|
|
447
503
|
```ruby
|
|
448
504
|
page.has_selector?('table tr')
|
|
449
|
-
page.has_selector?(:xpath, '
|
|
505
|
+
page.has_selector?(:xpath, './/table/tr')
|
|
450
506
|
|
|
451
|
-
page.has_xpath?('
|
|
507
|
+
page.has_xpath?('.//table/tr')
|
|
452
508
|
page.has_css?('table tr.foo')
|
|
453
509
|
page.has_content?('foo')
|
|
454
510
|
```
|
|
@@ -460,29 +516,41 @@ You can use these with RSpec's magic matchers:
|
|
|
460
516
|
|
|
461
517
|
```ruby
|
|
462
518
|
expect(page).to have_selector('table tr')
|
|
463
|
-
expect(page).to have_selector(:xpath, '
|
|
519
|
+
expect(page).to have_selector(:xpath, './/table/tr')
|
|
464
520
|
|
|
465
|
-
expect(page).to have_xpath('
|
|
521
|
+
expect(page).to have_xpath('.//table/tr')
|
|
466
522
|
expect(page).to have_css('table tr.foo')
|
|
467
523
|
expect(page).to have_content('foo')
|
|
468
524
|
```
|
|
469
525
|
|
|
470
|
-
### Finding
|
|
526
|
+
### <a name="finding"></a>Finding
|
|
471
527
|
|
|
472
|
-
_Full reference: [Capybara::Node::Finders](http://rubydoc.info/github/
|
|
528
|
+
_Full reference: [Capybara::Node::Finders](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders)_
|
|
473
529
|
|
|
474
530
|
You can also find specific elements, in order to manipulate them:
|
|
475
531
|
|
|
476
532
|
```ruby
|
|
477
533
|
find_field('First Name').value
|
|
534
|
+
find_field(id: 'my_field').value
|
|
478
535
|
find_link('Hello', :visible => :all).visible?
|
|
536
|
+
find_link(class: ['some_class', 'some_other_class'], :visible => :all).visible?
|
|
537
|
+
|
|
479
538
|
find_button('Send').click
|
|
539
|
+
find_button(value: '1234').click
|
|
480
540
|
|
|
481
|
-
find(:xpath, "
|
|
541
|
+
find(:xpath, ".//table/tr").click
|
|
482
542
|
find("#overlay").find("h1").click
|
|
483
543
|
all('a').each { |a| a[:href] }
|
|
484
544
|
```
|
|
485
545
|
|
|
546
|
+
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.
|
|
547
|
+
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).
|
|
548
|
+
|
|
549
|
+
```ruby
|
|
550
|
+
find_field('First Name'){ |el| el['data-xyz'] == '123' }
|
|
551
|
+
find("#img_loading"){ |img| img['complete'] == true }
|
|
552
|
+
```
|
|
553
|
+
|
|
486
554
|
**Note**: `find` will wait for an element to appear on the page, as explained in the
|
|
487
555
|
Ajax section. If the element does not appear it will raise an error.
|
|
488
556
|
|
|
@@ -494,21 +562,21 @@ find('#navigation').click_link('Home')
|
|
|
494
562
|
expect(find('#navigation')).to have_button('Sign out')
|
|
495
563
|
```
|
|
496
564
|
|
|
497
|
-
### Scoping
|
|
565
|
+
### <a name="scoping"></a>Scoping
|
|
498
566
|
|
|
499
567
|
Capybara makes it possible to restrict certain actions, such as interacting with
|
|
500
568
|
forms or clicking links and buttons, to within a specific area of the page. For
|
|
501
569
|
this purpose you can use the generic
|
|
502
|
-
<tt>[within](http://rubydoc.info/github/
|
|
570
|
+
<tt>[within](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session#within-instance_method)</tt>
|
|
503
571
|
method. Optionally you can specify which kind of selector to use.
|
|
504
572
|
|
|
505
573
|
```ruby
|
|
506
574
|
within("li#employee") do
|
|
507
|
-
fill_in 'Name', :
|
|
575
|
+
fill_in 'Name', with: 'Jimmy'
|
|
508
576
|
end
|
|
509
577
|
|
|
510
|
-
within(:xpath, "
|
|
511
|
-
fill_in 'Name', :
|
|
578
|
+
within(:xpath, ".//li[@id='employee']") do
|
|
579
|
+
fill_in 'Name', with: 'Jimmy'
|
|
512
580
|
end
|
|
513
581
|
```
|
|
514
582
|
|
|
@@ -518,15 +586,15 @@ specific table, identified by either id or text of the table's caption tag.
|
|
|
518
586
|
|
|
519
587
|
```ruby
|
|
520
588
|
within_fieldset('Employee') do
|
|
521
|
-
fill_in 'Name', :
|
|
589
|
+
fill_in 'Name', with: 'Jimmy'
|
|
522
590
|
end
|
|
523
591
|
|
|
524
592
|
within_table('Employee') do
|
|
525
|
-
fill_in 'Name', :
|
|
593
|
+
fill_in 'Name', with: 'Jimmy'
|
|
526
594
|
end
|
|
527
595
|
```
|
|
528
596
|
|
|
529
|
-
### Working with windows
|
|
597
|
+
### <a name="working-with-windows"></a>Working with windows
|
|
530
598
|
|
|
531
599
|
Capybara provides some methods to ease finding and switching windows:
|
|
532
600
|
|
|
@@ -541,7 +609,7 @@ within_window facebook_window do
|
|
|
541
609
|
end
|
|
542
610
|
```
|
|
543
611
|
|
|
544
|
-
### Scripting
|
|
612
|
+
### <a name="scripting"></a>Scripting
|
|
545
613
|
|
|
546
614
|
In drivers which support it, you can easily execute JavaScript:
|
|
547
615
|
|
|
@@ -556,7 +624,7 @@ that this may break with more complicated expressions:
|
|
|
556
624
|
result = page.evaluate_script('4 + 4');
|
|
557
625
|
```
|
|
558
626
|
|
|
559
|
-
### Modals
|
|
627
|
+
### <a name="modals"></a>Modals
|
|
560
628
|
|
|
561
629
|
In drivers which support it, you can accept, dismiss and respond to alerts, confirms and prompts.
|
|
562
630
|
|
|
@@ -594,7 +662,7 @@ end
|
|
|
594
662
|
expect(message).to eq('Who is the chief architect of Linux?')
|
|
595
663
|
```
|
|
596
664
|
|
|
597
|
-
### Debugging
|
|
665
|
+
### <a name="debugging"></a>Debugging
|
|
598
666
|
|
|
599
667
|
It can be useful to take a snapshot of the page as it currently is and take a
|
|
600
668
|
look at it:
|
|
@@ -604,7 +672,7 @@ save_and_open_page
|
|
|
604
672
|
```
|
|
605
673
|
|
|
606
674
|
You can also retrieve the current state of the DOM as a string using
|
|
607
|
-
<tt>[page.html](http://rubydoc.info/github/
|
|
675
|
+
<tt>[page.html](http://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Session#html-instance_method)</tt>.
|
|
608
676
|
|
|
609
677
|
```ruby
|
|
610
678
|
print page.html
|
|
@@ -625,12 +693,16 @@ Or have it save and automatically open:
|
|
|
625
693
|
save_and_open_screenshot
|
|
626
694
|
```
|
|
627
695
|
|
|
628
|
-
|
|
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
|
+
|
|
700
|
+
## <a name="matching"></a>Matching
|
|
629
701
|
|
|
630
702
|
It is possible to customize how Capybara finds elements. At your disposal
|
|
631
703
|
are two options, `Capybara.exact` and `Capybara.match`.
|
|
632
704
|
|
|
633
|
-
### Exactness
|
|
705
|
+
### <a name="exactness"></a>Exactness
|
|
634
706
|
|
|
635
707
|
`Capybara.exact` and the `exact` option work together with the `is` expression
|
|
636
708
|
inside the XPath gem. When `exact` is true, all `is` expressions match exactly,
|
|
@@ -647,7 +719,7 @@ click_link("Password") # does not match "Password confirmation"
|
|
|
647
719
|
click_link("Password", exact: false) # can be overridden
|
|
648
720
|
```
|
|
649
721
|
|
|
650
|
-
### Strategy
|
|
722
|
+
### <a name="strategy"></a>Strategy
|
|
651
723
|
|
|
652
724
|
Using `Capybara.match` and the equivalent `match` option, you can control how
|
|
653
725
|
Capybara behaves when multiple elements all match a query. There are currently
|
|
@@ -668,7 +740,10 @@ The default for `Capybara.match` is `:smart`. To emulate the behaviour in
|
|
|
668
740
|
Capybara 2.0.x, set `Capybara.match` to `:one`. To emulate the behaviour in
|
|
669
741
|
Capybara 1.x, set `Capybara.match` to `:prefer_exact`.
|
|
670
742
|
|
|
671
|
-
## Transactions and database setup
|
|
743
|
+
## <a name="transactions-and-database-setup"></a>Transactions and database setup
|
|
744
|
+
|
|
745
|
+
**Note:** Rails 5.1+ now "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.
|
|
672
747
|
|
|
673
748
|
Some Capybara drivers need to run against an actual HTTP server. Capybara takes
|
|
674
749
|
care of this and starts one for you in the same process as your test, but on
|
|
@@ -682,26 +757,9 @@ your test code to be invisible to Capybara.
|
|
|
682
757
|
|
|
683
758
|
Cucumber handles this by using truncation instead of transactions, i.e. they
|
|
684
759
|
empty out the entire database after each test. You can get the same behaviour
|
|
685
|
-
by using a gem such as [database_cleaner](https://github.com/
|
|
760
|
+
by using a gem such as [database_cleaner](https://github.com/DatabaseCleaner/database_cleaner).
|
|
686
761
|
|
|
687
|
-
|
|
688
|
-
threads. This may have thread safety implications and could cause strange
|
|
689
|
-
failures, so use caution with this approach. It can be implemented in
|
|
690
|
-
ActiveRecord through the following monkey patch:
|
|
691
|
-
|
|
692
|
-
```ruby
|
|
693
|
-
class ActiveRecord::Base
|
|
694
|
-
mattr_accessor :shared_connection
|
|
695
|
-
@@shared_connection = nil
|
|
696
|
-
|
|
697
|
-
def self.connection
|
|
698
|
-
@@shared_connection || retrieve_connection
|
|
699
|
-
end
|
|
700
|
-
end
|
|
701
|
-
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
|
|
702
|
-
```
|
|
703
|
-
|
|
704
|
-
## Asynchronous JavaScript (Ajax and friends)
|
|
762
|
+
## <a name="asynchronous-javascript-ajax-and-friends"></a>Asynchronous JavaScript (Ajax and friends)
|
|
705
763
|
|
|
706
764
|
When working with asynchronous JavaScript, you might come across situations
|
|
707
765
|
where you are attempting to interact with an element which is not yet present
|
|
@@ -741,7 +799,7 @@ The former would immediately fail because the content has not yet been removed.
|
|
|
741
799
|
Only the latter would wait for the asynchronous process to remove the content
|
|
742
800
|
from the page.
|
|
743
801
|
|
|
744
|
-
Capybara's
|
|
802
|
+
Capybara's RSpec matchers, however, are smart enough to handle either form.
|
|
745
803
|
The two following statements are functionally equivalent:
|
|
746
804
|
|
|
747
805
|
```ruby
|
|
@@ -763,13 +821,12 @@ the text of the `h1` to "Something", and this happened, this test would
|
|
|
763
821
|
pass. If you do not want this behaviour, you can set
|
|
764
822
|
`Capybara.automatic_reload` to `false`.
|
|
765
823
|
|
|
766
|
-
## Using the DSL elsewhere
|
|
824
|
+
## <a name="using-the-dsl-elsewhere"></a>Using the DSL elsewhere
|
|
767
825
|
|
|
768
826
|
You can mix the DSL into any context by including <tt>Capybara::DSL</tt>:
|
|
769
827
|
|
|
770
828
|
|
|
771
829
|
```ruby
|
|
772
|
-
require 'capybara'
|
|
773
830
|
require 'capybara/dsl'
|
|
774
831
|
|
|
775
832
|
Capybara.default_driver = :webkit
|
|
@@ -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
|
|
@@ -789,7 +846,7 @@ end
|
|
|
789
846
|
|
|
790
847
|
This enables its use in unsupported testing frameworks, and for general-purpose scripting.
|
|
791
848
|
|
|
792
|
-
## Calling remote servers
|
|
849
|
+
## <a name="calling-remote-servers"></a>Calling remote servers
|
|
793
850
|
|
|
794
851
|
Normally Capybara expects to be testing an in-process Rack application, but you
|
|
795
852
|
can also use it to talk to a web server running anywhere on the internet, by
|
|
@@ -818,40 +875,61 @@ remote application:
|
|
|
818
875
|
Capybara.run_server = false
|
|
819
876
|
```
|
|
820
877
|
|
|
821
|
-
## 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
|
```
|
|
837
915
|
|
|
838
|
-
## XPath, CSS and selectors
|
|
916
|
+
## <a name="xpath-css-and-selectors"></a>XPath, CSS and selectors
|
|
839
917
|
|
|
840
918
|
Capybara does not try to guess what kind of selector you are going to give it,
|
|
841
919
|
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
935
|
Capybara allows you to add custom selectors, which can be very useful if you
|
|
@@ -881,7 +959,7 @@ find(:row, 3)
|
|
|
881
959
|
find(:flash_type, :notice)
|
|
882
960
|
```
|
|
883
961
|
|
|
884
|
-
## Beware the XPath // trap
|
|
962
|
+
## <a name="beware-the-xpath--trap"></a>Beware the XPath // trap
|
|
885
963
|
|
|
886
964
|
In XPath the expression // means something very specific, and it might not be what
|
|
887
965
|
you think. Contrary to common belief, // means "anywhere in the document" not "anywhere
|
|
@@ -909,7 +987,7 @@ within(:xpath, '//body') do
|
|
|
909
987
|
end
|
|
910
988
|
```
|
|
911
989
|
|
|
912
|
-
## Configuring and adding drivers
|
|
990
|
+
## <a name="configuring-and-adding-drivers"></a>Configuring and adding drivers
|
|
913
991
|
|
|
914
992
|
Capybara makes it convenient to switch between different drivers. It also exposes
|
|
915
993
|
an API to tweak those drivers with whatever settings you want, or to add your own
|
|
@@ -938,10 +1016,10 @@ Whatever is returned from the block should conform to the API described by
|
|
|
938
1016
|
Capybara::Driver::Base, it does not however have to inherit from this class.
|
|
939
1017
|
Gems can use this API to add their own drivers to Capybara.
|
|
940
1018
|
|
|
941
|
-
The [Selenium wiki](
|
|
1019
|
+
The [Selenium wiki](https://github.com/SeleniumHQ/selenium/wiki/Ruby-Bindings) has
|
|
942
1020
|
additional info about how the underlying driver can be configured.
|
|
943
1021
|
|
|
944
|
-
## Gotchas:
|
|
1022
|
+
## <a name="gotchas"></a>Gotchas:
|
|
945
1023
|
|
|
946
1024
|
* Access to session and request is not possible from the test, Access to
|
|
947
1025
|
response is limited. Some drivers allow access to response headers and HTTP
|
|
@@ -957,7 +1035,7 @@ additional info about how the underlying driver can be configured.
|
|
|
957
1035
|
since Capybara's Ajax timing uses the system time, resulting in Capybara
|
|
958
1036
|
never timing out and just hanging when a failure occurs. It's still possible to
|
|
959
1037
|
use gems which allow you to travel in time, rather than freeze time.
|
|
960
|
-
One such gem is [Timecop](
|
|
1038
|
+
One such gem is [Timecop](https://github.com/travisjeffery/timecop).
|
|
961
1039
|
|
|
962
1040
|
* When using Rack::Test, beware if attempting to visit absolute URLs. For
|
|
963
1041
|
example, a session might not be shared between visits to `posts_path`
|
|
@@ -969,7 +1047,36 @@ additional info about how the underlying driver can be configured.
|
|
|
969
1047
|
are testing for specific server errors and using multiple sessions make sure to test for the
|
|
970
1048
|
errors using the initial session (usually :default)
|
|
971
1049
|
|
|
972
|
-
##
|
|
1050
|
+
## <a name="threadsafe"></a>"Threadsafe" mode - BETA - may change
|
|
1051
|
+
|
|
1052
|
+
In normal mode most of Capybara's configuration options are global settings which can cause issues
|
|
1053
|
+
if using multiple sessions and wanting to change a setting for only one of the sessions. To provide
|
|
1054
|
+
support for this type of usage Capybara now provides a "threadsafe" mode which can be enabled by setting
|
|
1055
|
+
|
|
1056
|
+
```ruby
|
|
1057
|
+
Capybara.threadsafe = true
|
|
1058
|
+
```
|
|
1059
|
+
|
|
1060
|
+
This setting can only be changed before any sessions have been created. In "threadsafe" mode the following
|
|
1061
|
+
behaviors of Capybara change
|
|
1062
|
+
|
|
1063
|
+
* Most options can now be set on a session. These can either be set at session creation time or after, and
|
|
1064
|
+
default to the global options at the time of session creation. Options which are NOT session specific are
|
|
1065
|
+
`app`, `reuse_server`, `default_driver`, `javascript_driver`, and (obviously) `threadsafe`. Any drivers and servers
|
|
1066
|
+
registered through `register_driver` and `register_server` are also global.
|
|
1067
|
+
|
|
1068
|
+
```ruby
|
|
1069
|
+
my_session = Capybara::Session.new(:driver, some_app) do |config|
|
|
1070
|
+
config.automatic_label_click = true # only set for my_session
|
|
1071
|
+
end
|
|
1072
|
+
my_session.config.default_max_wait_time = 10 # only set for my_session
|
|
1073
|
+
Capybara.default_max_wait_time = 2 # will not change the default_max_wait in my_session
|
|
1074
|
+
```
|
|
1075
|
+
|
|
1076
|
+
* `current_driver` and `session_name` are thread specific. This means that `using_session` and
|
|
1077
|
+
`using_driver` also only affect the current thread.
|
|
1078
|
+
|
|
1079
|
+
## <a name="development"></a>Development
|
|
973
1080
|
|
|
974
1081
|
To set up a development environment, simply do:
|
|
975
1082
|
|
|
@@ -979,5 +1086,5 @@ bundle exec rake # run the test suite
|
|
|
979
1086
|
```
|
|
980
1087
|
|
|
981
1088
|
See
|
|
982
|
-
[CONTRIBUTING.md](https://github.com/
|
|
1089
|
+
[CONTRIBUTING.md](https://github.com/teamcapybara/capybara/blob/master/CONTRIBUTING.md)
|
|
983
1090
|
for how to send issues and pull requests.
|