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