capybara 2.0.0.beta2 → 2.0.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +30 -1
- data/README.md +52 -31
- data/lib/capybara.rb +1 -0
- data/lib/capybara/driver/base.rb +1 -1
- data/lib/capybara/driver/node.rb +1 -0
- data/lib/capybara/dsl.rb +12 -5
- data/lib/capybara/helpers.rb +33 -0
- data/lib/capybara/node/actions.rb +4 -2
- data/lib/capybara/node/base.rb +52 -1
- data/lib/capybara/node/element.rb +0 -12
- data/lib/capybara/node/finders.rb +1 -1
- data/lib/capybara/node/matchers.rb +57 -47
- data/lib/capybara/node/simple.rb +4 -0
- data/lib/capybara/query.rb +11 -11
- data/lib/capybara/rack_test/browser.rb +14 -15
- data/lib/capybara/rack_test/driver.rb +2 -2
- data/lib/capybara/rack_test/node.rb +15 -2
- data/lib/capybara/result.rb +7 -19
- data/lib/capybara/rspec.rb +7 -4
- data/lib/capybara/rspec/features.rb +4 -1
- data/lib/capybara/rspec/matchers.rb +8 -3
- data/lib/capybara/selector.rb +1 -2
- data/lib/capybara/selenium/driver.rb +2 -2
- data/lib/capybara/selenium/node.rb +9 -7
- data/lib/capybara/session.rb +47 -31
- data/lib/capybara/spec/fixtures/another_test_file.txt +1 -0
- data/lib/capybara/spec/public/test.js +1 -1
- data/lib/capybara/spec/session/all_spec.rb +60 -62
- data/lib/capybara/spec/session/assert_selector.rb +123 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +72 -58
- data/lib/capybara/spec/session/body_spec.rb +21 -0
- data/lib/capybara/spec/session/check_spec.rb +67 -50
- data/lib/capybara/spec/session/choose_spec.rb +32 -21
- data/lib/capybara/spec/session/click_button_spec.rb +261 -221
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +40 -30
- data/lib/capybara/spec/session/click_link_spec.rb +95 -81
- data/lib/capybara/spec/session/current_url_spec.rb +70 -60
- data/lib/capybara/spec/session/evaluate_script_spec.rb +6 -0
- data/lib/capybara/spec/session/execute_script_spec.rb +7 -0
- data/lib/capybara/spec/session/fill_in_spec.rb +118 -92
- data/lib/capybara/spec/session/find_button_spec.rb +16 -14
- data/lib/capybara/spec/session/find_by_id_spec.rb +16 -14
- data/lib/capybara/spec/session/find_field_spec.rb +23 -21
- data/lib/capybara/spec/session/find_link_spec.rb +15 -14
- data/lib/capybara/spec/session/find_spec.rb +96 -91
- data/lib/capybara/spec/session/first_spec.rb +53 -55
- data/lib/capybara/spec/session/has_button_spec.rb +22 -24
- data/lib/capybara/spec/session/has_css_spec.rb +190 -205
- data/lib/capybara/spec/session/has_field_spec.rb +167 -169
- data/lib/capybara/spec/session/has_link_spec.rb +26 -29
- data/lib/capybara/spec/session/has_select_spec.rb +175 -176
- data/lib/capybara/spec/session/has_selector_spec.rb +94 -100
- data/lib/capybara/spec/session/has_table_spec.rb +22 -26
- data/lib/capybara/spec/session/has_text_spec.rb +159 -132
- data/lib/capybara/spec/session/has_xpath_spec.rb +100 -96
- data/lib/capybara/spec/session/headers.rb +4 -17
- data/lib/capybara/spec/session/html_spec.rb +15 -0
- data/lib/capybara/spec/session/node_spec.rb +172 -82
- data/lib/capybara/spec/session/reset_session_spec.rb +42 -0
- data/lib/capybara/spec/session/response_code.rb +4 -17
- data/lib/capybara/spec/session/save_page_spec.rb +46 -0
- data/lib/capybara/spec/session/screenshot.rb +8 -24
- data/lib/capybara/spec/session/select_spec.rb +100 -89
- data/lib/capybara/spec/session/source_spec.rb +12 -0
- data/lib/capybara/spec/session/text_spec.rb +15 -17
- data/lib/capybara/spec/session/uncheck_spec.rb +22 -17
- data/lib/capybara/spec/session/unselect_spec.rb +57 -52
- data/lib/capybara/spec/session/visit_spec.rb +58 -60
- data/lib/capybara/spec/session/within_frame_spec.rb +24 -26
- data/lib/capybara/spec/session/within_spec.rb +119 -121
- data/lib/capybara/spec/session/within_window_spec.rb +29 -31
- data/lib/capybara/spec/spec_helper.rb +84 -0
- data/lib/capybara/spec/test_app.rb +5 -3
- data/lib/capybara/spec/views/form.erb +1 -0
- data/lib/capybara/spec/views/with_html.erb +6 -1
- data/lib/capybara/spec/views/with_js.erb +1 -0
- data/lib/capybara/version.rb +1 -1
- data/spec/basic_node_spec.rb +2 -2
- data/spec/capybara_spec.rb +9 -0
- data/spec/dsl_spec.rb +22 -10
- data/spec/rack_test_spec.rb +28 -23
- data/spec/result_spec.rb +51 -0
- data/spec/rspec/features_spec.rb +19 -0
- data/spec/rspec/matchers_spec.rb +6 -0
- data/spec/rspec_spec.rb +1 -1
- data/spec/selenium_spec.rb +11 -25
- data/spec/server_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -46
- metadata +41 -98
- data/lib/capybara/spec/session.rb +0 -183
- data/lib/capybara/spec/session/javascript.rb +0 -290
- data/lib/capybara/util/save_and_open_page.rb +0 -45
- data/spec/save_and_open_page_spec.rb +0 -155
data/History.txt
CHANGED
@@ -2,6 +2,35 @@
|
|
2
2
|
|
3
3
|
### Changed
|
4
4
|
|
5
|
+
* `require 'capybara/rails'` will automatically enable `:respect_data_method`
|
6
|
+
on the RackTest driver, so the behavior matches Capybara 1.1.2 [Jo Liss]
|
7
|
+
* Dropped official support for Ruby 1.8.x. [Jonas Nicklas]
|
8
|
+
* All methods which find or manipulate fields or buttons now ignore them when
|
9
|
+
they are disabled. [Jonas Nicklas]
|
10
|
+
* Can no longer find elements by id via `find(:foo)`, use `find("#foo")` or
|
11
|
+
`find_by_id("foo")` instead. [Jonas Nicklas]
|
12
|
+
* Rename `Driver#body` to `Driver#html` (relevant only for driver authors) [Jo
|
13
|
+
Liss]
|
14
|
+
|
15
|
+
### Added
|
16
|
+
|
17
|
+
* Multiple files can be uploaded with `attach_file` [Jarl Friis]
|
18
|
+
|
19
|
+
### Fixed
|
20
|
+
|
21
|
+
* `has_text` (`has_content`) now accepts non-string arguments, like numbers.
|
22
|
+
[Jo Liss]
|
23
|
+
* `has_text` and `text` now correctly normalize Unicode whitespace, such as
|
24
|
+
` `. [Jo Liss]
|
25
|
+
* RackTest allows protocol relative URLs [Jonas Nicklas]
|
26
|
+
* Arguments are cast to string where necessary, so that e.g. `click_link(:foo)` works
|
27
|
+
as expected. [Jonas Nicklas]
|
28
|
+
* `:count => 0` now works as expected [Jarl Friis]
|
29
|
+
|
30
|
+
# Version 2.0.0.beta2
|
31
|
+
|
32
|
+
### Changed
|
33
|
+
|
5
34
|
* `respect_data_method` default to `false` for the RackTest driver, which means
|
6
35
|
that Capybara no longer picks up `:method => :post` et. al. from links in Rails
|
7
36
|
by default. [Jonas Nicklas]
|
@@ -77,7 +106,7 @@
|
|
77
106
|
session is reset [James Tucker, Jonas Nicklas]
|
78
107
|
* A ton of new selectors built in out of the box, like `field`, `link`, `button`,
|
79
108
|
etc... [Adam McCrea, Jonas Nicklas]
|
80
|
-
* `has_text
|
109
|
+
* `has_text?` has been added as an alias for `has_content?` [Jonas Nicklas]
|
81
110
|
* Add `Capybara.server_host` option (default: 127.0.0.1) [David Balatero]
|
82
111
|
* Add `:type` option for `page.has_field?` [Gonzalo Rodríguez]
|
83
112
|
* Custom matchers can now be specified in CSS in addition to XPath [Jonas Nicklas]
|
data/README.md
CHANGED
@@ -4,14 +4,23 @@
|
|
4
4
|
[![Dependency Status](https://gemnasium.com/jnicklas/capybara.png)](https://gemnasium.com/jnicklas/capybara)
|
5
5
|
[![Code Quality](https://codeclimate.com/badge.png)](https://codeclimate.com/github/jnicklas/capybara)
|
6
6
|
|
7
|
-
Capybara helps you test
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
Capybara helps you test web applications by simulating how a real user would
|
8
|
+
interact with your app. It is agnostic about the driver running your tests and
|
9
|
+
comes with Rack::Test and Selenium support built in. WebKit is supported
|
10
|
+
through an external gem.
|
11
11
|
|
12
12
|
**Need help?** Ask on the mailing list (please do not open an issue on
|
13
13
|
GitHub): http://groups.google.com/group/ruby-capybara
|
14
14
|
|
15
|
+
## Key benefits
|
16
|
+
|
17
|
+
- **No setup** necessary for Rails and Rack application. Works out of the box.
|
18
|
+
- **Intuitive API** which mimics the language an actual user would use.
|
19
|
+
- **Switch the backend** your tests run against from fast headless mode
|
20
|
+
to an actual browser with no changes to your tests.
|
21
|
+
- **Powerful synchronization** features mean you never have to manually wait
|
22
|
+
for asynchronous processes to complete.
|
23
|
+
|
15
24
|
## Setup
|
16
25
|
|
17
26
|
To install, type
|
@@ -32,6 +41,9 @@ If you are not using Rails, set Capybara.app to your rack app:
|
|
32
41
|
Capybara.app = MyRackApp
|
33
42
|
```
|
34
43
|
|
44
|
+
If you need to test JavaScript, or if your app interacts with (or is located at)
|
45
|
+
a remote URL, you'll need to [use a different driver](#drivers).
|
46
|
+
|
35
47
|
## Using Capybara with Cucumber
|
36
48
|
|
37
49
|
The `cucumber-rails` gem comes with Capybara support built-in. If you
|
@@ -126,11 +138,21 @@ feature "Signing up" do
|
|
126
138
|
end
|
127
139
|
click_link 'Sign in'
|
128
140
|
end
|
141
|
+
|
142
|
+
given(:other_user) { User.make(:email => 'other@example.com', :password => 'rous') }
|
143
|
+
|
144
|
+
scenario "Signing in as another user" do
|
145
|
+
within("#session") do
|
146
|
+
fill_in 'Login', :with => other_user.email
|
147
|
+
fill_in 'Password', :with => other_user.password
|
148
|
+
end
|
149
|
+
click_link 'Sign in'
|
150
|
+
end
|
129
151
|
end
|
130
152
|
```
|
131
153
|
|
132
154
|
`feature` is in fact just an alias for `describe ..., :type => :request`,
|
133
|
-
`background` is an alias for `before`,
|
155
|
+
`background` is an alias for `before`, `scenario` for `it`, and `given`/`given!` aliases for `let`/`let!`, respectively.
|
134
156
|
|
135
157
|
## Using Capybara with Test::Unit
|
136
158
|
|
@@ -217,10 +239,11 @@ Capybara uses the same DSL to drive a variety of browser and headless drivers.
|
|
217
239
|
|
218
240
|
### Selecting the Driver
|
219
241
|
|
220
|
-
By default, Capybara uses the `:rack_test` driver, which is fast but
|
221
|
-
support JavaScript
|
222
|
-
|
223
|
-
|
242
|
+
By default, Capybara uses the `:rack_test` driver, which is fast but limited: it
|
243
|
+
does not support JavaScript, nor is it able to access HTTP resources outside of
|
244
|
+
your Rack application, such as remote APIs and OAuth services. To get around
|
245
|
+
these limitations, you can set up a different default driver for your features.
|
246
|
+
For example if you'd prefer to run everything in Selenium, you could do:
|
224
247
|
|
225
248
|
```ruby
|
226
249
|
Capybara.default_driver = :selenium
|
@@ -248,15 +271,17 @@ switch in the middle of a test.
|
|
248
271
|
### RackTest
|
249
272
|
|
250
273
|
RackTest is Capybara's default driver. It is written in pure Ruby and does not
|
251
|
-
have any support for executing JavaScript. Since the RackTest driver
|
252
|
-
directly
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
274
|
+
have any support for executing JavaScript. Since the RackTest driver interacts
|
275
|
+
directly with Rack interfaces, it does not require a server to be started.
|
276
|
+
However, this means that if your application is not a Rack application (Rails,
|
277
|
+
Sinatra and most other Ruby frameworks are Rack applications) then you cannot
|
278
|
+
use this driver. Furthermore, you cannot use the RackTest driver to test a
|
279
|
+
remote application, or to access remote URLs (e.g., redirects to external
|
280
|
+
sites, external APIs, or OAuth services) that your application might interact
|
281
|
+
with.
|
282
|
+
|
257
283
|
[capybara-mechanize](https://github.com/jeroenvandijk/capybara-mechanize)
|
258
|
-
|
259
|
-
separate project.
|
284
|
+
provides a similar driver that can access remote servers.
|
260
285
|
|
261
286
|
RackTest can be configured with a set of headers like this:
|
262
287
|
|
@@ -474,14 +499,6 @@ that this may break with more complicated expressions:
|
|
474
499
|
result = page.evaluate_script('4 + 4');
|
475
500
|
```
|
476
501
|
|
477
|
-
### Saving screenshot
|
478
|
-
|
479
|
-
In drivers which support it, you can save screenshot:
|
480
|
-
|
481
|
-
```ruby
|
482
|
-
page.save_screenshot('screenshot.png')
|
483
|
-
```
|
484
|
-
|
485
502
|
### Debugging
|
486
503
|
|
487
504
|
It can be useful to take a snapshot of the page as it currently is and take a
|
@@ -501,6 +518,12 @@ print page.html
|
|
501
518
|
This is mostly useful for debugging. You should avoid testing against the
|
502
519
|
contents of `page.html` and use the more expressive finder methods instead.
|
503
520
|
|
521
|
+
Finally, in drivers that support it, you can save a screenshot:
|
522
|
+
|
523
|
+
```ruby
|
524
|
+
page.save_screenshot('screenshot.png')
|
525
|
+
```
|
526
|
+
|
504
527
|
## Transactions and database setup
|
505
528
|
|
506
529
|
Some Capybara drivers need to run against an actual HTTP server. Capybara takes
|
@@ -814,12 +837,6 @@ additional info about how the underlying driver can be configured.
|
|
814
837
|
|
815
838
|
## Development
|
816
839
|
|
817
|
-
If you found a _reproducible_ bug, open a [GitHub
|
818
|
-
Issue](http://github.com/jnicklas/capybara/issues) to submit a bug report.
|
819
|
-
|
820
|
-
Even better, send a pull request! Make sure all changes are well tested,
|
821
|
-
Capybara is a testing tool after all. Topic branches are good.
|
822
|
-
|
823
840
|
To set up a development environment, simply do:
|
824
841
|
|
825
842
|
```bash
|
@@ -827,3 +844,7 @@ git submodule update --init
|
|
827
844
|
bundle install
|
828
845
|
bundle exec rake # run the test suite
|
829
846
|
```
|
847
|
+
|
848
|
+
See
|
849
|
+
[CONTRIBUTING.md](https://github.com/jnicklas/capybara/blob/master/CONTRIBUTING.md)
|
850
|
+
for how to send issues and pull requests.
|
data/lib/capybara.rb
CHANGED
data/lib/capybara/driver/base.rb
CHANGED
data/lib/capybara/driver/node.rb
CHANGED
data/lib/capybara/dsl.rb
CHANGED
@@ -2,6 +2,15 @@ require 'capybara'
|
|
2
2
|
|
3
3
|
module Capybara
|
4
4
|
module DSL
|
5
|
+
def self.included(base)
|
6
|
+
warn "including Capybara::DSL in the global scope is not recommended!" if base == Object
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.extended(base)
|
11
|
+
warn "extending the main object with Capybara::DSL is not recommended!" if base == TOPLEVEL_BINDING.eval("self")
|
12
|
+
super
|
13
|
+
end
|
5
14
|
|
6
15
|
##
|
7
16
|
#
|
@@ -38,11 +47,9 @@ module Capybara
|
|
38
47
|
end
|
39
48
|
|
40
49
|
Session::DSL_METHODS.each do |method|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
-
RUBY
|
50
|
+
define_method method do |*args, &block|
|
51
|
+
page.send method, *args, &block
|
52
|
+
end
|
46
53
|
end
|
47
54
|
end
|
48
55
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Capybara
|
2
|
+
module Helpers
|
3
|
+
class << self
|
4
|
+
##
|
5
|
+
#
|
6
|
+
# Normalizes whitespace space by stripping leading and trailing
|
7
|
+
# whitespace and replacing sequences of whitespace characters
|
8
|
+
# with a single space.
|
9
|
+
#
|
10
|
+
# @param [String] text Text to normalize
|
11
|
+
# @return [String] Normalized text
|
12
|
+
#
|
13
|
+
def normalize_whitespace(text)
|
14
|
+
# http://en.wikipedia.org/wiki/Whitespace_character#Unicode
|
15
|
+
# We should have a better reference.
|
16
|
+
# See also http://stackoverflow.com/a/11758133/525872
|
17
|
+
text.to_s.gsub(/[\s\u0085\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000]+/, ' ').strip
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
#
|
22
|
+
# Escapes any characters that would have special meaning in a regexp
|
23
|
+
# if text is not a regexp
|
24
|
+
#
|
25
|
+
# @param [String] text Text to escape
|
26
|
+
# @return [String] Escaped text
|
27
|
+
#
|
28
|
+
def to_regexp(text)
|
29
|
+
text.is_a?(Regexp) ? text : Regexp.escape(normalize_whitespace(text))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -135,10 +135,12 @@ module Capybara
|
|
135
135
|
# page.attach_file(locator, '/path/to/file.png')
|
136
136
|
#
|
137
137
|
# @param [String] locator Which field to attach the file to
|
138
|
-
# @param [String] path The path of the file that will be attached
|
138
|
+
# @param [String] path The path of the file that will be attached, or an array of paths
|
139
139
|
#
|
140
140
|
def attach_file(locator, path)
|
141
|
-
|
141
|
+
(String === path ? [path] : path).each do |p|
|
142
|
+
raise Capybara::FileNotFound, "cannot attach file, #{p} does not exist" unless File.exist?(p.to_s)
|
143
|
+
end
|
142
144
|
find(:file_field, locator).set(path)
|
143
145
|
end
|
144
146
|
end
|
data/lib/capybara/node/base.rb
CHANGED
@@ -38,14 +38,47 @@ module Capybara
|
|
38
38
|
self
|
39
39
|
end
|
40
40
|
|
41
|
+
##
|
42
|
+
#
|
43
|
+
# This method is Capybara's primary defence agains asynchronicity
|
44
|
+
# problems. It works by attempting to run a given block of code until it
|
45
|
+
# succeeds. The exact behaviour of this method depends on a number of
|
46
|
+
# factors. Basically there are certain exceptions which, when raised
|
47
|
+
# from the block, instead of bubbling up, are caught, and the block is
|
48
|
+
# re-run.
|
49
|
+
#
|
50
|
+
# Certain drivers, such as RackTest, have no support for aynchronous
|
51
|
+
# processes, these drivers run the block, and any error raised bubbles up
|
52
|
+
# immediately. This allows faster turn around in the case where an
|
53
|
+
# expectation fails.
|
54
|
+
#
|
55
|
+
# Only exceptions that are {Capybara::ElementNotFound} or any subclass
|
56
|
+
# thereof cause the block to be rerun. Drivers may specify additional
|
57
|
+
# exceptions which also cause reruns. This usually occurs when a node is
|
58
|
+
# manipulated which no longer exists on the page. For example, the
|
59
|
+
# Selenium driver specifies
|
60
|
+
# `Selenium::WebDriver::Error::ObsoleteElementError`.
|
61
|
+
#
|
62
|
+
# As long as any of these exceptions are thrown, the block is re-run,
|
63
|
+
# until a certain amount of time passes. The amount of time defaults to
|
64
|
+
# {Capybara.default_wait_time} and can be overriden through the `seconds`
|
65
|
+
# argument. This time is compared with the system time to see how much
|
66
|
+
# time has passed. If the return value of {Time.now} is stubbed out,
|
67
|
+
# Capybara will raise `Capybara::FrozenInTime`.
|
68
|
+
#
|
69
|
+
# @param [Integer] seconds Number of seconds to retry this block
|
70
|
+
# @return [Object] The result of the given block
|
71
|
+
# @raise [Capybara::FrozenInTime] If the return value of {Time.now} appears stuck
|
72
|
+
#
|
41
73
|
def synchronize(seconds=Capybara.default_wait_time)
|
42
74
|
start_time = Time.now
|
43
75
|
|
44
76
|
begin
|
45
77
|
yield
|
46
78
|
rescue => e
|
79
|
+
raise e if @unsynchronized
|
47
80
|
raise e unless driver.wait?
|
48
|
-
raise e unless driver.invalid_element_errors.include?(e.class)
|
81
|
+
raise e unless driver.invalid_element_errors.include?(e.class) || e.is_a?(Capybara::ElementNotFound)
|
49
82
|
raise e if (Time.now - start_time) >= seconds
|
50
83
|
sleep(0.05)
|
51
84
|
raise Capybara::FrozenInTime, "time appears to be frozen, Capybara does not work with libraries which freeze time, consider using time travelling instead" if Time.now == start_time
|
@@ -54,6 +87,24 @@ module Capybara
|
|
54
87
|
end
|
55
88
|
end
|
56
89
|
|
90
|
+
##
|
91
|
+
#
|
92
|
+
# Within the given block, prevent synchronize from having any effect.
|
93
|
+
#
|
94
|
+
# This is an internal method which should not be called unless you are
|
95
|
+
# absolutely sure of what you're doing.
|
96
|
+
#
|
97
|
+
# @api private
|
98
|
+
# @return [Object] The result of the given block
|
99
|
+
#
|
100
|
+
def unsynchronized
|
101
|
+
orig = @unsynchronized
|
102
|
+
@unsynchronized = true
|
103
|
+
yield
|
104
|
+
ensure
|
105
|
+
@unsynchronized = orig
|
106
|
+
end
|
107
|
+
|
57
108
|
protected
|
58
109
|
|
59
110
|
def driver
|
@@ -177,18 +177,6 @@ module Capybara
|
|
177
177
|
synchronize { base.drag_to(node.base) }
|
178
178
|
end
|
179
179
|
|
180
|
-
def find(*args)
|
181
|
-
synchronize { super }
|
182
|
-
end
|
183
|
-
|
184
|
-
def first(*args)
|
185
|
-
synchronize { super }
|
186
|
-
end
|
187
|
-
|
188
|
-
def all(*args)
|
189
|
-
synchronize { super }
|
190
|
-
end
|
191
|
-
|
192
180
|
def reload
|
193
181
|
if @allow_reload
|
194
182
|
reloaded = parent.reload.first(@query.name, @query.locator, @query.options)
|
@@ -52,7 +52,7 @@ module Capybara
|
|
52
52
|
|
53
53
|
##
|
54
54
|
#
|
55
|
-
# Find a button on the page. The
|
55
|
+
# Find a button on the page. The button can be found by its id, name or value.
|
56
56
|
#
|
57
57
|
# @param [String] locator Which button to find
|
58
58
|
# @return [Capybara::Element] The found element
|
@@ -25,8 +25,7 @@ module Capybara
|
|
25
25
|
# has_selector? can also accept XPath expressions generated by the
|
26
26
|
# XPath gem:
|
27
27
|
#
|
28
|
-
# xpath
|
29
|
-
# page.has_selector?(:xpath, xpath)
|
28
|
+
# page.has_selector?(:xpath, XPath.descendant(:p))
|
30
29
|
#
|
31
30
|
# @param (see Capybara::Node::Finders#all)
|
32
31
|
# @option options [Integer] :count (nil) Number of times the expression should occur
|
@@ -38,14 +37,6 @@ module Capybara
|
|
38
37
|
return false
|
39
38
|
end
|
40
39
|
|
41
|
-
def assert_selector(*args)
|
42
|
-
synchronize do
|
43
|
-
result = all(*args)
|
44
|
-
result.matches_count? or raise Capybara::ExpectationNotMet, result.failure_message
|
45
|
-
end
|
46
|
-
return true
|
47
|
-
end
|
48
|
-
|
49
40
|
##
|
50
41
|
#
|
51
42
|
# Checks if a given selector is not on the page or current node.
|
@@ -60,6 +51,51 @@ module Capybara
|
|
60
51
|
return false
|
61
52
|
end
|
62
53
|
|
54
|
+
##
|
55
|
+
#
|
56
|
+
# Asserts that a given selector is on the page or current node.
|
57
|
+
#
|
58
|
+
# page.assert_selector('p#foo')
|
59
|
+
# page.assert_selector(:xpath, './/p[@id="foo"]')
|
60
|
+
# page.assert_selector(:foo)
|
61
|
+
#
|
62
|
+
# By default it will check if the expression occurs at least once,
|
63
|
+
# but a different number can be specified.
|
64
|
+
#
|
65
|
+
# page.assert_selector('p#foo', :count => 4)
|
66
|
+
#
|
67
|
+
# This will check if the expression occurs exactly 4 times.
|
68
|
+
#
|
69
|
+
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
70
|
+
# such as :text and :visible.
|
71
|
+
#
|
72
|
+
# page.assert_selector('li', :text => 'Horse', :visible => true)
|
73
|
+
#
|
74
|
+
# {assert_selector} can also accept XPath expressions generated by the
|
75
|
+
# XPath gem:
|
76
|
+
#
|
77
|
+
# page.assert_selector(:xpath, XPath.descendant(:p))
|
78
|
+
#
|
79
|
+
# @param (see Capybara::Node::Finders#all)
|
80
|
+
# @option options [Integer] :count (nil) Number of times the expression should occur
|
81
|
+
# @raise [Capybara::ExpectationNotMet] If the selector does not exist
|
82
|
+
#
|
83
|
+
def assert_selector(*args)
|
84
|
+
synchronize do
|
85
|
+
result = all(*args)
|
86
|
+
result.matches_count? or raise Capybara::ExpectationNotMet, result.failure_message
|
87
|
+
end
|
88
|
+
return true
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
#
|
93
|
+
# Asserts that a given selector is not on the page or current node.
|
94
|
+
# Usage is identical to Capybara::Node::Matchers#assert_selector
|
95
|
+
#
|
96
|
+
# @param (see Capybara::Node::Finders#assert_selector)
|
97
|
+
# @raise [Capybara::ExpectationNotMet] If the selector exists
|
98
|
+
#
|
63
99
|
def assert_no_selector(*args)
|
64
100
|
synchronize do
|
65
101
|
result = all(*args)
|
@@ -157,18 +193,17 @@ module Capybara
|
|
157
193
|
# Checks if the page or current node has the given text content,
|
158
194
|
# ignoring any HTML tags and normalizing whitespace.
|
159
195
|
#
|
160
|
-
#
|
161
|
-
#
|
196
|
+
# This only matches displayable text and specifically excludes text
|
197
|
+
# contained within non-display nodes such as script or head tags.
|
162
198
|
#
|
163
199
|
# @param [String] content The text to check for
|
164
200
|
# @return [Boolean] Whether it exists
|
165
201
|
#
|
166
202
|
def has_text?(content)
|
167
|
-
normalized_content = normalize_whitespace(content)
|
168
|
-
|
169
203
|
synchronize do
|
170
|
-
normalize_whitespace(text).match(
|
171
|
-
|
204
|
+
unless Capybara::Helpers.normalize_whitespace(text).match(Capybara::Helpers.to_regexp(content))
|
205
|
+
raise ExpectationNotMet
|
206
|
+
end
|
172
207
|
end
|
173
208
|
return true
|
174
209
|
rescue Capybara::ExpectationNotMet
|
@@ -181,18 +216,17 @@ module Capybara
|
|
181
216
|
# Checks if the page or current node does not have the given text
|
182
217
|
# content, ignoring any HTML tags and normalizing whitespace.
|
183
218
|
#
|
184
|
-
#
|
185
|
-
#
|
219
|
+
# This only matches displayable text and specifically excludes text
|
220
|
+
# contained within non-display nodes such as script or head tags.
|
186
221
|
#
|
187
222
|
# @param [String] content The text to check for
|
188
|
-
# @return [Boolean] Whether it
|
223
|
+
# @return [Boolean] Whether it doesn't exist
|
189
224
|
#
|
190
225
|
def has_no_text?(content)
|
191
|
-
normalized_content = normalize_whitespace(content)
|
192
|
-
|
193
226
|
synchronize do
|
194
|
-
|
195
|
-
|
227
|
+
if Capybara::Helpers.normalize_whitespace(text).match(Capybara::Helpers.to_regexp(content))
|
228
|
+
raise ExpectationNotMet
|
229
|
+
end
|
196
230
|
end
|
197
231
|
return true
|
198
232
|
rescue Capybara::ExpectationNotMet
|
@@ -426,30 +460,6 @@ module Capybara
|
|
426
460
|
|
427
461
|
private
|
428
462
|
|
429
|
-
##
|
430
|
-
#
|
431
|
-
# Normalizes whitespace space by stripping leading and trailing
|
432
|
-
# whitespace and replacing sequences of whitespace characters
|
433
|
-
# with a single space.
|
434
|
-
#
|
435
|
-
# @param [String] text Text to normalize
|
436
|
-
# @return [String] Normalized text
|
437
|
-
#
|
438
|
-
def normalize_whitespace(text)
|
439
|
-
text.is_a?(Regexp) ? text : text.gsub(/\s+/, ' ').strip
|
440
|
-
end
|
441
|
-
|
442
|
-
##
|
443
|
-
#
|
444
|
-
# Escapes any characters that would have special meaning in a regexp
|
445
|
-
# if text is not a regexp
|
446
|
-
#
|
447
|
-
# @param [String] text Text to escape
|
448
|
-
# @return [String] Escaped text
|
449
|
-
#
|
450
|
-
def escape_regexp(text)
|
451
|
-
text.is_a?(Regexp) ? text : Regexp.escape(text)
|
452
|
-
end
|
453
463
|
end
|
454
464
|
end
|
455
465
|
end
|