capybara 2.5.0 → 2.18.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Build Status](https://secure.travis-ci.org/
|
4
|
-
[![Dependency Status](https://gemnasium.com/
|
5
|
-
[![Code Climate](https://codeclimate.com/github/
|
3
|
+
[![Build Status](https://secure.travis-ci.org/teamcapybara/capybara.svg)](https://travis-ci.org/teamcapybara/capybara)
|
4
|
+
[![Dependency Status](https://gemnasium.com/teamcapybara/capybara.svg)](https://gemnasium.com/teamcapybara/capybara)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/teamcapybara/capybara.svg)](https://codeclimate.com/github/teamcapybara/capybara)
|
6
|
+
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jnicklas/capybara?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
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.
|