capybara 0.3.9 → 0.4.0.rc
Sign up to get free protection for your applications and to get access to all the features.
- 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
|