capybara 1.1.4 → 2.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/History.txt +100 -0
  2. data/License.txt +22 -0
  3. data/README.md +829 -0
  4. data/lib/capybara.rb +124 -6
  5. data/lib/capybara/cucumber.rb +2 -5
  6. data/lib/capybara/driver/base.rb +5 -5
  7. data/lib/capybara/driver/node.rb +2 -2
  8. data/lib/capybara/dsl.rb +3 -121
  9. data/lib/capybara/node/actions.rb +12 -28
  10. data/lib/capybara/node/base.rb +5 -13
  11. data/lib/capybara/node/element.rb +21 -21
  12. data/lib/capybara/node/finders.rb +27 -89
  13. data/lib/capybara/node/matchers.rb +107 -69
  14. data/lib/capybara/node/simple.rb +11 -13
  15. data/lib/capybara/query.rb +78 -0
  16. data/lib/capybara/rack_test/browser.rb +16 -27
  17. data/lib/capybara/rack_test/driver.rb +11 -1
  18. data/lib/capybara/rack_test/node.rb +17 -1
  19. data/lib/capybara/result.rb +84 -0
  20. data/lib/capybara/rspec/matchers.rb +28 -63
  21. data/lib/capybara/selector.rb +97 -33
  22. data/lib/capybara/selenium/driver.rb +14 -61
  23. data/lib/capybara/selenium/node.rb +6 -15
  24. data/lib/capybara/server.rb +32 -27
  25. data/lib/capybara/session.rb +54 -30
  26. data/lib/capybara/spec/public/jquery-ui.js +791 -0
  27. data/lib/capybara/spec/public/jquery.js +9046 -0
  28. data/lib/capybara/spec/public/test.js +4 -1
  29. data/lib/capybara/spec/session.rb +56 -27
  30. data/lib/capybara/spec/session/all_spec.rb +8 -4
  31. data/lib/capybara/spec/session/attach_file_spec.rb +12 -9
  32. data/lib/capybara/spec/session/check_spec.rb +6 -3
  33. data/lib/capybara/spec/session/choose_spec.rb +4 -1
  34. data/lib/capybara/spec/session/click_button_spec.rb +5 -14
  35. data/lib/capybara/spec/session/click_link_or_button_spec.rb +2 -1
  36. data/lib/capybara/spec/session/click_link_spec.rb +3 -17
  37. data/lib/capybara/spec/session/current_url_spec.rb +77 -9
  38. data/lib/capybara/spec/session/fill_in_spec.rb +8 -18
  39. data/lib/capybara/spec/session/find_spec.rb +19 -46
  40. data/lib/capybara/spec/session/first_spec.rb +2 -34
  41. data/lib/capybara/spec/session/has_css_spec.rb +1 -1
  42. data/lib/capybara/spec/session/has_field_spec.rb +28 -0
  43. data/lib/capybara/spec/session/has_select_spec.rb +84 -31
  44. data/lib/capybara/spec/session/has_table_spec.rb +7 -69
  45. data/lib/capybara/spec/session/has_text_spec.rb +168 -0
  46. data/lib/capybara/spec/session/javascript.rb +65 -81
  47. data/lib/capybara/spec/session/node_spec.rb +115 -0
  48. data/lib/capybara/spec/session/screenshot.rb +29 -0
  49. data/lib/capybara/spec/session/select_spec.rb +12 -12
  50. data/lib/capybara/spec/session/text_spec.rb +9 -4
  51. data/lib/capybara/spec/session/unselect_spec.rb +12 -6
  52. data/lib/capybara/spec/session/visit_spec.rb +76 -0
  53. data/lib/capybara/spec/session/within_frame_spec.rb +33 -0
  54. data/lib/capybara/spec/session/within_spec.rb +47 -58
  55. data/lib/capybara/spec/session/within_window_spec.rb +40 -0
  56. data/lib/capybara/spec/test_app.rb +27 -3
  57. data/lib/capybara/spec/views/form.erb +11 -10
  58. data/lib/capybara/spec/views/host_links.erb +2 -2
  59. data/lib/capybara/spec/views/tables.erb +6 -66
  60. data/lib/capybara/spec/views/with_html.erb +3 -3
  61. data/lib/capybara/spec/views/with_js.erb +11 -8
  62. data/lib/capybara/util/save_and_open_page.rb +4 -3
  63. data/lib/capybara/version.rb +1 -1
  64. data/spec/basic_node_spec.rb +15 -3
  65. data/spec/dsl_spec.rb +12 -10
  66. data/spec/rack_test_spec.rb +152 -0
  67. data/spec/rspec/features_spec.rb +0 -2
  68. data/spec/rspec/matchers_spec.rb +164 -89
  69. data/spec/rspec_spec.rb +0 -2
  70. data/spec/selenium_spec.rb +67 -0
  71. data/spec/server_spec.rb +35 -23
  72. data/spec/spec_helper.rb +18 -2
  73. metadata +30 -30
  74. data/README.rdoc +0 -722
  75. data/lib/capybara/spec/driver.rb +0 -301
  76. data/lib/capybara/spec/session/current_host_spec.rb +0 -68
  77. data/lib/capybara/spec/session/has_content_spec.rb +0 -106
  78. data/lib/capybara/util/timeout.rb +0 -27
  79. data/spec/driver/rack_test_driver_spec.rb +0 -89
  80. data/spec/driver/selenium_driver_spec.rb +0 -37
  81. data/spec/session/rack_test_session_spec.rb +0 -55
  82. data/spec/session/selenium_session_spec.rb +0 -26
  83. data/spec/string_spec.rb +0 -77
  84. data/spec/timeout_spec.rb +0 -28
@@ -1,3 +1,103 @@
1
+ # master
2
+
3
+ ### Changed
4
+
5
+ * `respect_data_method` default to `false` for the RackTest driver, which means
6
+ that Capybara no longer picks up `:method => :post` et. al. from links in Rails
7
+ by default. [Jonas Nicklas]
8
+ * `find` now raises an error if more than one element was found. Since `find` is
9
+ used by most actions, like `click_link` under the surface, this means that all
10
+ actions need to unambiguous in the future. [Jonas Nicklas]
11
+ * `Element#text` on RackTest now only returns visible text and normalizes
12
+ (strips) whitespace, as with Selenium [Mark Dodwell, Jo Liss]
13
+ * `has_content?` now checks the text value returned by `Element#text`, as opposed to
14
+ querying the DOM. Which means it does not match hidden text.
15
+ [Ryan Montgomery, Mark Dodwell, Jo Liss]
16
+ * #394: `#body` now returns the unmodified source (like `#source`), not the current
17
+ state of the DOM (like `#html`), by popular request [Jonas Nicklas]
18
+ * `Node#all` no longer returns an array, but rather an enumerable `Capybara::Result`
19
+ [Jonas Nicklas]
20
+ * The arguments to `select` and `unselect` needs to be the exact text of an option
21
+ in a select box, substrings are no longer allowed [Jonas Nicklas]
22
+ * The `options` option to `has_select?` must match the exact set of options. Use
23
+ `with_options` for the old behaviour. [Gonzalo Rodriguez]
24
+ * The `selected` option to `has_select?` must match all selected options for multiple
25
+ selects. [Gonzalo Rodriguez]
26
+ * Various internals for running driver specs, this should only affect driver authors
27
+ [Jonas Nicklas]
28
+
29
+ ### Removed
30
+
31
+ * No longer possible to specify `failure_message` for custom selectors. [Jonas Nicklas]
32
+ * #589: `Capybara.server_boot_timeout` has been removed in favor of a higher
33
+ (60-second) hard-coded timeout [Jo Liss]
34
+ * `Capybara.prefer_visible_elements` has been removed, as it is no longer needed
35
+ with the changed find semantics [Jonas Nicklas]
36
+ * `Node#wait_until` and `Session#wait_until` have been removed. See `Node#synchronize`
37
+ for an alternative [Jonas Nicklas]
38
+ * `Capybara.timeout` has been removed [Jonas Nicklas]
39
+ * The `:resynchronize` option has been removed from the Selenium driver [Jonas Nicklas]
40
+ * The `rows` option to `has_table?` has been removed without replacement.
41
+ [Jonas Nicklas]
42
+
43
+ ### Fixed
44
+
45
+ * Nodes found via `all` are no longer reloaded. This fixes weird quirks where
46
+ nodes would seemingly randomly replace themselves with other nodes [Jonas Nicklas]
47
+ * Session is only reset if it has been modified, dramatically improves performance if
48
+ only part of the test suite runs Capybara. [Jonas Nicklas]
49
+ * Test suite now passes on Ruby 1.8 [Jo Liss]
50
+ * #565: `require 'capybara/dsl'` is no longer necessary [Jo Liss]
51
+ * `Rack::Test` now respects ports when changing hosts [Jo Liss]
52
+ * #603: `Rack::Test` now preserves the original referer URL when following a
53
+ redirect [Rob van Dijk]
54
+ * Rack::Test now does not send a referer when calling `visit` multiple times
55
+ [Jo Liss]
56
+ * Exceptions during server boot now propagate to main thread [James Tucker]
57
+ * RSpec integration now cleans up before the test instead of after [Darwin]
58
+ * If `respect_data_method` is true, the data-method attribute can be capitalized
59
+ [Marco Antonio]
60
+ * Rack app boot timing out raises an error as opposed to just logging to STDOUT
61
+ [Adrian Irving-Beer]
62
+ * `#source` returns an empty string instead of nil if no pages have been visited
63
+ [Jonas Nicklas]
64
+ * Ignore first leading newline in textareas in RackTest [Vitalii Khustochka]
65
+ * `within_frame` returns the value of the given block [Alistair Hutchison]
66
+ * Running `Node.set` on text fields will not trigger more than one change event
67
+ [Andrew Kasper]
68
+ * Throw an error when an option is given to a finder method, like `all` or
69
+ `has_selector?` which Capybara doesn't understand [Jonas Nicklas]
70
+ * Two references to the node now register as equal when comparing them with `==`
71
+ [Jonas Nicklas]
72
+
73
+ ### Added
74
+
75
+ * Much improved error message [Jonas Nicklas]
76
+ * Errors from inside the session for apps running in a server are raised when
77
+ session is reset [James Tucker, Jonas Nicklas]
78
+ * A ton of new selectors built in out of the box, like `field`, `link`, `button`,
79
+ etc... [Adam McCrea, Jonas Nicklas]
80
+ * `has_text`, `has_content` ... [Jonas Nicklas]
81
+ * Add `Capybara.server_host` option (default: 127.0.0.1) [David Balatero]
82
+ * Add `:type` option for `page.has_field?` [Gonzalo Rodríguez]
83
+ * Custom matchers can now be specified in CSS in addition to XPath [Jonas Nicklas]
84
+ * `Node#synchronize` method to rerun a block of code if certain errors are raised
85
+ [Jonas Nicklas]
86
+ * `Capybara.always_include_port` config option always includes the server port in
87
+ URLs when using `visit`. Facilitates testing different domain names`. [Douwe Maan]
88
+ * Redirect limit for RackTest driver is configurable [Josh Lane]
89
+ * Server port can be manually specified during initialization of server.
90
+ [Jonas Nicklas, John Wilger]
91
+ * `has_content?` and `has_text?` can be given a regular expression [Vasiliy Ermolovich]
92
+
93
+ # Version 1.1.2
94
+
95
+ Release date: 2011-11-15
96
+
97
+ ### Fixed
98
+
99
+ * #541: Make attach_file work with selenium-webdriver >=2.12 [Jonas Nicklas]
100
+
1
101
  # Version 1.1.0
2
102
 
3
103
  Release date: 2011-09-02
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2009-2012 Jonas Nicklas
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,829 @@
1
+ # Capybara
2
+
3
+ [![Build Status](https://secure.travis-ci.org/jnicklas/capybara.png)](http://travis-ci.org/jnicklas/capybara)
4
+ [![Dependency Status](https://gemnasium.com/jnicklas/capybara.png)](https://gemnasium.com/jnicklas/capybara)
5
+ [![Code Quality](https://codeclimate.com/badge.png)](https://codeclimate.com/github/jnicklas/capybara)
6
+
7
+ Capybara helps you test Rails and Rack applications by simulating how a real
8
+ user would interact with your app. It is agnostic about the driver running your
9
+ tests and comes with Rack::Test and Selenium support built in. WebKit is
10
+ supported through an external gem.
11
+
12
+ **Need help?** Ask on the mailing list (please do not open an issue on
13
+ GitHub): http://groups.google.com/group/ruby-capybara
14
+
15
+ ## Setup
16
+
17
+ To install, type
18
+
19
+ ```bash
20
+ sudo gem install capybara
21
+ ```
22
+
23
+ If you are using Rails, add this line to your test helper file:
24
+
25
+ ```ruby
26
+ require 'capybara/rails'
27
+ ```
28
+
29
+ If you are not using Rails, set Capybara.app to your rack app:
30
+
31
+ ```ruby
32
+ Capybara.app = MyRackApp
33
+ ```
34
+
35
+ ## Using Capybara with Cucumber
36
+
37
+ The `cucumber-rails` gem comes with Capybara support built-in. If you
38
+ are not using Rails, manually load the `capybara/cucumber` module:
39
+
40
+ ```ruby
41
+ require 'capybara/cucumber'
42
+ Capybara.app = MyRackApp
43
+ ```
44
+
45
+ You can use the Capybara DSL in your steps, like so:
46
+
47
+ ```ruby
48
+ When /I sign in/ do
49
+ within("#session") do
50
+ fill_in 'Login', :with => 'user@example.com'
51
+ fill_in 'Password', :with => 'password'
52
+ end
53
+ click_link 'Sign in'
54
+ end
55
+ ```
56
+
57
+ You can switch to the `Capybara.javascript_driver` (`:selenium`
58
+ by default) by tagging scenarios (or features) with `@javascript`:
59
+
60
+ ```ruby
61
+ @javascript
62
+ Scenario: do something Ajaxy
63
+ When I click the Ajax link
64
+ ...
65
+ ```
66
+
67
+ There are also explicit `@selenium` and `@rack_test`
68
+ tags set up for you.
69
+
70
+ ## Using Capybara with RSpec
71
+
72
+ Load RSpec 2.x support by adding the following line (typically to your
73
+ `spec_helper.rb` file):
74
+
75
+ ```ruby
76
+ require 'capybara/rspec'
77
+ ```
78
+
79
+ If you are using Rails, put your Capybara specs in `spec/requests` or
80
+ `spec/integration`.
81
+
82
+ If you are not using Rails, tag all the example groups in which you want to use
83
+ Capybara with `:type => :request`.
84
+
85
+ You can now write your specs like so:
86
+
87
+ ```ruby
88
+ describe "the signup process", :type => :request do
89
+ before :each do
90
+ User.make(:email => 'user@example.com', :password => 'caplin')
91
+ end
92
+
93
+ it "signs me in" do
94
+ within("#session") do
95
+ fill_in 'Login', :with => 'user@example.com'
96
+ fill_in 'Password', :with => 'password'
97
+ end
98
+ click_link 'Sign in'
99
+ end
100
+ end
101
+ ```
102
+
103
+ Use `:js => true` to switch to the `Capybara.javascript_driver`
104
+ (`:selenium` by default), or provide a `:driver` option to switch
105
+ to one specific driver. For example:
106
+
107
+ ```ruby
108
+ describe 'some stuff which requires js', :js => true do
109
+ it 'will use the default js driver'
110
+ it 'will switch to one specific driver', :driver => :webkit
111
+ end
112
+ ```
113
+
114
+ Finally, Capybara also comes with a built in DSL for creating descriptive acceptance tests:
115
+
116
+ ```ruby
117
+ feature "Signing up" do
118
+ background do
119
+ User.make(:email => 'user@example.com', :password => 'caplin')
120
+ end
121
+
122
+ scenario "Signing in with correct credentials" do
123
+ within("#session") do
124
+ fill_in 'Login', :with => 'user@example.com'
125
+ fill_in 'Password', :with => 'caplin'
126
+ end
127
+ click_link 'Sign in'
128
+ end
129
+ end
130
+ ```
131
+
132
+ `feature` is in fact just an alias for `describe ..., :type => :request`,
133
+ `background` is an alias for `before`, and `scenario` for `it`.
134
+
135
+ ## Using Capybara with Test::Unit
136
+
137
+ * If you are using Rails, add `database_cleaner` to your Gemfile:
138
+
139
+ ```ruby
140
+ group :test do
141
+ gem 'database_cleaner'
142
+ end
143
+ ```
144
+
145
+ Then add the following code in your `test_helper.rb` file to make
146
+ Capybara available in all test cases deriving from
147
+ `ActionDispatch::IntegrationTest`:
148
+
149
+ ```ruby
150
+ # Transactional fixtures do not work with Selenium tests, because Capybara
151
+ # uses a separate server thread, which the transactions would be hidden
152
+ # from. We hence use DatabaseCleaner to truncate our test database.
153
+ DatabaseCleaner.strategy = :truncation
154
+
155
+ class ActionDispatch::IntegrationTest
156
+ # Make the Capybara DSL available in all integration tests
157
+ include Capybara::DSL
158
+
159
+ # Stop ActiveRecord from wrapping tests in transactions
160
+ self.use_transactional_fixtures = false
161
+
162
+ teardown do
163
+ DatabaseCleaner.clean # Truncate the database
164
+ Capybara.reset_sessions! # Forget the (simulated) browser state
165
+ Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
166
+ end
167
+ end
168
+ ```
169
+
170
+ * If you are not using Rails, define a base class for your Capybara tests like
171
+ so:
172
+
173
+ ```ruby
174
+ class CapybaraTestCase < Test::Unit::TestCase
175
+ include Capybara::DSL
176
+
177
+ def teardown
178
+ Capybara.reset_sessions!
179
+ Capybara.use_default_driver
180
+ end
181
+ end
182
+ ```
183
+
184
+ Remember to call `super` in any subclasses that override
185
+ `teardown`.
186
+
187
+ To switch the driver, set `Capybara.current_driver`. For instance,
188
+
189
+ ```ruby
190
+ class BlogTest < ActionDispatch::IntegrationTest
191
+ setup do
192
+ Capybara.current_driver = Capybara.javascript_driver # :selenium by default
193
+ end
194
+
195
+ test 'shows blog posts' do
196
+ # ... this test is run with Selenium ...
197
+ end
198
+ end
199
+ ```
200
+
201
+ ## Using Capybara with MiniTest::Spec
202
+
203
+ Set up your base class as with Test::Unit. (On Rails, the right base class
204
+ could be something other than ActionDispatch::IntegrationTest.)
205
+
206
+ The capybara_minitest_spec gem ([Github](https://github.com/ordinaryzelig/capybara_minitest_spec),
207
+ [rubygems.org](https://rubygems.org/gems/capybara_minitest_spec)) provides MiniTest::Spec
208
+ expectations for Capybara. For example:
209
+
210
+ ```ruby
211
+ page.must_have_content('Important!')
212
+ ```
213
+
214
+ ## Drivers
215
+
216
+ Capybara uses the same DSL to drive a variety of browser and headless drivers.
217
+
218
+ ### Selecting the Driver
219
+
220
+ By default, Capybara uses the `:rack_test` driver, which is fast but does not
221
+ support JavaScript. You can set up a different default driver for your
222
+ features. For example if you'd prefer to run everything in Selenium, you could
223
+ do:
224
+
225
+ ```ruby
226
+ Capybara.default_driver = :selenium
227
+ ```
228
+
229
+ However, if you are using RSpec or Cucumber, you may instead want to consider
230
+ leaving the faster `:rack_test` as the __default_driver__, and marking only those
231
+ tests that require a JavaScript-capable driver using `:js => true` or
232
+ `@javascript`, respectively. By default, JavaScript tests are run using the
233
+ `:selenium` driver. You can change this by setting
234
+ `Capybara.javascript_driver`.
235
+
236
+ You can also change the driver temporarily (typically in the Before/setup and
237
+ After/teardown blocks):
238
+
239
+ ```ruby
240
+ Capybara.current_driver = :webkit # temporarily select different driver
241
+ ... tests ...
242
+ Capybara.use_default_driver # switch back to default driver
243
+ ```
244
+
245
+ **Note**: switching the driver creates a new session, so you may not be able to
246
+ switch in the middle of a test.
247
+
248
+ ### RackTest
249
+
250
+ RackTest is Capybara's default driver. It is written in pure Ruby and does not
251
+ have any support for executing JavaScript. Since the RackTest driver works
252
+ directly against the Rack interface, it does not need any server to be started,
253
+ it can work directly against any Rack app. This means that if your
254
+ application is not a Rack application (Rails, Sinatra and most other Ruby
255
+ frameworks are Rack applications) then you cannot use this driver. You cannot
256
+ use the RackTest driver to test a remote application.
257
+ [capybara-mechanize](https://github.com/jeroenvandijk/capybara-mechanize)
258
+ intends to provide a similar driver which works against remote servers, it is a
259
+ separate project.
260
+
261
+ RackTest can be configured with a set of headers like this:
262
+
263
+ ```ruby
264
+ Capybara.register_driver :rack_test do |app|
265
+ Capybara::RackTest::Driver.new(app, :browser => :chrome)
266
+ end
267
+ ```
268
+
269
+ See the section on adding and configuring drivers.
270
+
271
+ ### Selenium
272
+
273
+ At the moment, Capybara supports [Selenium 2.0
274
+ (Webdriver)](http://seleniumhq.org/docs/01_introducing_selenium.html#selenium-2-aka-selenium-webdriver),
275
+ *not* Selenium RC. Provided Firefox is installed, everything is set up for you,
276
+ and you should be able to start using Selenium right away.
277
+
278
+ **Note**: drivers which run the server in a different thread may not work share the
279
+ same transaction as your tests, causing data not to be shared between your test
280
+ and test server, see "Transactions and database setup" below.
281
+
282
+ ### Capybara-webkit
283
+
284
+ The [capybara-webkit driver](https://github.com/thoughtbot/capybara-webkit) is for true headless
285
+ testing. It uses QtWebKit to start a rendering engine process. It can execute JavaScript as well.
286
+ It is significantly faster than drivers like Selenium since it does not load an entire browser.
287
+
288
+ You can install it with:
289
+
290
+ ```bash
291
+ gem install capybara-webkit
292
+ ```
293
+
294
+ And you can use it by:
295
+
296
+ ```ruby
297
+ Capybara.javascript_driver = :webkit
298
+ ```
299
+
300
+ ### Poltergeist
301
+
302
+ [Poltergeist](https://github.com/jonleighton/poltergeist) is another
303
+ headless driver which integrates Capybara with
304
+ [PhantomJS](http://phantomjs.org/). It is truly headless, so doesn't
305
+ require Xvfb to run on your CI server. It will also detect and report
306
+ any Javascript errors that happen within the page.
307
+
308
+ ## The DSL
309
+
310
+ *A complete reference is available at
311
+ [rubydoc.info](http://rubydoc.info/github/jnicklas/capybara/master)*.
312
+
313
+ **Note**: All searches in Capybara are *case sensitive*. This is because
314
+ Capybara heavily uses XPath, which doesn't support case insensitivity.
315
+
316
+ ### Navigating
317
+
318
+ You can use the
319
+ [#visit](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#visit-instance_method)
320
+ method to navigate to other pages:
321
+
322
+ ```ruby
323
+ visit('/projects')
324
+ visit(post_comments_path(post))
325
+ ```
326
+
327
+ The visit method only takes a single parameter, the request method is **always**
328
+ GET.
329
+
330
+ You can get the [current path](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#current_path-instance_method)
331
+ of the browsing session for test assertions:
332
+
333
+ ```ruby
334
+ current_path.should == post_comments_path(post)
335
+ ```
336
+
337
+ ### Clicking links and buttons
338
+
339
+ *Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions)*
340
+
341
+ You can interact with the webapp by following links and buttons. Capybara
342
+ automatically follows any redirects, and submits forms associated with buttons.
343
+
344
+ ```ruby
345
+ click_link('id-of-link')
346
+ click_link('Link Text')
347
+ click_button('Save')
348
+ click_on('Link Text') # clicks on either links or buttons
349
+ click_on('Button Value')
350
+ ```
351
+
352
+ ### Interacting with forms
353
+
354
+ *Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions)*
355
+
356
+ There are a number of tools for interacting with form elements:
357
+
358
+ ```ruby
359
+ fill_in('First Name', :with => 'John')
360
+ fill_in('Password', :with => 'Seekrit')
361
+ fill_in('Description', :with => 'Really Long Text...')
362
+ choose('A Radio Button')
363
+ check('A Checkbox')
364
+ uncheck('A Checkbox')
365
+ attach_file('Image', '/path/to/image.jpg')
366
+ select('Option', :from => 'Select Box')
367
+ ```
368
+
369
+ ### Querying
370
+
371
+ *Full reference: [Capybara::Node::Matchers](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Matchers)*
372
+
373
+ Capybara has a rich set of options for querying the page for the existence of
374
+ certain elements, and working with and manipulating those elements.
375
+
376
+ ```ruby
377
+ page.has_selector?('table tr')
378
+ page.has_selector?(:xpath, '//table/tr')
379
+ page.has_no_selector?(:content)
380
+
381
+ page.has_xpath?('//table/tr')
382
+ page.has_css?('table tr.foo')
383
+ page.has_content?('foo')
384
+ ```
385
+
386
+ **Note:** The negative forms like `has_no_selector?` are different from `not
387
+ has_selector?`. Read the section on asynchronous JavaScript for an explanation.
388
+
389
+ You can use these with RSpec's magic matchers:
390
+
391
+ ```ruby
392
+ page.should have_selector('table tr')
393
+ page.should have_selector(:xpath, '//table/tr')
394
+ page.should have_no_selector(:content)
395
+
396
+ page.should have_xpath('//table/tr')
397
+ page.should have_css('table tr.foo')
398
+ page.should have_content('foo')
399
+ ```
400
+
401
+ ### Finding
402
+
403
+ _Full reference: [Capybara::Node::Finders](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Finders)_
404
+
405
+ You can also find specific elements, in order to manipulate them:
406
+
407
+ ```ruby
408
+ find_field('First Name').value
409
+ find_link('Hello').visible?
410
+ find_button('Send').click
411
+
412
+ find(:xpath, "//table/tr").click
413
+ find("#overlay").find("h1").click
414
+ all('a').each { |a| a[:href] }
415
+ ```
416
+
417
+ **Note**: `find` will wait for an element to appear on the page, as explained in the
418
+ Ajax section. If the element does not appear it will raise an error.
419
+
420
+ These elements all have all the Capybara DSL methods available, so you can restrict them
421
+ to specific parts of the page:
422
+
423
+ ```ruby
424
+ find('#navigation').click_link('Home')
425
+ find('#navigation').should have_button('Sign out')
426
+ ```
427
+
428
+ ### Scoping
429
+
430
+ Capybara makes it possible to restrict certain actions, such as interacting with
431
+ forms or clicking links and buttons, to within a specific area of the page. For
432
+ this purpose you can use the generic
433
+ <tt>[within](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#within-instance_method)</tt>
434
+ method. Optionally you can specify which kind of selector to use.
435
+
436
+ ```ruby
437
+ within("li#employee") do
438
+ fill_in 'Name', :with => 'Jimmy'
439
+ end
440
+
441
+ within(:xpath, "//li[@id='employee']") do
442
+ fill_in 'Name', :with => 'Jimmy'
443
+ end
444
+ ```
445
+
446
+ **Note**: `within` will scope the actions to the _first_ (not _any_) element that matches the selector.
447
+
448
+ There are special methods for restricting the scope to a specific fieldset,
449
+ identified by either an id or the text of the fieldset's legend tag, and to a
450
+ specific table, identified by either id or text of the table's caption tag.
451
+
452
+ ```ruby
453
+ within_fieldset('Employee') do
454
+ fill_in 'Name', :with => 'Jimmy'
455
+ end
456
+
457
+ within_table('Employee') do
458
+ fill_in 'Name', :with => 'Jimmy'
459
+ end
460
+ ```
461
+
462
+ ### Scripting
463
+
464
+ In drivers which support it, you can easily execute JavaScript:
465
+
466
+ ```ruby
467
+ page.execute_script("$('body').empty()")
468
+ ```
469
+
470
+ For simple expressions, you can return the result of the script. Note
471
+ that this may break with more complicated expressions:
472
+
473
+ ```ruby
474
+ result = page.evaluate_script('4 + 4');
475
+ ```
476
+
477
+ ### Saving screenshot
478
+
479
+ In drivers which support it, you can save screenshot:
480
+
481
+ ```ruby
482
+ page.save_screenshot('screenshot.png')
483
+ ```
484
+
485
+ ### Debugging
486
+
487
+ It can be useful to take a snapshot of the page as it currently is and take a
488
+ look at it:
489
+
490
+ ```ruby
491
+ save_and_open_page
492
+ ```
493
+
494
+ You can also retrieve the current state of the DOM as a string using
495
+ <tt>[page.html](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#html-instance_method)</tt>.
496
+
497
+ ```ruby
498
+ print page.html
499
+ ```
500
+
501
+ This is mostly useful for debugging. You should avoid testing against the
502
+ contents of `page.html` and use the more expressive finder methods instead.
503
+
504
+ ## Transactions and database setup
505
+
506
+ Some Capybara drivers need to run against an actual HTTP server. Capybara takes
507
+ care of this and starts one for you in the same process as your test, but on
508
+ another thread. Selenium is one of those drivers, whereas RackTest is not.
509
+
510
+ If you are using a SQL database, it is common to run every test in a
511
+ transaction, which is rolled back at the end of the test, rspec-rails does this
512
+ by default out of the box for example. Since transactions are usually not
513
+ shared across threads, this will cause data you have put into the database in
514
+ your test code to be invisible to Capybara.
515
+
516
+ Cucumber handles this by using truncation instead of transactions, i.e. they
517
+ empty out the entire database after each test. You can get the same behaviour
518
+ by using a gem such as [database_cleaner](https://github.com/bmabey/database_cleaner).
519
+
520
+ It is also possible to force your ORM to use the same transaction for all
521
+ threads. This may have thread safety implications and could cause strange
522
+ failures, so use caution with this approach. It can be implemented in
523
+ ActiveRecord through the following monkey patch:
524
+
525
+ ```ruby
526
+ class ActiveRecord::Base
527
+ mattr_accessor :shared_connection
528
+ @@shared_connection = nil
529
+
530
+ def self.connection
531
+ @@shared_connection || retrieve_connection
532
+ end
533
+ end
534
+ ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
535
+ ```
536
+
537
+ ## Asynchronous JavaScript (Ajax and friends)
538
+
539
+ When working with asynchronous JavaScript, you might come across situations
540
+ where you are attempting to interact with an element which is not yet present
541
+ on the page. Capybara automatically deals with this by waiting for elements
542
+ to appear on the page.
543
+
544
+ When issuing instructions to the DSL such as:
545
+
546
+ ```ruby
547
+ click_link('foo')
548
+ click_link('bar')
549
+ page.should have_content('baz')
550
+ ```
551
+
552
+ If clicking on the *foo* link triggers an asynchronous process, such as
553
+ an Ajax request, which, when complete will add the *bar* link to the page,
554
+ clicking on the *bar* link would be expected to fail, since that link doesn't
555
+ exist yet. However Capybara is smart enought to retry finding the link for a
556
+ brief period of time before giving up and throwing an error. The same is true of
557
+ the next line, which looks for the content *baz* on the page; it will retry
558
+ looking for that content for a brief time. You can adjust how long this period
559
+ is (the default is 2 seconds):
560
+
561
+ ```ruby
562
+ Capybara.default_wait_time = 5
563
+ ```
564
+
565
+ Be aware that because of this behaviour, the following two statements are **not**
566
+ equivalent, and you should **always** use the latter!
567
+
568
+ ```ruby
569
+ !page.has_xpath?('a')
570
+ page.has_no_xpath?('a')
571
+ ```
572
+
573
+ The former would immediately fail because the content has not yet been removed.
574
+ Only the latter would wait for the asynchronous process to remove the content
575
+ from the page.
576
+
577
+ Capybara's Rspec matchers, however, are smart enough to handle either form.
578
+ The two following statements are functionally equivalent:
579
+
580
+ ```ruby
581
+ page.should_not have_xpath('a')
582
+ page.should have_no_xpath('a')
583
+ ```
584
+
585
+ Capybara's waiting behaviour is quite advanced, and can deal with situations
586
+ such as the following line of code:
587
+
588
+ ```ruby
589
+ find('#sidebar').find('h1').should have_content('Something')
590
+ ```
591
+
592
+ Even if JavaScript causes `#sidebar` to disappear off the page, Capybara
593
+ will automatically reload it and any elements it contains. So if an AJAX
594
+ request causes the contents of `#sidebar` to change, which would update
595
+ the text of the `h1` to "Something", and this happened, this test would
596
+ pass. If you do not want this behaviour, you can set
597
+ `Capybara.automatic_reload` to `false`.
598
+
599
+ ## Using the DSL elsewhere
600
+
601
+ You can mix the DSL into any context by including <tt>Capybara::DSL</tt>:
602
+
603
+
604
+ ```ruby
605
+ require 'capybara'
606
+ require 'capybara/dsl'
607
+
608
+ Capybara.default_driver = :webkit
609
+
610
+ module MyModule
611
+ include Capybara::DSL
612
+
613
+ def login!
614
+ within("//form[@id='session']") do
615
+ fill_in 'Login', :with => 'user@example.com'
616
+ fill_in 'Password', :with => 'password'
617
+ end
618
+ click_link 'Sign in'
619
+ end
620
+ end
621
+ ```
622
+
623
+ This enables its use in unsupported testing frameworks, and for general-purpose scripting.
624
+
625
+ ## Calling remote servers
626
+
627
+ Normally Capybara expects to be testing an in-process Rack application, but you
628
+ can also use it to talk to a web server running anywhere on the internets, by
629
+ setting app_host:
630
+
631
+ ```ruby
632
+ Capybara.current_driver = :selenium
633
+ Capybara.app_host = 'http://www.google.com'
634
+ ...
635
+ visit('/')
636
+ ```
637
+
638
+ **Note**: the default driver (`:rack_test`) does not support running
639
+ against a remote server. With drivers that support it, you can also visit any
640
+ URL directly:
641
+
642
+ ```ruby
643
+ visit('http://www.google.com')
644
+ ```
645
+
646
+ By default Capybara will try to boot a rack application automatically. You
647
+ might want to switch off Capybara's rack server if you are running against a
648
+ remote application:
649
+
650
+ ```ruby
651
+ Capybara.run_server = false
652
+ ```
653
+
654
+ ## Using the sessions manually
655
+
656
+ For ultimate control, you can instantiate and use a
657
+ [Session](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session)
658
+ manually.
659
+
660
+ ```ruby
661
+ require 'capybara'
662
+
663
+ session = Capybara::Session.new(:webkit, my_rack_app)
664
+ session.within("//form[@id='session']") do
665
+ session.fill_in 'Login', :with => 'user@example.com'
666
+ session.fill_in 'Password', :with => 'password'
667
+ end
668
+ session.click_link 'Sign in'
669
+ ```
670
+
671
+ ## XPath, CSS and selectors
672
+
673
+ Capybara does not try to guess what kind of selector you are going to give it,
674
+ and will always use CSS by default. If you want to use XPath, you'll need to
675
+ do:
676
+
677
+ ```ruby
678
+ within(:xpath, '//ul/li') { ... }
679
+ find(:xpath, '//ul/li').text
680
+ find(:xpath, '//li[contains(.//a[@href = "#"]/text(), "foo")]').value
681
+ ```
682
+
683
+ Alternatively you can set the default selector to XPath:
684
+
685
+ ```ruby
686
+ Capybara.default_selector = :xpath
687
+ find('//ul/li').text
688
+ ```
689
+
690
+ Capybara allows you to add custom selectors, which can be very useful if you
691
+ find yourself using the same kinds of selectors very often:
692
+
693
+ ```ruby
694
+ Capybara.add_selector(:id) do
695
+ xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
696
+ end
697
+
698
+ Capybara.add_selector(:row) do
699
+ xpath { |num| ".//tbody/tr[#{num}]" }
700
+ end
701
+
702
+ Capybara.add_selector(:flash_type) do
703
+ css { |type| "#flash.#{type}" }
704
+ end
705
+ ```
706
+
707
+ The block given to xpath must always return an XPath expression as a String, or
708
+ an XPath expression generated through the XPath gem. You can now use these
709
+ selectors like this:
710
+
711
+ ```ruby
712
+ find(:id, 'post_123')
713
+ find(:row, 3)
714
+ find(:flash_type, :notice)
715
+ ```
716
+
717
+ You can specify an optional match option which will automatically use the
718
+ selector if it matches the argument:
719
+
720
+ ```ruby
721
+ Capybara.add_selector(:id) do
722
+ xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
723
+ match { |value| value.is_a?(Symbol) }
724
+ end
725
+ ```
726
+
727
+ Now use it like this:
728
+
729
+ ```ruby
730
+ find(:post_123)
731
+ ```
732
+
733
+ This :id selector is already built into Capybara by default, so you don't
734
+ need to add it yourself.
735
+
736
+ ## Beware the XPath // trap
737
+
738
+ In XPath the expression // means something very specific, and it might not be what
739
+ you think. Contrary to common belief, // means "anywhere in the document" not "anywhere
740
+ in the current context". As an example:
741
+
742
+ ```ruby
743
+ page.find(:xpath, '//body').all(:xpath, '//script')
744
+ ```
745
+
746
+ You might expect this to find all script tags in the body, but actually, it finds all
747
+ script tags in the entire document, not only those in the body! What you're looking
748
+ for is the .// expression which means "any descendant of the current node":
749
+
750
+ ```ruby
751
+ page.find(:xpath, '//body').all(:xpath, './/script')
752
+ ```
753
+ The same thing goes for within:
754
+
755
+ ```ruby
756
+ within(:xpath, '//body') do
757
+ page.find(:xpath, './/script')
758
+ within(:xpath, './/table/tbody') do
759
+ ...
760
+ end
761
+ end
762
+ ```
763
+
764
+ ## Configuring and adding drivers
765
+
766
+ Capybara makes it convenient to switch between different drivers. It also exposes
767
+ an API to tweak those drivers with whatever settings you want, or to add your own
768
+ drivers. This is how to switch the selenium driver to use chrome:
769
+
770
+ ```ruby
771
+ Capybara.register_driver :selenium do |app|
772
+ Capybara::Selenium::Driver.new(app, :browser => :chrome)
773
+ end
774
+ ```
775
+
776
+ However, it's also possible to give this a different name, so tests can switch
777
+ between using different browsers effortlessly:
778
+
779
+ ```ruby
780
+ Capybara.register_driver :selenium_chrome do |app|
781
+ Capybara::Selenium::Driver.new(app, :browser => :chrome)
782
+ end
783
+ ```
784
+
785
+ Whatever is returned from the block should conform to the API described by
786
+ Capybara::Driver::Base, it does not however have to inherit from this class.
787
+ Gems can use this API to add their own drivers to Capybara.
788
+
789
+ The [Selenium wiki](http://code.google.com/p/selenium/wiki/RubyBindings) has
790
+ additional info about how the underlying driver can be configured.
791
+
792
+ ## Gotchas:
793
+
794
+ * Access to session and request is not possible from the test, Access to
795
+ response is limited. Some drivers allow access to response headers and HTTP
796
+ status code, but this kind of functionality is not provided by some drivers,
797
+ such as Selenium.
798
+
799
+ * Access to Rails specific stuff (such as `controller`) is unavailable,
800
+ since we're not using Rails' integration testing.
801
+
802
+ * Freezing time: It's common practice to mock out the Time so that features
803
+ that depend on the current Date work as expected. This can be problematic,
804
+ since Capybara's Ajax timing uses the system time, resulting in Capybara
805
+ never timing out and just hanging when a failure occurs. It's still possible to
806
+ use gems which allow you to travel in time, rather than freeze time.
807
+ One such gem is [Timecop](http://github.com/jtrupiano/timecop).
808
+
809
+ * When using Rack::Test, beware if attempting to visit absolute URLs. For
810
+ example, a session might not be shared between visits to `posts_path`
811
+ and `posts_url`. If testing an absolute URL in an Action Mailer email,
812
+ set `default_url_options` to match the Rails default of
813
+ `www.example.com`.
814
+
815
+ ## Development
816
+
817
+ If you found a _reproducible_ bug, open a [GitHub
818
+ Issue](http://github.com/jnicklas/capybara/issues) to submit a bug report.
819
+
820
+ Even better, send a pull request! Make sure all changes are well tested,
821
+ Capybara is a testing tool after all. Topic branches are good.
822
+
823
+ To set up a development environment, simply do:
824
+
825
+ ```bash
826
+ git submodule update --init
827
+ bundle install
828
+ bundle exec rake # run the test suite
829
+ ```