bbc-capybara 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/History.txt +325 -0
  2. data/License.txt +22 -0
  3. data/README.md +815 -0
  4. data/lib/capybara.rb +368 -0
  5. data/lib/capybara/cucumber.rb +25 -0
  6. data/lib/capybara/driver/base.rb +64 -0
  7. data/lib/capybara/driver/node.rb +74 -0
  8. data/lib/capybara/dsl.rb +50 -0
  9. data/lib/capybara/node/actions.rb +146 -0
  10. data/lib/capybara/node/base.rb +63 -0
  11. data/lib/capybara/node/document.rb +25 -0
  12. data/lib/capybara/node/element.rb +201 -0
  13. data/lib/capybara/node/finders.rb +154 -0
  14. data/lib/capybara/node/matchers.rb +442 -0
  15. data/lib/capybara/node/simple.rb +132 -0
  16. data/lib/capybara/query.rb +63 -0
  17. data/lib/capybara/rack_test/browser.rb +126 -0
  18. data/lib/capybara/rack_test/driver.rb +80 -0
  19. data/lib/capybara/rack_test/form.rb +80 -0
  20. data/lib/capybara/rack_test/node.rb +121 -0
  21. data/lib/capybara/rails.rb +17 -0
  22. data/lib/capybara/rspec.rb +26 -0
  23. data/lib/capybara/rspec/features.rb +22 -0
  24. data/lib/capybara/rspec/matchers.rb +152 -0
  25. data/lib/capybara/selector.rb +156 -0
  26. data/lib/capybara/selenium/driver.rb +169 -0
  27. data/lib/capybara/selenium/node.rb +91 -0
  28. data/lib/capybara/server.rb +87 -0
  29. data/lib/capybara/session.rb +322 -0
  30. data/lib/capybara/spec/driver.rb +329 -0
  31. data/lib/capybara/spec/fixtures/capybara.jpg +3 -0
  32. data/lib/capybara/spec/fixtures/test_file.txt +1 -0
  33. data/lib/capybara/spec/public/jquery-ui.js +791 -0
  34. data/lib/capybara/spec/public/jquery.js +9046 -0
  35. data/lib/capybara/spec/public/test.js +43 -0
  36. data/lib/capybara/spec/session.rb +148 -0
  37. data/lib/capybara/spec/session/all_spec.rb +78 -0
  38. data/lib/capybara/spec/session/attach_file_spec.rb +76 -0
  39. data/lib/capybara/spec/session/check_spec.rb +68 -0
  40. data/lib/capybara/spec/session/choose_spec.rb +29 -0
  41. data/lib/capybara/spec/session/click_button_spec.rb +305 -0
  42. data/lib/capybara/spec/session/click_link_or_button_spec.rb +37 -0
  43. data/lib/capybara/spec/session/click_link_spec.rb +120 -0
  44. data/lib/capybara/spec/session/current_url_spec.rb +83 -0
  45. data/lib/capybara/spec/session/fill_in_spec.rb +127 -0
  46. data/lib/capybara/spec/session/find_button_spec.rb +18 -0
  47. data/lib/capybara/spec/session/find_by_id_spec.rb +18 -0
  48. data/lib/capybara/spec/session/find_field_spec.rb +26 -0
  49. data/lib/capybara/spec/session/find_link_spec.rb +19 -0
  50. data/lib/capybara/spec/session/find_spec.rb +168 -0
  51. data/lib/capybara/spec/session/first_spec.rb +105 -0
  52. data/lib/capybara/spec/session/has_button_spec.rb +32 -0
  53. data/lib/capybara/spec/session/has_css_spec.rb +243 -0
  54. data/lib/capybara/spec/session/has_field_spec.rb +192 -0
  55. data/lib/capybara/spec/session/has_link_spec.rb +37 -0
  56. data/lib/capybara/spec/session/has_select_spec.rb +129 -0
  57. data/lib/capybara/spec/session/has_selector_spec.rb +129 -0
  58. data/lib/capybara/spec/session/has_table_spec.rb +34 -0
  59. data/lib/capybara/spec/session/has_text_spec.rb +138 -0
  60. data/lib/capybara/spec/session/has_xpath_spec.rb +123 -0
  61. data/lib/capybara/spec/session/headers.rb +19 -0
  62. data/lib/capybara/spec/session/javascript.rb +312 -0
  63. data/lib/capybara/spec/session/response_code.rb +19 -0
  64. data/lib/capybara/spec/session/select_spec.rb +119 -0
  65. data/lib/capybara/spec/session/text_spec.rb +24 -0
  66. data/lib/capybara/spec/session/uncheck_spec.rb +21 -0
  67. data/lib/capybara/spec/session/unselect_spec.rb +67 -0
  68. data/lib/capybara/spec/session/within_spec.rb +178 -0
  69. data/lib/capybara/spec/test_app.rb +156 -0
  70. data/lib/capybara/spec/views/buttons.erb +4 -0
  71. data/lib/capybara/spec/views/fieldsets.erb +29 -0
  72. data/lib/capybara/spec/views/form.erb +366 -0
  73. data/lib/capybara/spec/views/frame_one.erb +8 -0
  74. data/lib/capybara/spec/views/frame_two.erb +8 -0
  75. data/lib/capybara/spec/views/header_links.erb +7 -0
  76. data/lib/capybara/spec/views/host_links.erb +12 -0
  77. data/lib/capybara/spec/views/popup_one.erb +8 -0
  78. data/lib/capybara/spec/views/popup_two.erb +8 -0
  79. data/lib/capybara/spec/views/postback.erb +13 -0
  80. data/lib/capybara/spec/views/tables.erb +62 -0
  81. data/lib/capybara/spec/views/with_html.erb +75 -0
  82. data/lib/capybara/spec/views/with_html_entities.erb +1 -0
  83. data/lib/capybara/spec/views/with_js.erb +53 -0
  84. data/lib/capybara/spec/views/with_scope.erb +36 -0
  85. data/lib/capybara/spec/views/with_simple_html.erb +1 -0
  86. data/lib/capybara/spec/views/within_frames.erb +10 -0
  87. data/lib/capybara/spec/views/within_popups.erb +25 -0
  88. data/lib/capybara/util/save_and_open_page.rb +45 -0
  89. data/lib/capybara/util/timeout.rb +27 -0
  90. data/lib/capybara/version.rb +3 -0
  91. data/spec/basic_node_spec.rb +89 -0
  92. data/spec/capybara_spec.rb +46 -0
  93. data/spec/driver/rack_test_driver_spec.rb +90 -0
  94. data/spec/driver/selenium_driver_spec.rb +55 -0
  95. data/spec/dsl_spec.rb +255 -0
  96. data/spec/fixtures/selenium_driver_rspec_failure.rb +8 -0
  97. data/spec/fixtures/selenium_driver_rspec_success.rb +8 -0
  98. data/spec/rspec/features_spec.rb +43 -0
  99. data/spec/rspec/matchers_spec.rb +564 -0
  100. data/spec/rspec_spec.rb +51 -0
  101. data/spec/save_and_open_page_spec.rb +155 -0
  102. data/spec/server_spec.rb +74 -0
  103. data/spec/session/rack_test_session_spec.rb +61 -0
  104. data/spec/session/selenium_session_spec.rb +26 -0
  105. data/spec/spec_helper.rb +31 -0
  106. data/spec/timeout_spec.rb +28 -0
  107. metadata +297 -0
@@ -0,0 +1,325 @@
1
+ # master
2
+
3
+ ### Fixed
4
+
5
+ * Test suite now passes on Ruby 1.8 [Jo Liss]
6
+ * #565: `require 'capybara/dsl'` is no longer necessary [Jo Liss]
7
+ * Rack::Test now respects ports when changing hosts [Jo Liss]
8
+ * #603: Rack::Test now preserves the original referer URL when following a
9
+ redirect [Rob van Dijk]
10
+
11
+ ### Added
12
+
13
+ * #481: XPath ... and new selectors ... [Adam McCrea, Jonas Nicklas]
14
+ * has_text, has_content ... [Jonas Nicklas]
15
+ * Add Capybara.server_host option (default: 127.0.0.1) [David Balatero]
16
+
17
+ ### Changed
18
+
19
+ * #394: #body now returns the unmodified source (like #source), not the current
20
+ state of the DOM (like #html) [Jonas Nicklas]
21
+ * Element#text on RackTest now only returns visible text and normalizes
22
+ (strips) whitespace, as with Selenium [Mark Dodwell, Jo Liss]
23
+
24
+ ### Removed
25
+
26
+ * #589: Capybara.server_boot_timeout has been removed in favor of a higher
27
+ (60-second) hard-coded timeout [Jo Liss]
28
+
29
+ # Version 1.1.2
30
+
31
+ Release date: 2011-11-15
32
+
33
+ ### Fixed
34
+
35
+ * #541: Make attach_file work with selenium-webdriver >=2.12 [Jonas Nicklas]
36
+
37
+ # Version 1.1.0
38
+
39
+ Release date: 2011-09-02
40
+
41
+ ### Fixed
42
+
43
+ * Sensible inspect for Capybara::Session [Jo Liss]
44
+ * Fix headers and host on redirect [Matt Colyer, Jonas Nicklas, Kim Burgestrand]
45
+ * using_driver now restores the old driver instead of reverting to the default [Carol Nichols]
46
+ * Errors when following links relative to the root path under rack-test [Jonas Nicklas, Kim Burgestrand]
47
+ * Make sure exit codes are propagated properly [Edgar Beigarts]
48
+
49
+ ### Changed
50
+
51
+ * resynchronization is off by default under Selenium
52
+
53
+ ### Added
54
+
55
+ * Elements are automatically reloaded (including parents) during wait [Jonas Nicklas]
56
+ * Rescue driver specific element errors, such as the dreaded ObsoleteElementError and retry [Jonas Nicklas]
57
+ * Raise an error if something has frozen time [Jonas Nicklas]
58
+ * Allow within to take a node instead of a selector [Peter Williams]
59
+ * Using wait_time_time to change wait time for a block of code [Jonas Nicklas, Kim Burgestrand]
60
+ * Option for rack-test driver to disable data-method hack [Jonas Nicklas, Kim Burgestrand]
61
+
62
+ # Version 1.0.1
63
+
64
+ Release date: 2011-08-12
65
+
66
+ ### Fixed
67
+
68
+ * Dependend on selenium-webdriver ~>2.0 and fix deprecations [Thomas Walpole, Jo Liss]
69
+ * Depend on Launch 2.0 [Jeremy Hinegardner]
70
+ * Rack-Test ignores fill in on fields with maxlength=""
71
+
72
+ # Version 1.0.0
73
+
74
+ Release date: 2011-06-14
75
+
76
+ ### Added
77
+
78
+ * Added DSL for acceptance tests, inspired by Luismi Cavallé's Steak [Luismi Cavalle and Jonas Nicklas]
79
+ * Selenium driver automatically waits for AJAX requests to finish [mgiambalvo, Nicklas Ramhöj and Jonas Nicklas]
80
+ * Support for switching between multiple named sessions [Tristan Dunn]
81
+ * failure_message can be specified for Selectors [Jonas Nicklas]
82
+ * RSpec matchers [David Chelimsky and Jonas Nicklas]
83
+ * Added save_page to save tempfile without opening in browser [Jeff Kreeftmeijer]
84
+ * Cucumber now switches automatically to a registered driver if the tag matches the name [Jonas Nicklas]
85
+ * Added Session#text [Jonas Nicklas and Scott Cytacki]
86
+ * Added Session#html as an alias for Session#body [Jo Liss]
87
+ * Added Session#current_host method [Jonas Nicklas]
88
+ * Buttons can now be clicked by title [Javier Martin]
89
+ * :headers option for RackTest driver to set custom HTTP headers [Jonas Nicklas]
90
+
91
+ ### Removed
92
+
93
+ * Culerity and Celerity drivers have been removed and split into separate gems [Gabriel Sobrinho]
94
+
95
+ ### Deprecated
96
+
97
+ * `include Capybara` has been deprecated in favour of `include Capybara::DSL` [Jonas Nicklas]
98
+
99
+ ### Changed
100
+
101
+ * Rack test driver class has been renamed from Capybara::Driver::RackTest to Capybara::RackTest::Driver [Jonas Nicklas]
102
+ * Selenium driver class has been renamed from Capybara::Driver::Selenium to Capybara::Selenium::Driver [Jonas Nicklas]
103
+ * Capybara now prefers visible elements over hidden elements, disable by setting Capybara.prefer_visible_elements = false [Jonas Nicklas and Nicklas Ramhöj]
104
+ * For RSpec, :type => :request is now supported (and preferred over :acceptance) [Jo Liss]
105
+ * Selenium driver tried to wait for AJAX requests to finish before proceeding [Jonas Nicklas and Nicklas Ramhöj]
106
+ * Session no longer uses method missing, uses explicit delegates instead [Jonas Nicklas]
107
+
108
+ ### Fixed
109
+
110
+ * The Rack::Test driver now respects maxlength on text fields [Guilherme Carvalho]
111
+ * Allow for more than one save_and_open_page call per second [Jo Liss]
112
+ * Automatically convert options to :count, :minimum, :maximum, etc. to integers [Keith Marcum]
113
+ * Rack::Test driver honours maxlength on input fields [Guilherme Carvalho]
114
+ * Rack::Test now works as expected with domains and subdomains [Jonas Nicklas]
115
+ * Session is reset more thoroughly between tests. [Jonas Nicklas]
116
+ * Raise error when uploading non-existant file [Jonas Nicklas]
117
+ * Rack reponse body should respond to #each [Piotr Sarnacki]
118
+ * Deprecation warnings with selenium webdriver 0.2.0 [Aaron Gibraltar]
119
+ * Selenium Chrome no longer YELLS tagname [Carl Jackson & David W. Frank]
120
+ * Capybara no longer strips encoding before sending to Rack [Jonas Nicklas]
121
+ * Improve handling of relative URLs [John Barton]
122
+ * Readd and fix build_rack_mock_session [Jonas Nicklas, Jon Leighton]
123
+
124
+ # Version 0.4.1
125
+
126
+ Release date: 2011-01-21
127
+
128
+ ### Added
129
+
130
+ * New click_on alias for click_link_or_button, shorter yet unambiguous. [Jonas Nicklas]
131
+ * Finders now accept :visible => false which will find all elements regardless of Capybara.ignore_hidden_elements [Jonas Nicklas]
132
+ * Configure how the server is started via Capybara.server { |app, port| ... }. [John Firebough]
133
+ * Added :between, :maximum and :minimum options to has_selector and friends [James B. Byrne]
134
+ * New Capybara.string util function which allows matchers on arbitrary strings, mostly for helper and view specs [David Chelimsky and Jonas Nicklas]
135
+ * Server boot timeout is now configurable, via Capybara.server_boot_timeout [Adam Cigánek]
136
+ * Built in support for RSpec [Jonas Nicklas]
137
+ * Capybara.using_driver to switch to a different driver temporarily [Jeff Kreeftmeijer]
138
+ * Added Session#first which is somewhat speedier than Session#all, use it internally for speed boost [John Firebaugh]
139
+
140
+ ### Changed
141
+
142
+ * Session#within now accepts the same arguments as other finders, like Session#all and Session#find [Jonas Nicklas]
143
+
144
+ ### Removed
145
+
146
+ * All deprecations from 0.4.0 have been removed. [Jonas Nicklas]
147
+
148
+ ### Fixed
149
+
150
+ * Don't mangle URLs in save_and_open_page when using self-closing tags [Adam Spiers]
151
+ * Catch correct error when server boot times out [Jonas Nicklas]
152
+ * Celerity driver now properly passes through options, making it configurable [Jonas Nicklas]
153
+ * Better implementation of attributes in C[ue]lerity, should fix issues with attributes with strange names [Jonas Nicklas]
154
+ * Session#find no longer swallows errors [Jonas Nicklas]
155
+ * Fix problems with multiple file inputs [Philip Arndt]
156
+ * Submit multipart forms as multipart under rack-test even if they contain no files [Ryan Kinderman]
157
+ * Matchers like has_select? and has_checked_field? now work with dynamically changed values [John Firebaugh]
158
+ * Preserve order of rack params [Joel Chippindale]
159
+ * RackTest#reset! is more thorough [Joel Chippindale]
160
+
161
+ # Version 0.4.0
162
+
163
+ Release date: 2010-10-22
164
+
165
+ ### Changed
166
+
167
+ * The Selector API was changed slightly, use Capybara.add_selector, see README
168
+
169
+ ### Fixed
170
+
171
+ * Celerity driver is registered properly
172
+ * has_selector? and has_no_selector? added to DSL
173
+ * Multiple selects return correct values under C[cu]lerity
174
+ * Naked query strings are handled correctly by rack-test
175
+
176
+ # Version 0.4.0.rc
177
+
178
+ Release date: 2010-10-12
179
+
180
+ ### Changed
181
+
182
+ * within and find/locate now follow the XPath spec in that //foo finds all nodes in the document, instead of
183
+ only for the context node. See this post for details: http://groups.google.com/group/ruby-capybara/browse_thread/thread/b129067979df21b3
184
+ * within now executes within the first found instance of the selector, not in all of them
185
+ * find now waits for AJAX requests and raises an exception when the element is not found (same as locate used to do)
186
+ * The default selector is now CSS, not XPath
187
+
188
+ ### Deprecated
189
+
190
+ * Session#click has been renamed click_link_or_button and the old click has been deprecated
191
+ * Node#node has been renamed native
192
+ * Node#locate is deprecated in favor of Node#find, which now behaves identically
193
+ * Session#drag is deprecated, please use Node#drag_to(other_node) instead
194
+
195
+ ### Added
196
+
197
+ * Pretty much everything is properly documented now
198
+ * It's now possible to call all session methods on nodes, like `find('#foo').fill_in(...)`
199
+ * Custom selectors can be added with Capybara::Selector.add
200
+ * The :id selector is added by default, use it lile `find(:id, 'foo')` or `find(:foo)`
201
+ * Added Node#has_selector? so any kind of selector can be queried.
202
+ * Added Capybara.configure for less wordy configuration
203
+ * Added within_window to switch between different windows (currently Selenium only)
204
+ * Capybara.server_port to provide a fixed port if wanted (defaults to automatic selection)
205
+
206
+ ### Fixed
207
+
208
+ * CSS selectors with multiple selectors, such as "h1, h2" now work correctly
209
+ * Port is automatically assigned instead of guessing
210
+ * Strip encodings in rack-test, no more warnings!
211
+ * RackTest no longer submits disabled fields
212
+ * Servers no longer output annoying debug information when started
213
+ * TCP port selection is left to Ruby to decide, no more port guessing
214
+ * Select boxes now return option value instead of text if present
215
+ * The default has been changed from localhost to 127.0.0.1, should fix some obscure selenium bugs
216
+ * RackTest now supports complex field names, such as foo[bar][][baz]
217
+
218
+ # Version 0.3.9
219
+
220
+ Release date: 2010-07-03
221
+
222
+ ### Added
223
+
224
+ * status_code which returns the HTTP status code of the last response (no Selenium!)
225
+ * Capybara.save_and_open_page to store tempfiles
226
+ * RackTest and Culerity drivers now clean up after themselves properly
227
+
228
+ ### Fixed
229
+
230
+ * When no rack app is set and the app is called, a more descriptive error is raised
231
+ * select now works with optgroups
232
+ * Don't submit image buttons unless they were clicked under rack-test
233
+ * Support custom field types under Selenium
234
+ * Support input fields without a type, treat them as though they were text fields
235
+ * Redirect now throws an error after 5 redirects, as per RFC
236
+ * Selenium now properly raises an error when Node#trigger is called
237
+ * Node#value now returns the correct value for textareas under rack-test
238
+
239
+ # Version 0.3.8
240
+
241
+ Release date: 2010-05-12
242
+
243
+ ### Added
244
+
245
+ * Within_frame method to execute a block of code within a particular iframe (Selenium only!)
246
+
247
+ ### Fixed
248
+
249
+ * Single quotes are properly escaped with `select` under rack-test and Selenium.
250
+ * The :text option for searches now escapes regexp special characters when a string is given.
251
+ * Selenium now correctly checks already checked checkboxes (same with uncheck)
252
+ * Timing issue which caused Selenium to hang under certain circumstances.
253
+ * Selenium now resolves attributes even if they are given as a Symbol
254
+
255
+ # Version 0.3.7
256
+
257
+ Release date: 2010-04-09
258
+
259
+ This is a drop in compatible maintainance release. It's mostly
260
+ important for driver authors.
261
+
262
+ ### Added
263
+
264
+ * RackTest scans for data-method which rails3 uses to change the request method
265
+
266
+ ### Fixed
267
+
268
+ * Don't hang when starting server on Windoze
269
+
270
+ ### Changed
271
+
272
+ * The driver and session specs are now located inside lib! Driver authors can simply require them.
273
+
274
+ # Version 0.3.6
275
+
276
+ Release date: 2010-03-22
277
+
278
+ This is a maintainance release with minor bug fixes, should be
279
+ drop in compatible.
280
+
281
+ ### Added
282
+
283
+ * It's now possible to load in external drivers
284
+
285
+ ### Fixed
286
+
287
+ * has_content? ignores whitespace
288
+ * Trigger events when choosing radios and checking checkboxes under Selenium
289
+ * Make Capybara.app totally optional when running without server
290
+ * Changed fallback host so it matches the one set up by Rails' integration tests
291
+
292
+ # Version 0.3.5
293
+
294
+ Release date: 2010-02-26
295
+
296
+ This is a mostly backwards compatible release, it does break
297
+ the API in some minor places, which should hopefully not affect
298
+ too many users, please read the release notes carefully!
299
+
300
+ ### Breaking
301
+
302
+ * Relative searching in a node (e.g. find('//p').all('//a')) will now follow XPath standard
303
+ this means that if you want to find descendant nodes only, you'll need to prefix a dot!
304
+ * `visit` now accepts fully qualified URLs for drivers that support it.
305
+ * Capybara will always try to run a rack server, unless you set Capybara.run_sever = false
306
+
307
+ ### Changed
308
+
309
+ * thin is preferred over mongrel and webrick, since it is Ruby 1.9 compatible
310
+ * click_button and click will find <input type="button">, clicking them does nothing in RackTest
311
+
312
+ ### Added
313
+
314
+ * Much improved error messages in a multitude of places
315
+ * More semantic page querying with has_link?, has_button?, etc...
316
+ * Option to ignore hidden elements when querying and interacting with the page
317
+ * Support for multiple selects
318
+
319
+ ### Fixed
320
+
321
+ * find_by_id is no longer broken
322
+ * clicking links where the image's alt attribute contains the text is now possible
323
+ * within_fieldset and within_table work when the default selector is CSS
324
+ * boolean attributes work the same across drivers (return true/false)
325
+
@@ -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,815 @@
1
+ # Capybara
2
+
3
+ [![Build Status](https://secure.travis-ci.org/jnicklas/capybara.png)](http://travis-ci.org/jnicklas/capybara)
4
+
5
+ Capybara helps you test Rails and Rack applications by simulating how a real
6
+ user would interact with your app. It is agnostic about the driver running your
7
+ tests and comes with Rack::Test and Selenium support built in. WebKit is
8
+ supported through an external gem.
9
+
10
+ **Need help?** Ask on the mailing list (please do not open an issue on
11
+ GitHub): http://groups.google.com/group/ruby-capybara
12
+
13
+ ## Setup
14
+
15
+ To install, type
16
+
17
+ ```bash
18
+ sudo gem install capybara
19
+ ```
20
+
21
+ If you are using Rails, add this line to your test helper file:
22
+
23
+ ```ruby
24
+ require 'capybara/rails'
25
+ ```
26
+
27
+ If you are not using Rails, set Capybara.app to your rack app:
28
+
29
+ ```ruby
30
+ Capybara.app = MyRackApp
31
+ ```
32
+
33
+ ## Using Capybara with Cucumber
34
+
35
+ The `cucumber-rails` gem comes with Capybara support built-in. If you
36
+ are not using Rails, manually load the `capybara/cucumber` module:
37
+
38
+ ```ruby
39
+ require 'capybara/cucumber'
40
+ Capybara.app = MyRackApp
41
+ ```
42
+
43
+ You can use the Capybara DSL in your steps, like so:
44
+
45
+ ```ruby
46
+ When /I sign in/ do
47
+ within("#session") do
48
+ fill_in 'Login', :with => 'user@example.com'
49
+ fill_in 'Password', :with => 'password'
50
+ end
51
+ click_link 'Sign in'
52
+ end
53
+ ```
54
+
55
+ You can switch to the `Capybara.javascript_driver` (`:selenium`
56
+ by default) by tagging scenarios (or features) with `@javascript`:
57
+
58
+ ```ruby
59
+ @javascript
60
+ Scenario: do something Ajaxy
61
+ When I click the Ajax link
62
+ ...
63
+ ```
64
+
65
+ There are also explicit `@selenium` and `@rack_test`
66
+ tags set up for you.
67
+
68
+ ## Using Capybara with RSpec
69
+
70
+ Load RSpec 2.x support by adding the following line (typically to your
71
+ `spec_helper.rb` file):
72
+
73
+ ```ruby
74
+ require 'capybara/rspec'
75
+ ```
76
+
77
+ If you are using Rails, put your Capybara specs in `spec/requests` or
78
+ `spec/integration`.
79
+
80
+ If you are not using Rails, tag all the example groups in which you want to use
81
+ Capybara with `:type => :request`.
82
+
83
+ You can now write your specs like so:
84
+
85
+ ```ruby
86
+ describe "the signup process", :type => :request do
87
+ before :each do
88
+ User.make(:email => 'user@example.com', :password => 'caplin')
89
+ end
90
+
91
+ it "signs me in" do
92
+ within("#session") do
93
+ fill_in 'Login', :with => 'user@example.com'
94
+ fill_in 'Password', :with => 'password'
95
+ end
96
+ click_link 'Sign in'
97
+ end
98
+ end
99
+ ```
100
+
101
+ Use `:js => true` to switch to the `Capybara.javascript_driver`
102
+ (`:selenium` by default), or provide a `:driver` option to switch
103
+ to one specific driver. For example:
104
+
105
+ ```ruby
106
+ describe 'some stuff which requires js', :js => true do
107
+ it 'will use the default js driver'
108
+ it 'will switch to one specific driver', :driver => :webkit
109
+ end
110
+ ```
111
+
112
+ Finally, Capybara also comes with a built in DSL for creating descriptive acceptance tests:
113
+
114
+ ```ruby
115
+ feature "Signing up" do
116
+ background do
117
+ User.make(:email => 'user@example.com', :password => 'caplin')
118
+ end
119
+
120
+ scenario "Signing in with correct credentials" do
121
+ within("#session") do
122
+ fill_in 'Login', :with => 'user@example.com'
123
+ fill_in 'Password', :with => 'caplin'
124
+ end
125
+ click_link 'Sign in'
126
+ end
127
+ end
128
+ ```
129
+
130
+ `feature` is in fact just an alias for `describe ..., :type => :request`,
131
+ `background` is an alias for `before`, and `scenario` for `it`.
132
+
133
+ ## Using Capybara with Test::Unit
134
+
135
+ * If you are using Rails, add `database_cleaner` to your Gemfile:
136
+
137
+ ```ruby
138
+ group :test do
139
+ gem 'database_cleaner'
140
+ end
141
+ ```
142
+
143
+ Then add the following code in your `test_helper.rb` file to make
144
+ Capybara available in all test cases deriving from
145
+ `ActionDispatch::IntegrationTest`:
146
+
147
+ ```ruby
148
+ # Transactional fixtures do not work with Selenium tests, because Capybara
149
+ # uses a separate server thread, which the transactions would be hidden
150
+ # from. We hence use DatabaseCleaner to truncate our test database.
151
+ DatabaseCleaner.strategy = :truncation
152
+
153
+ class ActionDispatch::IntegrationTest
154
+ # Make the Capybara DSL available in all integration tests
155
+ include Capybara::DSL
156
+
157
+ # Stop ActiveRecord from wrapping tests in transactions
158
+ self.use_transactional_fixtures = false
159
+
160
+ teardown do
161
+ DatabaseCleaner.clean # Truncate the database
162
+ Capybara.reset_sessions! # Forget the (simulated) browser state
163
+ Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
164
+ end
165
+ end
166
+ ```
167
+
168
+ * If you are not using Rails, define a base class for your Capybara tests like
169
+ so:
170
+
171
+ ```ruby
172
+ class CapybaraTestCase < Test::Unit::TestCase
173
+ include Capybara::DSL
174
+
175
+ def teardown
176
+ Capybara.reset_sessions!
177
+ Capybara.use_default_driver
178
+ end
179
+ end
180
+ ```
181
+
182
+ Remember to call `super` in any subclasses that override
183
+ `teardown`.
184
+
185
+ To switch the driver, set `Capybara.current_driver`. For instance,
186
+
187
+ ```ruby
188
+ class BlogTest < ActionDispatch::IntegrationTest
189
+ setup do
190
+ Capybara.current_driver = Capybara.javascript_driver # :selenium by default
191
+ end
192
+
193
+ test 'shows blog posts'
194
+ # ... this test is run with Selenium ...
195
+ end
196
+ end
197
+ ```
198
+
199
+ ## Using Capybara with MiniTest::Spec
200
+
201
+ Set up your base class as with Test::Unit. (On Rails, the right base class
202
+ could be something other than ActionDispatch::IntegrationTest.)
203
+
204
+ The capybara_minitest_spec gem ([Github](https://github.com/ordinaryzelig/capybara_minitest_spec),
205
+ [rubygems.org](https://rubygems.org/gems/capybara_minitest_spec)) provides MiniTest::Spec
206
+ expectations for Capybara. For example:
207
+
208
+ ```ruby
209
+ page.must_have_content('Important!')
210
+ ```
211
+
212
+ ## Drivers
213
+
214
+ Capybara uses the same DSL to drive a variety of browser and headless drivers.
215
+
216
+ ### Selecting the Driver
217
+
218
+ By default, Capybara uses the `:rack_test` driver, which is fast but does not
219
+ support JavaScript. You can set up a different default driver for your
220
+ features. For example if you'd prefer to run everything in Selenium, you could
221
+ do:
222
+
223
+ ```ruby
224
+ Capybara.default_driver = :selenium
225
+ ```
226
+
227
+ However, if you are using RSpec or Cucumber, you may instead want to consider
228
+ leaving the faster `:rack_test` as the __default_driver__, and marking only those
229
+ tests that require a JavaScript-capable driver using `:js => true` or
230
+ `@javascript`, respectively. By default, JavaScript tests are run using the
231
+ `:selenium` driver. You can change this by setting
232
+ `Capybara.javascript_driver`.
233
+
234
+ You can also change the driver temporarily (typically in the Before/setup and
235
+ After/teardown blocks):
236
+
237
+ ```ruby
238
+ Capybara.current_driver = :webkit # temporarily select different driver
239
+ ... tests ...
240
+ Capybara.use_default_driver # switch back to default driver
241
+ ```
242
+
243
+ **Note**: switching the driver creates a new session, so you may not be able to
244
+ switch in the middle of a test.
245
+
246
+ ### RackTest
247
+
248
+ RackTest is Capybara's default driver. It is written in pure Ruby and does not
249
+ have any support for executing JavaScript. Since the RackTest driver works
250
+ directly against the Rack interface, it does not need any server to be started,
251
+ it can work directly against any Rack app. This means that if your
252
+ application is not a Rack application (Rails, Sinatra and most other Ruby
253
+ frameworks are Rack applications) then you cannot use this driver. You cannot
254
+ use the RackTest driver to test a remote application.
255
+ [capybara-mechanize](https://github.com/jeroenvandijk/capybara-mechanize)
256
+ intends to provide a similar driver which works against remote servers, it is a
257
+ separate project.
258
+
259
+ RackTest can be configured with a set of headers like this:
260
+
261
+ ```ruby
262
+ Capybara.register_driver :rack_test do |app|
263
+ Capybara::RackTest::Driver.new(app, :browser => :chrome)
264
+ end
265
+ ```
266
+
267
+ See the section on adding and configuring drivers.
268
+
269
+ ### Selenium
270
+
271
+ At the moment, Capybara supports [Selenium 2.0
272
+ (Webdriver)](http://seleniumhq.org/docs/01_introducing_selenium.html#selenium-2-aka-selenium-webdriver),
273
+ *not* Selenium RC. Provided Firefox is installed, everything is set up for you,
274
+ and you should be able to start using Selenium right away.
275
+
276
+ Capybara can block and wait for Ajax requests to finish after you've interacted
277
+ with the page. To enable this behaviour, set the `:resynchronize` driver
278
+ option to `true`. This should normally not be necessary, since
279
+ Capybara's automatic reloading should take care of any asynchronicity problems.
280
+ See the section on Asynchronous JavaScript for details.
281
+
282
+ **Note**: drivers which run the server in a different thread may not work share the
283
+ same transaction as your tests, causing data not to be shared between your test
284
+ and test server, see "Transactions and database setup" below.
285
+
286
+ ### Capybara-webkit
287
+
288
+ The [capybara-webkit driver](https://github.com/thoughtbot/capybara-webkit) is for true headless
289
+ testing. It uses QtWebKit to start a rendering engine process. It can execute JavaScript as well.
290
+ It is significantly faster than drivers like Selenium since it does not load an entire browser.
291
+
292
+ You can install it with:
293
+
294
+ ```bash
295
+ gem install capybara-webkit
296
+ ```
297
+
298
+ And you can use it by:
299
+
300
+ ```ruby
301
+ Capybara.javascript_driver = :webkit
302
+ ```
303
+
304
+ ## The DSL
305
+
306
+ *A complete reference is available at
307
+ [at rubydoc.info](http://rubydoc.info/github/jnicklas/capybara/master)*.
308
+
309
+ **Note**: All searches in Capybara are *case sensitive*. This is because
310
+ Capybara heavily uses XPath, which doesn't support case insensitivity.
311
+
312
+ ### Navigating
313
+
314
+ You can use the
315
+ [#visit](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#visit-instance_method)
316
+ method to navigate to other pages:
317
+
318
+ ```ruby
319
+ visit('/projects')
320
+ visit(post_comments_path(post))
321
+ ```
322
+
323
+ The visit method only takes a single parameter, the request method is **always**
324
+ GET.
325
+
326
+ You can get the [current path](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#current_path-instance_method)
327
+ of the browsing session for test assertions:
328
+
329
+ ```ruby
330
+ current_path.should == post_comments_path(post)
331
+ ```
332
+
333
+ ### Clicking links and buttons
334
+
335
+ *Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions)*
336
+
337
+ You can interact with the webapp by following links and buttons. Capybara
338
+ automatically follows any redirects, and submits forms associated with buttons.
339
+
340
+ ```ruby
341
+ click_link('id-of-link')
342
+ click_link('Link Text')
343
+ click_button('Save')
344
+ click_on('Link Text') # clicks on either links or buttons
345
+ click_on('Button Value')
346
+ ```
347
+
348
+ ### Interacting with forms
349
+
350
+ *Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions)*
351
+
352
+ There are a number of tools for interacting with form elements:
353
+
354
+ ```ruby
355
+ fill_in('First Name', :with => 'John')
356
+ fill_in('Password', :with => 'Seekrit')
357
+ fill_in('Description', :with => 'Really Long Text...')
358
+ choose('A Radio Button')
359
+ check('A Checkbox')
360
+ uncheck('A Checkbox')
361
+ attach_file('Image', '/path/to/image.jpg')
362
+ select('Option', :from => 'Select Box')
363
+ ```
364
+
365
+ ### Querying
366
+
367
+ *Full reference: [Capybara::Node::Matchers](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Matchers)*
368
+
369
+ Capybara has a rich set of options for querying the page for the existence of
370
+ certain elements, and working with and manipulating those elements.
371
+
372
+ ```ruby
373
+ page.has_selector?('table tr')
374
+ page.has_selector?(:xpath, '//table/tr')
375
+ page.has_no_selector?(:content)
376
+
377
+ page.has_xpath?('//table/tr')
378
+ page.has_css?('table tr.foo')
379
+ page.has_content?('foo')
380
+ ```
381
+
382
+ **Note:** The negative forms like `has_no_selector?` are different from `not
383
+ has_selector?`. Read the section on asynchronous JavaScript for an explanation.
384
+
385
+ You can use these with RSpec's magic matchers:
386
+
387
+ ```ruby
388
+ page.should have_selector('table tr')
389
+ page.should have_selector(:xpath, '//table/tr')
390
+ page.should have_no_selector(:content)
391
+
392
+ page.should have_xpath('//table/tr')
393
+ page.should have_css('table tr.foo')
394
+ page.should have_content('foo')
395
+ ```
396
+
397
+ ### Finding
398
+
399
+ _Full reference: [Capybara::Node::Finders](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Finders)_
400
+
401
+ You can also find specific elements, in order to manipulate them:
402
+
403
+ ```ruby
404
+ find_field('First Name').value
405
+ find_link('Hello').visible?
406
+ find_button('Send').click
407
+
408
+ find(:xpath, "//table/tr").click
409
+ find("#overlay").find("h1").click
410
+ all('a').each { |a| a[:href] }
411
+ ```
412
+
413
+ **Note**: `find` will wait for an element to appear on the page, as explained in the
414
+ Ajax section. If the element does not appear it will raise an error.
415
+
416
+ These elements all have all the Capybara DSL methods available, so you can restrict them
417
+ to specific parts of the page:
418
+
419
+ ```ruby
420
+ find('#navigation').click_link('Home')
421
+ find('#navigation').should have_button('Sign out')
422
+ ```
423
+
424
+ ### Scoping
425
+
426
+ Capybara makes it possible to restrict certain actions, such as interacting with
427
+ forms or clicking links and buttons, to within a specific area of the page. For
428
+ this purpose you can use the generic
429
+ <tt>[within](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#within-instance_method)</tt>
430
+ method. Optionally you can specify which kind of selector to use.
431
+
432
+ ```ruby
433
+ within("li#employee") do
434
+ fill_in 'Name', :with => 'Jimmy'
435
+ end
436
+
437
+ within(:xpath, "//li[@id='employee']") do
438
+ fill_in 'Name', :with => 'Jimmy'
439
+ end
440
+ ```
441
+
442
+ **Note**: `within` will scope the actions to the _first_ (not _any_) element that matches the selector.
443
+
444
+ There are special methods for restricting the scope to a specific fieldset,
445
+ identified by either an id or the text of the fieldet's legend tag, and to a
446
+ specific table, identified by either id or text of the table's caption tag.
447
+
448
+ ```ruby
449
+ within_fieldset('Employee') do
450
+ fill_in 'Name', :with => 'Jimmy'
451
+ end
452
+
453
+ within_table('Employee') do
454
+ fill_in 'Name', :with => 'Jimmy'
455
+ end
456
+ ```
457
+
458
+ ### Scripting
459
+
460
+ In drivers which support it, you can easily execute JavaScript:
461
+
462
+ ```ruby
463
+ page.execute_script("$('body').empty()")
464
+ ```
465
+
466
+ For simple expressions, you can return the result of the script. Note
467
+ that this may break with more complicated expressions:
468
+
469
+ ```ruby
470
+ result = page.evaluate_script('4 + 4');
471
+ ```
472
+
473
+ ### Debugging
474
+
475
+ It can be useful to take a snapshot of the page as it currently is and take a
476
+ look at it:
477
+
478
+ ```ruby
479
+ save_and_open_page
480
+ ```
481
+
482
+ You can also retrieve the current state of the DOM as a string using
483
+ <tt>[page.html](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#html-instance_method)</tt>.
484
+
485
+ ```ruby
486
+ print page.html
487
+ ```
488
+
489
+ This is mostly useful for debugging. You should avoid testing against the
490
+ contents of `page.html` and use the more expressive finder methods instead.
491
+
492
+ ## Transactions and database setup
493
+
494
+ Some Capybara drivers need to run against an actual HTTP server. Capybara takes
495
+ care of this and starts one for you in the same process as your test, but on
496
+ another thread. Selenium is one of those drivers, whereas RackTest is not.
497
+
498
+ If you are using an SQL database, it is common to run every test in a
499
+ transaction, which is rolled back at the end of the test, rspec-rails does this
500
+ by default out of the box for example. Since transactions are usually not
501
+ shared across threads, this will cause data you have put into the database in
502
+ your test code to be invisible to Capybara.
503
+
504
+ Cucumber handles this by using truncation instead of transactions, i.e. they
505
+ empty out the entire database after each test. You can get the same behaviour
506
+ by using a gem such as [database_cleaner](https://github.com/bmabey/database_cleaner).
507
+
508
+ It is also possible to force your ORM to use the same transaction for all
509
+ threads. This may have thread safety implications and could cause strange
510
+ failures, so use caution with this approach. It can be implemented in
511
+ ActiveRecord through the following monkey patch:
512
+
513
+ ```ruby
514
+ class ActiveRecord::Base
515
+ mattr_accessor :shared_connection
516
+ @@shared_connection = nil
517
+
518
+ def self.connection
519
+ @@shared_connection || retrieve_connection
520
+ end
521
+ end
522
+ ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
523
+ ```
524
+
525
+ ## Asynchronous JavaScript (Ajax and friends)
526
+
527
+ When working with asynchronous JavaScript, you might come across situations
528
+ where you are attempting to interact with an element which is not yet present
529
+ on the page. Capybara automatically deals with this by waiting for elements
530
+ to appear on the page.
531
+
532
+ When issuing instructions to the DSL such as:
533
+
534
+ ```ruby
535
+ click_link('foo')
536
+ click_link('bar')
537
+ page.should have_content('baz')
538
+ ```
539
+
540
+ If clicking on the *foo* link triggers an asynchronous process, such as
541
+ an Ajax request, which, when complete will add the *bar* link to the page,
542
+ clicking on the *bar* link would be expected to fail, since that link doesn't
543
+ exist yet. However Capybara is smart enought to retry finding the link for a
544
+ brief period of time before giving up and throwing an error. The same is true of
545
+ the next line, which looks for the content *baz* on the page; it will retry
546
+ looking for that content for a brief time. You can adjust how long this period
547
+ is (the default is 2 seconds):
548
+
549
+ ```ruby
550
+ Capybara.default_wait_time = 5
551
+ ```
552
+
553
+ Be aware that because of this behaviour, the following two statements are **not**
554
+ equivalent, and you should **always** use the latter!
555
+
556
+ ```ruby
557
+ !page.has_xpath?('a')
558
+ page.has_no_xpath?('a')
559
+ ```
560
+
561
+ The former would immediately fail because the content has not yet been removed.
562
+ Only the latter would wait for the asynchronous process to remove the content
563
+ from the page.
564
+
565
+ Capybara's Rspec matchers, however, are smart enough to handle either form.
566
+ The two following statements are functionally equivalent:
567
+
568
+ ```ruby
569
+ page.should_not have_xpath('a')
570
+ page.should have_no_xpath('a')
571
+ ```
572
+
573
+ Capybara's waiting behaviour is quite advanced, and can deal with situations
574
+ such as the following line of code:
575
+
576
+ ```ruby
577
+ find('#sidebar').find('h1').should have_content('Something')
578
+ ```
579
+
580
+ Even if JavaScript causes `#sidebar` to disappear off the page, Capybara
581
+ will automatically reload it and any elements it contains. So if an AJAX
582
+ request causes the contents of `#sidebar` to change, which would update
583
+ the text of the `h1` to "Something", and this happened, this test would
584
+ pass. If you do not want this behaviour, you can set
585
+ `Capybara.automatic_reload` to `false`.
586
+
587
+ ## Using the DSL in unsupported testing frameworks
588
+
589
+ You can mix the DSL into any context by including <tt>Capybara::DSL</tt>:
590
+
591
+ ```ruby
592
+ require 'capybara'
593
+ require 'capybara/dsl'
594
+
595
+ Capybara.default_driver = :webkit
596
+
597
+ module MyModule
598
+ include Capybara::DSL
599
+
600
+ def login!
601
+ within("//form[@id='session']") do
602
+ fill_in 'Login', :with => 'user@example.com'
603
+ fill_in 'Password', :with => 'password'
604
+ end
605
+ click_link 'Sign in'
606
+ end
607
+ end
608
+ ```
609
+
610
+ ## Calling remote servers
611
+
612
+ Normally Capybara expects to be testing an in-process Rack application, but you
613
+ can also use it to talk to a web server running anywhere on the internets, by
614
+ setting app_host:
615
+
616
+ ```ruby
617
+ Capybara.current_driver = :selenium
618
+ Capybara.app_host = 'http://www.google.com'
619
+ ...
620
+ visit('/')
621
+ ```
622
+
623
+ **Note**: the default driver (`:rack_test`) does not support running
624
+ against a remote server. With drivers that support it, you can also visit any
625
+ URL directly:
626
+
627
+ ```ruby
628
+ visit('http://www.google.com')
629
+ ```
630
+
631
+ By default Capybara will try to boot a rack application automatically. You
632
+ might want to switch off Capybara's rack server if you are running against a
633
+ remote application:
634
+
635
+ ```ruby
636
+ Capybara.run_server = false
637
+ ```
638
+
639
+ ## Using the sessions manually
640
+
641
+ For ultimate control, you can instantiate and use a
642
+ [Session](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session)
643
+ manually.
644
+
645
+ ```ruby
646
+ require 'capybara'
647
+
648
+ session = Capybara::Session.new(:webkit, my_rack_app)
649
+ session.within("//form[@id='session']") do
650
+ session.fill_in 'Login', :with => 'user@example.com'
651
+ session.fill_in 'Password', :with => 'password'
652
+ end
653
+ session.click_link 'Sign in'
654
+ ```
655
+
656
+ ## XPath, CSS and selectors
657
+
658
+ Capybara does not try to guess what kind of selector you are going to give it,
659
+ and will always use CSS by default. If you want to use XPath, you'll need to
660
+ do:
661
+
662
+ ```ruby
663
+ within(:xpath, '//ul/li') { ... }
664
+ find(:xpath, '//ul/li').text
665
+ find(:xpath, '//li[contains(.//a[@href = "#"]/text(), "foo")]').value
666
+ ```
667
+
668
+ Alternatively you can set the default selector to XPath:
669
+
670
+ ```ruby
671
+ Capybara.default_selector = :xpath
672
+ find('//ul/li').text
673
+ ```
674
+
675
+ Capybara allows you to add custom selectors, which can be very useful if you
676
+ find yourself using the same kinds of selectors very often:
677
+
678
+ ```ruby
679
+ Capybara.add_selector(:id) do
680
+ xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
681
+ end
682
+
683
+ Capybara.add_selector(:row) do
684
+ xpath { |num| ".//tbody/tr[#{num}]" }
685
+ end
686
+
687
+ Capybara.add_selector(:flash_type) do
688
+ css { |type| "#flash.#{type}" }
689
+ end
690
+ ```
691
+
692
+ The block given to xpath must always return an XPath expression as a String, or
693
+ an XPath expression generated through the XPath gem. You can now use these
694
+ selectors like this:
695
+
696
+ ```ruby
697
+ find(:id, 'post_123')
698
+ find(:row, 3)
699
+ find(:flash_type, :notice)
700
+ ```
701
+
702
+ You can specify an optional match option which will automatically use the
703
+ selector if it matches the argument:
704
+
705
+ ```ruby
706
+ Capybara.add_selector(:id) do
707
+ xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
708
+ match { |value| value.is_a?(Symbol) }
709
+ end
710
+ ```
711
+
712
+ Now use it like this:
713
+
714
+ ```ruby
715
+ find(:post_123)
716
+ ```
717
+
718
+ This :id selector is already built into Capybara by default, so you don't
719
+ need to add it yourself.
720
+
721
+ ## Beware the XPath // trap
722
+
723
+ In XPath the expression // means something very specific, and it might not be what
724
+ you think. Contrary to common belief, // means "anywhere in the document" not "anywhere
725
+ in the current context". As an example:
726
+
727
+ ```ruby
728
+ page.find(:xpath, '//body').all(:xpath, '//script')
729
+ ```
730
+
731
+ You might expect this to find all script tags in the body, but actually, it finds all
732
+ script tags in the entire document, not only those in the body! What you're looking
733
+ for is the .// expression which means "any descendant of the current node":
734
+
735
+ ```ruby
736
+ page.find(:xpath, '//body').all(:xpath, './/script')
737
+ ```
738
+ The same thing goes for within:
739
+
740
+ ```ruby
741
+ within(:xpath, '//body') do
742
+ page.find(:xpath, './/script')
743
+ within(:xpath, './/table/tbody') do
744
+ ...
745
+ end
746
+ end
747
+ ```
748
+
749
+ ## Configuring and adding drivers
750
+
751
+ Capybara makes it convenient to switch between different drivers. It also exposes
752
+ an API to tweak those drivers with whatever settings you want, or to add your own
753
+ drivers. This is how to switch the selenium driver to use chrome:
754
+
755
+ ```ruby
756
+ Capybara.register_driver :selenium do |app|
757
+ Capybara::Selenium::Driver.new(app, :browser => :chrome)
758
+ end
759
+ ```
760
+
761
+ However, it's also possible to give this a different name, so tests can switch
762
+ between using different browsers effortlessly:
763
+
764
+ ```ruby
765
+ Capybara.register_driver :selenium_chrome do |app|
766
+ Capybara::Selenium::Driver.new(app, :browser => :chrome)
767
+ end
768
+ ```
769
+
770
+ Whatever is returned from the block should conform to the API described by
771
+ Capybara::Driver::Base, it does not however have to inherit from this class.
772
+ Gems can use this API to add their own drivers to Capybara.
773
+
774
+ The [Selenium wiki](http://code.google.com/p/selenium/wiki/RubyBindings) has
775
+ additional info about how the underlying driver can be configured.
776
+
777
+ ## Gotchas:
778
+
779
+ * Access to session and request is not possible from the test, Access to
780
+ response is limited. Some drivers allow access to response headers and HTTP
781
+ status code, but this kind of functionality is not provided by some drivers,
782
+ such as Selenium.
783
+
784
+ * Access to Rails specific stuff (such as `controller`) is unavailable,
785
+ since we're not using Rails' integration testing.
786
+
787
+ * Freezing time: It's common practice to mock out the Time so that features
788
+ that depend on the current Date work as expected. This can be problematic,
789
+ since Capybara's Ajax timing uses the system time, resulting in Capybara
790
+ never timing out and just hanging when a failure occurs. It's still possible to
791
+ use plugins which allow you to travel in time, rather than freeze time.
792
+ One such plugin is [Timecop](http://github.com/jtrupiano/timecop).
793
+
794
+ * When using Rack::Test, beware if attempting to visit absolute URLs. For
795
+ example, a session might not be shared between visits to `posts_path`
796
+ and `posts_url`. If testing an absolute URL in an Action Mailer email,
797
+ set `default_url_options` to match the Rails default of
798
+ `www.example.com`.
799
+
800
+ ## Development
801
+
802
+ If you found a _reproducible_ bug, open a [GitHub
803
+ Issue](http://github.com/jnicklas/capybara/issues) to submit a bug report.
804
+
805
+ Even better, send a pull request! Make sure all changes are well tested,
806
+ Capybara is a testing tool after all. Topic branches are good.
807
+
808
+ To set up a development environment, simply do:
809
+
810
+ ```bash
811
+ git submodule update --init
812
+ gem install bundler
813
+ bundle install
814
+ bundle exec rake # run the test suite
815
+ ```