capybara 0.3.9 → 0.4.0.rc
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.
- data/History.txt +43 -1
- data/README.rdoc +168 -98
- data/lib/capybara.rb +77 -15
- data/lib/capybara/driver/base.rb +21 -16
- data/lib/capybara/driver/celerity_driver.rb +39 -41
- data/lib/capybara/driver/culerity_driver.rb +2 -1
- data/lib/capybara/driver/node.rb +66 -0
- data/lib/capybara/driver/rack_test_driver.rb +66 -67
- data/lib/capybara/driver/selenium_driver.rb +43 -47
- data/lib/capybara/dsl.rb +44 -6
- data/lib/capybara/node.rb +185 -24
- data/lib/capybara/node/actions.rb +170 -0
- data/lib/capybara/node/finders.rb +150 -0
- data/lib/capybara/node/matchers.rb +360 -0
- data/lib/capybara/rails.rb +1 -0
- data/lib/capybara/selector.rb +52 -0
- data/lib/capybara/server.rb +68 -87
- data/lib/capybara/session.rb +221 -207
- data/lib/capybara/spec/driver.rb +45 -35
- data/lib/capybara/spec/public/test.js +1 -1
- data/lib/capybara/spec/session.rb +28 -53
- data/lib/capybara/spec/session/all_spec.rb +7 -3
- data/lib/capybara/spec/session/check_spec.rb +50 -52
- data/lib/capybara/spec/session/click_button_spec.rb +9 -0
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +37 -0
- data/lib/capybara/spec/session/current_url_spec.rb +7 -0
- data/lib/capybara/spec/session/find_button_spec.rb +4 -2
- data/lib/capybara/spec/session/find_by_id_spec.rb +4 -2
- data/lib/capybara/spec/session/find_field_spec.rb +7 -3
- data/lib/capybara/spec/session/find_link_spec.rb +5 -3
- data/lib/capybara/spec/session/find_spec.rb +71 -6
- data/lib/capybara/spec/session/has_field_spec.rb +1 -1
- data/lib/capybara/spec/session/has_selector_spec.rb +129 -0
- data/lib/capybara/spec/session/has_xpath_spec.rb +4 -4
- data/lib/capybara/spec/session/javascript.rb +25 -5
- data/lib/capybara/spec/session/select_spec.rb +16 -2
- data/lib/capybara/spec/session/unselect_spec.rb +8 -1
- data/lib/capybara/spec/session/within_spec.rb +5 -5
- data/lib/capybara/spec/views/form.erb +65 -1
- data/lib/capybara/spec/views/popup_one.erb +8 -0
- data/lib/capybara/spec/views/popup_two.erb +8 -0
- data/lib/capybara/spec/views/with_html.erb +5 -0
- data/lib/capybara/spec/views/within_popups.erb +25 -0
- data/lib/capybara/{save_and_open_page.rb → util/save_and_open_page.rb} +3 -3
- data/lib/capybara/util/timeout.rb +27 -0
- data/lib/capybara/version.rb +1 -1
- data/spec/capybara_spec.rb +18 -8
- data/spec/driver/celerity_driver_spec.rb +10 -14
- data/spec/driver/culerity_driver_spec.rb +4 -3
- data/spec/driver/rack_test_driver_spec.rb +39 -2
- data/spec/driver/remote_culerity_driver_spec.rb +5 -7
- data/spec/driver/remote_selenium_driver_spec.rb +7 -10
- data/spec/driver/selenium_driver_spec.rb +3 -2
- data/spec/dsl_spec.rb +5 -14
- data/spec/save_and_open_page_spec.rb +19 -19
- data/spec/server_spec.rb +22 -10
- data/spec/session/celerity_session_spec.rb +17 -21
- data/spec/session/culerity_session_spec.rb +3 -3
- data/spec/session/rack_test_session_spec.rb +2 -2
- data/spec/session/selenium_session_spec.rb +2 -2
- data/spec/spec_helper.rb +27 -6
- data/spec/{wait_until_spec.rb → timeout_spec.rb} +14 -14
- metadata +88 -46
- data/lib/capybara/searchable.rb +0 -54
- data/lib/capybara/spec/session/click_spec.rb +0 -24
- data/lib/capybara/spec/session/locate_spec.rb +0 -65
- data/lib/capybara/wait_until.rb +0 -28
- data/lib/capybara/xpath.rb +0 -179
- data/spec/searchable_spec.rb +0 -66
- data/spec/xpath_spec.rb +0 -180
data/History.txt
CHANGED
@@ -1,6 +1,48 @@
|
|
1
|
+
# Version 0.4.0.rc
|
2
|
+
|
3
|
+
Release date:
|
4
|
+
|
5
|
+
### Changed
|
6
|
+
|
7
|
+
* within and find/locate now follow the XPath spec in that //foo finds all nodes in the document, instead of
|
8
|
+
only for the context node. See this post for details: http://groups.google.com/group/ruby-capybara/browse_thread/thread/b129067979df21b3
|
9
|
+
* within now executes within the first found instance of the selector, not in all of them
|
10
|
+
* find now waits for AJAX requests and raises an exception when the element is not found (same as locate used to do)
|
11
|
+
* The default selector is now CSS, not XPath
|
12
|
+
|
13
|
+
### Deprecated
|
14
|
+
|
15
|
+
* Session#click has been renamed click_link_or_button and the old click has been deprecated
|
16
|
+
* Node#node has been renamed native
|
17
|
+
* Node#locate is deprecated in favor of Node#find, which now behaves identically
|
18
|
+
* Session#drag is deprecated, please use Node#drag_to(other_node) instead
|
19
|
+
|
20
|
+
### Added
|
21
|
+
|
22
|
+
* Pretty much everything is properly documented now
|
23
|
+
* It's now possible to call all session methods on nodes, like `find('#foo').fill_in(...)`
|
24
|
+
* Custom selectors can be added with Capybara::Selector.add
|
25
|
+
* The :id selector is added by default, use it lile `find(:id, 'foo')` or `find(:foo)`
|
26
|
+
* Added Node#has_selector? so any kind of selector can be queried.
|
27
|
+
* Added Capybara.configure for less wordy configuration
|
28
|
+
* Added within_window to switch between different windows (currently Selenium only)
|
29
|
+
* Capybara.server_port to provide a fixed port if wanted (defaults to automatic selection)
|
30
|
+
|
31
|
+
### Fixed
|
32
|
+
|
33
|
+
* CSS selectors with multiple selectors, such as "h1, h2" now work correctly
|
34
|
+
* Port is automatically assigned instead of guessing
|
35
|
+
* Strip encodings in rack-test, no more warnings!
|
36
|
+
* RackTest no longer submits disabled fields
|
37
|
+
* Servers no longer output annoying debug information when started
|
38
|
+
* TCP port selection is left to Ruby to decide, no more port guessing
|
39
|
+
* Select boxes now return option value instead of text if present
|
40
|
+
* The default has been changed from localhost to 127.0.0.1, should fix some obscure selenium bugs
|
41
|
+
* RackTest now supports complex field names, such as foo[bar][][baz]
|
42
|
+
|
1
43
|
# Version 0.3.9
|
2
44
|
|
3
|
-
Release
|
45
|
+
Release date: 2010-07-03
|
4
46
|
|
5
47
|
### Added
|
6
48
|
|
data/README.rdoc
CHANGED
@@ -1,16 +1,19 @@
|
|
1
|
-
=
|
1
|
+
= Capybara
|
2
2
|
|
3
3
|
* http://github.com/jnicklas/capybara
|
4
4
|
|
5
5
|
== Description:
|
6
6
|
|
7
7
|
Capybara aims to simplify the process of integration testing Rack applications,
|
8
|
-
such as Rails, Sinatra or Merb.
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
such as Rails, Sinatra or Merb. Capybara simulates how a real user would
|
9
|
+
interact with a web application. It is agnostic about the driver running your
|
10
|
+
tests and currently comes bundled with rack-test, Culerity, Celerity and Selenium
|
11
|
+
support built in. env.js support is available as the
|
12
12
|
{capybara-envjs gem}[http://github.com/smparkes/capybara-envjs].
|
13
13
|
|
14
|
+
Online documentation is availbable
|
15
|
+
{at rdoc.info}[http://rdoc.info/projects/jnicklas/capybara].
|
16
|
+
|
14
17
|
== Install:
|
15
18
|
|
16
19
|
Install as a gem:
|
@@ -31,18 +34,22 @@ Pull requests are very welcome! Make sure your patches are well tested, Capybara
|
|
31
34
|
a testing tool after all. Please create a topic branch for every separate change
|
32
35
|
you make.
|
33
36
|
|
37
|
+
Capybara uses bundler in development. To set up a development environment, simply do:
|
38
|
+
|
39
|
+
gem install bundler --pre
|
40
|
+
bundle install
|
41
|
+
|
34
42
|
== Using Capybara with Cucumber
|
35
43
|
|
36
|
-
Capybara is built to work nicely with Cucumber.
|
37
|
-
|
38
|
-
Capybara is built into cucumber-rails 0.2. In your Rails app, just run:
|
44
|
+
Capybara is built to work nicely with Cucumber. Support for Capybara is built into
|
45
|
+
cucumber-rails. In your Rails app, just run:
|
39
46
|
|
40
|
-
|
47
|
+
rails generate cucumber:install --capybara
|
41
48
|
|
42
49
|
And everything should be set up and ready to go.
|
43
50
|
|
44
51
|
If you want to use Capybara with Cucumber outside Rails (for example with Merb
|
45
|
-
or Sinatra), you'll need require
|
52
|
+
or Sinatra), you'll need to require Capybara and set the Rack app manually:
|
46
53
|
|
47
54
|
require 'capybara/cucumber'
|
48
55
|
Capybara.app = MyRackApp
|
@@ -50,16 +57,13 @@ or Sinatra), you'll need require capybara and set the Rack app manually:
|
|
50
57
|
Now you can use it in your steps:
|
51
58
|
|
52
59
|
When /I sign in/ do
|
53
|
-
within("
|
60
|
+
within("#session") do
|
54
61
|
fill_in 'Login', :with => 'user@example.com'
|
55
62
|
fill_in 'Password', :with => 'password'
|
56
63
|
end
|
57
64
|
click_link 'Sign in'
|
58
65
|
end
|
59
66
|
|
60
|
-
Please note that while Capybara uses XPath selectors by default, Cucumber explicitly
|
61
|
-
changes this to CSS in `env.rb`. See "XPath and CSS" below.
|
62
|
-
|
63
67
|
== Default and current driver
|
64
68
|
|
65
69
|
You can set up a default driver for your features. For example if you'd prefer
|
@@ -103,11 +107,6 @@ At the moment, Capybara supports Webdriver, also called Selenium 2.0, *not*
|
|
103
107
|
Selenium RC. Provided Firefox is installed, everything is set up for you, and
|
104
108
|
you should be able to start using Selenium right away.
|
105
109
|
|
106
|
-
If desired, you can change Selenium browser to :chrome or :ie:
|
107
|
-
|
108
|
-
require "selenium-webdriver"
|
109
|
-
Selenium::WebDriver.for :chrome
|
110
|
-
|
111
110
|
== Celerity
|
112
111
|
|
113
112
|
Celerity only runs on JRuby, so you'll need to install the celerity gem under
|
@@ -115,10 +114,6 @@ JRuby:
|
|
115
114
|
|
116
115
|
jruby -S gem install celerity
|
117
116
|
|
118
|
-
Note that some specs currently fail on celerity 0.7.5, due to a bug in recent
|
119
|
-
versions of HTMLUnit. It is recommended you use celerity 0.7.4 for the time
|
120
|
-
being.
|
121
|
-
|
122
117
|
== Culerity
|
123
118
|
|
124
119
|
Install celerity as noted above, make sure JRuby is in your path. Note that
|
@@ -130,7 +125,9 @@ The {capybara-envjs driver}[http://github.com/smparkes/capybara-envjs]
|
|
130
125
|
uses the envjs gem ({GitHub}[http://github.com/smparkes/env-js],
|
131
126
|
{rubygems.org}[http://rubygems.org/gems/envjs]) to interpret
|
132
127
|
JavaScript outside the browser. The driver is installed by installing the capybara-envjs gem:
|
128
|
+
|
133
129
|
gem install capybara-envjs
|
130
|
+
|
134
131
|
More info about the driver and env.js are available through the links above. The envjs gem only supports
|
135
132
|
Ruby 1.8.7 at this time.
|
136
133
|
|
@@ -164,8 +161,8 @@ automatically follows any redirects, and submits forms associated with buttons.
|
|
164
161
|
click_link('id-of-link')
|
165
162
|
click_link('Link Text')
|
166
163
|
click_button('Save')
|
167
|
-
|
168
|
-
|
164
|
+
click_link_or_button('Link Text')
|
165
|
+
click_link_or_button('Button Value')
|
169
166
|
|
170
167
|
=== Interacting with forms
|
171
168
|
|
@@ -181,57 +178,24 @@ with the various form elements:
|
|
181
178
|
attach_file('Image', '/path/to/image.jpg')
|
182
179
|
select('Option', :from => 'Select Box')
|
183
180
|
|
184
|
-
=== Scoping
|
185
|
-
|
186
|
-
Capybara makes it possible to restrict certain actions, such as interacting with
|
187
|
-
forms or clicking links and buttons, to within a specific area of the page. For
|
188
|
-
this purpose you can use the generic <tt>within</tt> method. Optionally you can
|
189
|
-
specify which kind of selector (CSS or XPath to use).
|
190
|
-
|
191
|
-
within("//li[@id='employee']") do
|
192
|
-
fill_in 'Name', :with => 'Jimmy'
|
193
|
-
end
|
194
|
-
|
195
|
-
within(:css, "li#employee") do
|
196
|
-
fill_in 'Name', :with => 'Jimmy'
|
197
|
-
end
|
198
|
-
|
199
|
-
You can choose which kind of selector Capybara uses by default, by setting
|
200
|
-
<tt>Capybara.default_selector</tt>.
|
201
|
-
|
202
|
-
There are special methods for restricting the scope to a specific fieldset,
|
203
|
-
identified by either an id or the text of the fieldet's legend tag, and to a
|
204
|
-
specific table, identified by either id or text of the table's caption tag.
|
205
|
-
|
206
|
-
within_fieldset('Employee') do
|
207
|
-
fill_in 'Name', :with => 'Jimmy'
|
208
|
-
end
|
209
|
-
|
210
|
-
within_table('Employee') do
|
211
|
-
fill_in 'Name', :with => 'Jimmy'
|
212
|
-
end
|
213
|
-
|
214
|
-
You can also specify a scope to be used for future searches with the <tt>scope_to</tt>.
|
215
|
-
It returns a handle to the session scoped to the provided selector.
|
216
|
-
|
217
|
-
scope = page.scope_to("//div[@id='foo']")
|
218
|
-
scope.has_xpath("//a[@class='bar']")
|
219
|
-
|
220
|
-
You can also chain scopes by calling <tt>scope_to</tt> on an existing scope.
|
221
|
-
|
222
|
-
more_scope = scope.scope_to("//p")
|
223
|
-
more_scope.has_xpath("//a[@class='baz']")
|
224
|
-
|
225
181
|
=== Querying
|
226
182
|
|
227
183
|
Capybara has a rich set of options for querying the page for the existence of
|
228
184
|
certain elements, and working with and manipulating those elements.
|
229
185
|
|
186
|
+
page.has_selector?('table tr')
|
187
|
+
page.has_selector?(:xpath, '//table/tr')
|
188
|
+
page.has_no_selector?(:content)
|
189
|
+
|
230
190
|
page.has_xpath?('//table/tr')
|
231
191
|
page.has_css?('table tr.foo')
|
232
192
|
page.has_content?('foo')
|
233
193
|
|
234
|
-
You can use with
|
194
|
+
You can these use with RSpec's magic matchers:
|
195
|
+
|
196
|
+
page.should have_selector('table tr')
|
197
|
+
page.should have_selector(:xpath, '//table/tr')
|
198
|
+
page.should have_no_selector(:content)
|
235
199
|
|
236
200
|
page.should have_xpath('//table/tr')
|
237
201
|
page.should have_css('table tr.foo')
|
@@ -242,16 +206,54 @@ Note that <tt>page.should have_no_xpath</tt> is preferred over
|
|
242
206
|
<tt>page.should_not have_xpath</tt>. Read the section on asynchronous JavaScript
|
243
207
|
for an explanation.
|
244
208
|
|
209
|
+
=== Finding
|
210
|
+
|
245
211
|
You can also find specific elements, in order to manipulate them:
|
246
212
|
|
247
213
|
find_field('First Name').value
|
248
214
|
find_link('Hello').visible?
|
249
215
|
find_button('Send').click
|
250
216
|
|
251
|
-
find(
|
252
|
-
|
217
|
+
find(:xpath, "//table/tr").click
|
218
|
+
find("#overlay").find("h1").click
|
253
219
|
all('a').each { |a| a[:href] }
|
254
220
|
|
221
|
+
Note that <tt>find</tt> will wait for an element to appear on the page, as explained in the
|
222
|
+
AJAX section. If the element does not appear it will raise an error.
|
223
|
+
|
224
|
+
These elements all have all the Capybara DSL methods available, so you can restrict them
|
225
|
+
to specific parts of the page:
|
226
|
+
|
227
|
+
find('#navigation').click_link('Home')
|
228
|
+
find('#navigation').should have_button('Sign out')
|
229
|
+
|
230
|
+
=== Scoping
|
231
|
+
|
232
|
+
Capybara makes it possible to restrict certain actions, such as interacting with
|
233
|
+
forms or clicking links and buttons, to within a specific area of the page. For
|
234
|
+
this purpose you can use the generic <tt>within</tt> method. Optionally you can
|
235
|
+
specify which kind of selector to use.
|
236
|
+
|
237
|
+
within("li#employee") do
|
238
|
+
fill_in 'Name', :with => 'Jimmy'
|
239
|
+
end
|
240
|
+
|
241
|
+
within(:xpath, "//li[@id='employee']") do
|
242
|
+
fill_in 'Name', :with => 'Jimmy'
|
243
|
+
end
|
244
|
+
|
245
|
+
There are special methods for restricting the scope to a specific fieldset,
|
246
|
+
identified by either an id or the text of the fieldet's legend tag, and to a
|
247
|
+
specific table, identified by either id or text of the table's caption tag.
|
248
|
+
|
249
|
+
within_fieldset('Employee') do
|
250
|
+
fill_in 'Name', :with => 'Jimmy'
|
251
|
+
end
|
252
|
+
|
253
|
+
within_table('Employee') do
|
254
|
+
fill_in 'Name', :with => 'Jimmy'
|
255
|
+
end
|
256
|
+
|
255
257
|
=== Scripting
|
256
258
|
|
257
259
|
In drivers which support it, you can easily execute JavaScript:
|
@@ -297,8 +299,8 @@ is (the default is 2 seconds):
|
|
297
299
|
Be aware that because of this behaviour, the following two statements are *not*
|
298
300
|
equivalent, and you should *always* use the latter!
|
299
301
|
|
300
|
-
page.should_not have_xpath('
|
301
|
-
page.should have_no_xpath('
|
302
|
+
page.should_not have_xpath('a')
|
303
|
+
page.should have_no_xpath('a')
|
302
304
|
|
303
305
|
The former would incorrectly wait for the content to appear, since the
|
304
306
|
asynchronous process has not yet removed the element from the page, it would
|
@@ -329,18 +331,23 @@ examples. Just load the DSL and include it anywhere:
|
|
329
331
|
|
330
332
|
== Calling remote servers
|
331
333
|
|
332
|
-
Normally Capybara expects to be testing an in-process Rack application, but you
|
334
|
+
Normally Capybara expects to be testing an in-process Rack application, but you
|
335
|
+
can also use it to talk to a web server running anywhere on the internets, by
|
336
|
+
setting app_host:
|
333
337
|
|
334
338
|
Capybara.current_driver = :selenium
|
335
339
|
Capybara.app_host = 'http://www.google.com'
|
336
|
-
...
|
340
|
+
...
|
337
341
|
visit('/')
|
338
342
|
|
339
|
-
Note that rack-test does not support running against a remote server. With
|
343
|
+
Note that rack-test does not support running against a remote server. With
|
344
|
+
drivers that support it, you can also visit any URL directly:
|
340
345
|
|
341
346
|
visit('http://www.google.com')
|
342
347
|
|
343
|
-
By default Capybara will try to boot a rack application automatically. You
|
348
|
+
By default Capybara will try to boot a rack application automatically. You
|
349
|
+
might want to switch off Capybara's rack server if you are running against a
|
350
|
+
remote application:
|
344
351
|
|
345
352
|
Capybara.run_server = false
|
346
353
|
|
@@ -357,42 +364,105 @@ For ultimate control, you can instantiate and use a session manually.
|
|
357
364
|
end
|
358
365
|
session.click_link 'Sign in'
|
359
366
|
|
360
|
-
== XPath and
|
367
|
+
== XPath, CSS and selectors
|
361
368
|
|
362
369
|
Capybara does not try to guess what kind of selector you are going to give it,
|
363
|
-
if you want to use
|
370
|
+
if you want to use XPath with your 'within' declarations for example, you'll need
|
364
371
|
to do:
|
365
372
|
|
366
|
-
within(:
|
367
|
-
find(:
|
368
|
-
|
373
|
+
within(:xpath, '//ul/li') { ... }
|
374
|
+
find(:xpath, '//ul/li').text
|
375
|
+
find(:xpath, '//li[contains(.//a[@href = "#"]/text(), "foo")]').value
|
369
376
|
|
370
|
-
Alternatively you can set the default selector to
|
371
|
-
moving from Webrat and used CSS a lot, or simply generally prefer CSS:
|
377
|
+
Alternatively you can set the default selector to XPath:
|
372
378
|
|
373
|
-
Capybara.default_selector = :
|
374
|
-
|
375
|
-
find('ul li').text
|
376
|
-
locate('input#name').value
|
379
|
+
Capybara.default_selector = :xpath
|
380
|
+
find('//ul/li').text
|
377
381
|
|
378
|
-
|
382
|
+
Capybara allows you to add custom selectors, which can be very useful if you
|
383
|
+
find yourself using the same kinds of selectors very often:
|
384
|
+
|
385
|
+
Capybara::Selector.add(:id) { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
|
386
|
+
Capybara::Selector.add(:row) { |num| ".//tbody/tr[#{num}]" }
|
387
|
+
|
388
|
+
These must always return an XPath expression as a String, or an XPath expression
|
389
|
+
generated through the XPath gem. You can now use these selectors like this:
|
390
|
+
|
391
|
+
find(:id, 'post_123')
|
392
|
+
find(:row, 3)
|
379
393
|
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
394
|
+
You can specify an optional :for option which will automatically use the
|
395
|
+
selector if it matches the argument to find using ===:
|
396
|
+
|
397
|
+
Capybara::Selector.add(:id, :for => Symbol) { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
|
398
|
+
|
399
|
+
Now use it like this:
|
400
|
+
|
401
|
+
find(:post_123)
|
402
|
+
|
403
|
+
This :id selector is already built into Capybara by default, so you don't
|
404
|
+
need to add it yourself.
|
405
|
+
|
406
|
+
== Beware the XPath // trap
|
407
|
+
|
408
|
+
In XPath the expression // means something very specific, and it might not be what
|
409
|
+
you think. Contrary to common belief, // means "anywhere in the document" not "anywhere
|
410
|
+
in the current context". As an example:
|
411
|
+
|
412
|
+
page.find(:xpath, '//body').all(:xpath, '//script')
|
413
|
+
|
414
|
+
You might expect this to find all script tags in the body, but actually, it finds all
|
415
|
+
script tags in the entire document, not only those in the body! What you're looking
|
416
|
+
for is the .// expression which means "any descendant of the current node":
|
417
|
+
|
418
|
+
page.find(:xpath, '//body').all(:xpath, './/script')
|
419
|
+
|
420
|
+
The same thing goes for within:
|
421
|
+
|
422
|
+
within(:xpath, '//body') do
|
423
|
+
page.find(:xpath, './/script')
|
424
|
+
within(:xpath, './/table/tbody') do
|
425
|
+
...
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
== Configuring and adding drivers
|
430
|
+
|
431
|
+
Capybara makes it convenient to switch between different drivers. It also exposes
|
432
|
+
an API to tweak those drivers with whatever settings you want, or to add your own
|
433
|
+
drivers. This is how to switch the selenium driver to use chrome:
|
434
|
+
|
435
|
+
Capybara.register_driver :selenium do |app|
|
436
|
+
Capybara::Driver::Selenium.new(app, :browser => :chrome)
|
437
|
+
end
|
438
|
+
|
439
|
+
However, it's also possible to give this a different name, so tests can switch
|
440
|
+
between using different browsers effortlessly:
|
441
|
+
|
442
|
+
Capybara.register_driver :selenium_chrome do |app|
|
443
|
+
Capybara::Driver::Selenium.new(app, :browser => :chrome)
|
444
|
+
end
|
445
|
+
|
446
|
+
Whatever is returned from the block should conform to the API described by
|
447
|
+
Capybara::Driver::Base, it does not however have to inherit from this class.
|
448
|
+
Gems can use this API to add their own drivers to Capybara.
|
449
|
+
|
450
|
+
== Gotchas:
|
385
451
|
|
386
|
-
* Access to session
|
387
|
-
|
388
|
-
|
452
|
+
* Access to session and request is not possible from the test, Access to
|
453
|
+
response is limited. Some drivers allow access to response headers and HTTP
|
454
|
+
status code, but this kind of functionality is not provided by some drivers,
|
455
|
+
such as Selenium.
|
389
456
|
|
390
457
|
* Access to Rails specific stuff (such as <tt>controller</tt>) is unavailable,
|
391
458
|
since we're not using Rails' integration testing.
|
392
459
|
|
393
|
-
*
|
394
|
-
|
395
|
-
|
460
|
+
* Freezing time: It's common practice to mock out the Time so that features
|
461
|
+
that depend on the current Date work as expected. This can be problematic,
|
462
|
+
since Capybara's AJAX timing uses the system time, resulting in Capybara
|
463
|
+
never timing out and just hanging when a failure occurs. It's still possible to
|
464
|
+
use plugins which allow you to travel in time, rather than freeze time.
|
465
|
+
One such plugin is {Timecop}[http://github.com/jtrupiano/timecop].
|
396
466
|
|
397
467
|
== License:
|
398
468
|
|
data/lib/capybara.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'timeout'
|
2
2
|
require 'nokogiri'
|
3
|
+
require 'xpath'
|
3
4
|
|
4
5
|
module Capybara
|
5
6
|
class CapybaraError < StandardError; end
|
6
7
|
class DriverNotFoundError < CapybaraError; end
|
7
8
|
class ElementNotFound < CapybaraError; end
|
8
|
-
class OptionNotFound < ElementNotFound; end
|
9
9
|
class UnselectNotAllowed < CapybaraError; end
|
10
10
|
class NotSupportedByDriverError < CapybaraError; end
|
11
11
|
class TimeoutError < CapybaraError; end
|
@@ -13,33 +13,77 @@ module Capybara
|
|
13
13
|
class InfiniteRedirectError < TimeoutError; end
|
14
14
|
|
15
15
|
class << self
|
16
|
-
attr_accessor :
|
16
|
+
attr_accessor :asset_root, :app_host, :run_server, :default_host
|
17
|
+
attr_accessor :server_port
|
17
18
|
attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements
|
18
19
|
attr_accessor :save_and_open_page_path
|
19
20
|
|
20
|
-
|
21
|
-
|
21
|
+
##
|
22
|
+
#
|
23
|
+
# Configure Capybara to suit your needs.
|
24
|
+
#
|
25
|
+
# Capybara.configure do |config|
|
26
|
+
# config.run_server = false
|
27
|
+
# config.app_host = 'http://www.google.com'
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# === Configurable options
|
31
|
+
#
|
32
|
+
# [asset_root = String] Where static assets are located, used by save_and_open_page
|
33
|
+
# [app_host = String] The default host to use when giving a relative URL to visit
|
34
|
+
# [run_server = Boolean] Whether to start a Rack server for the given Rack app (Default: true)
|
35
|
+
# [default_selector = :css/:xpath] Methods which take a selector use the given type by default (Default: CSS)
|
36
|
+
# [default_wait_time = Integer] The number of seconds to wait for asynchronous processes to finish (Default: 2)
|
37
|
+
# [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: false)
|
38
|
+
#
|
39
|
+
# === DSL Options
|
40
|
+
#
|
41
|
+
# when using capybara/dsl, the following options are also available:
|
42
|
+
#
|
43
|
+
# [default_driver = Symbol] The name of the driver to use by default. (Default: :rack_test)
|
44
|
+
# [javascript_driver = Symbol] The name of a driver to use for JavaScript enabled tests. (Default: :selenium)
|
45
|
+
#
|
46
|
+
def configure
|
47
|
+
yield self
|
22
48
|
end
|
23
49
|
|
24
|
-
|
25
|
-
|
50
|
+
##
|
51
|
+
#
|
52
|
+
# Register a new driver for Capybara.
|
53
|
+
#
|
54
|
+
# Capybara.register_driver :rack_test do |app|
|
55
|
+
# Capybara::Driver::RackTest.new(app)
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# @param [Symbol] name The name of the new driver
|
59
|
+
# @yield [app] This block takes a rack app and returns a Capybara driver
|
60
|
+
# @yieldparam [<Rack>] app The rack application that this driver runs agains. May be nil.
|
61
|
+
# @yieldreturn [Capybara::Driver::Base] A Capybara driver instance
|
62
|
+
#
|
63
|
+
def register_driver(name, &block)
|
64
|
+
drivers[name] = block
|
26
65
|
end
|
27
66
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
67
|
+
def drivers
|
68
|
+
@drivers ||= {}
|
69
|
+
end
|
70
|
+
|
71
|
+
def deprecate(method, alternate_method)
|
72
|
+
warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead"
|
31
73
|
end
|
32
74
|
end
|
33
75
|
|
34
76
|
autoload :Server, 'capybara/server'
|
35
77
|
autoload :Session, 'capybara/session'
|
36
78
|
autoload :Node, 'capybara/node'
|
37
|
-
autoload :
|
38
|
-
autoload :
|
79
|
+
autoload :Document, 'capybara/node'
|
80
|
+
autoload :Element, 'capybara/node'
|
81
|
+
autoload :Selector, 'capybara/selector'
|
39
82
|
autoload :VERSION, 'capybara/version'
|
40
83
|
|
41
84
|
module Driver
|
42
85
|
autoload :Base, 'capybara/driver/base'
|
86
|
+
autoload :Node, 'capybara/driver/node'
|
43
87
|
autoload :RackTest, 'capybara/driver/rack_test_driver'
|
44
88
|
autoload :Celerity, 'capybara/driver/celerity_driver'
|
45
89
|
autoload :Culerity, 'capybara/driver/culerity_driver'
|
@@ -47,7 +91,25 @@ module Capybara
|
|
47
91
|
end
|
48
92
|
end
|
49
93
|
|
50
|
-
Capybara.
|
51
|
-
|
52
|
-
|
53
|
-
|
94
|
+
Capybara.configure do |config|
|
95
|
+
config.run_server = true
|
96
|
+
config.default_selector = :css
|
97
|
+
config.default_wait_time = 2
|
98
|
+
config.ignore_hidden_elements = false
|
99
|
+
end
|
100
|
+
|
101
|
+
Capybara.register_driver :rack_test do |app|
|
102
|
+
Capybara::Driver::RackTest.new(app)
|
103
|
+
end
|
104
|
+
|
105
|
+
Capybara.register_driver :celerity do |app|
|
106
|
+
Capybara::Driver::Culerity.new(app)
|
107
|
+
end
|
108
|
+
|
109
|
+
Capybara.register_driver :culerity do |app|
|
110
|
+
Capybara::Driver::Culerity.new(app)
|
111
|
+
end
|
112
|
+
|
113
|
+
Capybara.register_driver :selenium do |app|
|
114
|
+
Capybara::Driver::Selenium.new(app)
|
115
|
+
end
|