capybara 2.2.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +26 -0
- data/README.md +36 -14
- data/lib/capybara.rb +6 -3
- data/lib/capybara/driver/base.rb +37 -1
- data/lib/capybara/driver/node.rb +10 -2
- data/lib/capybara/helpers.rb +21 -13
- data/lib/capybara/node/base.rb +12 -7
- data/lib/capybara/node/element.rb +17 -1
- data/lib/capybara/node/finders.rb +22 -1
- data/lib/capybara/node/matchers.rb +26 -5
- data/lib/capybara/node/simple.rb +9 -2
- data/lib/capybara/rack_test/css_handlers.rb +3 -1
- data/lib/capybara/rack_test/form.rb +3 -2
- data/lib/capybara/rack_test/node.rb +3 -3
- data/lib/capybara/rspec.rb +1 -0
- data/lib/capybara/rspec/features.rb +2 -1
- data/lib/capybara/rspec/matchers.rb +50 -5
- data/lib/capybara/selenium/driver.rb +76 -12
- data/lib/capybara/selenium/node.rb +8 -0
- data/lib/capybara/server.rb +1 -1
- data/lib/capybara/session.rb +234 -29
- data/lib/capybara/spec/public/jquery.js +1 -1
- data/lib/capybara/spec/public/test.js +7 -0
- data/lib/capybara/spec/session/all_spec.rb +88 -17
- data/lib/capybara/spec/session/assert_selector.rb +6 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +15 -15
- data/lib/capybara/spec/session/body_spec.rb +4 -4
- data/lib/capybara/spec/session/check_spec.rb +16 -16
- data/lib/capybara/spec/session/choose_spec.rb +5 -5
- data/lib/capybara/spec/session/click_button_spec.rb +93 -84
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +8 -8
- data/lib/capybara/spec/session/click_link_spec.rb +26 -19
- data/lib/capybara/spec/session/current_scope_spec.rb +3 -3
- data/lib/capybara/spec/session/current_url_spec.rb +8 -8
- data/lib/capybara/spec/session/evaluate_script_spec.rb +1 -1
- data/lib/capybara/spec/session/execute_script_spec.rb +2 -2
- data/lib/capybara/spec/session/fill_in_spec.rb +22 -22
- data/lib/capybara/spec/session/find_button_spec.rb +4 -4
- data/lib/capybara/spec/session/find_by_id_spec.rb +3 -3
- data/lib/capybara/spec/session/find_field_spec.rb +7 -7
- data/lib/capybara/spec/session/find_link_spec.rb +4 -4
- data/lib/capybara/spec/session/find_spec.rb +46 -46
- data/lib/capybara/spec/session/first_spec.rb +23 -23
- data/lib/capybara/spec/session/go_back_spec.rb +3 -3
- data/lib/capybara/spec/session/go_forward_spec.rb +4 -4
- data/lib/capybara/spec/session/has_button_spec.rb +13 -13
- data/lib/capybara/spec/session/has_css_spec.rb +87 -87
- data/lib/capybara/spec/session/has_field_spec.rb +87 -87
- data/lib/capybara/spec/session/has_link_spec.rb +11 -11
- data/lib/capybara/spec/session/has_select_spec.rb +58 -58
- data/lib/capybara/spec/session/has_selector_spec.rb +48 -48
- data/lib/capybara/spec/session/has_table_spec.rb +7 -7
- data/lib/capybara/spec/session/has_text_spec.rb +73 -73
- data/lib/capybara/spec/session/has_title_spec.rb +10 -10
- data/lib/capybara/spec/session/has_xpath_spec.rb +44 -44
- data/lib/capybara/spec/session/headers.rb +1 -1
- data/lib/capybara/spec/session/html_spec.rb +9 -9
- data/lib/capybara/spec/session/node_spec.rb +81 -65
- data/lib/capybara/spec/session/reset_session_spec.rb +15 -15
- data/lib/capybara/spec/session/response_code.rb +1 -1
- data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +46 -0
- data/lib/capybara/spec/session/save_page_spec.rb +9 -9
- data/lib/capybara/spec/session/{screenshot.rb → screenshot_spec.rb} +4 -2
- data/lib/capybara/spec/session/select_spec.rb +22 -22
- data/lib/capybara/spec/session/text_spec.rb +15 -10
- data/lib/capybara/spec/session/title_spec.rb +2 -2
- data/lib/capybara/spec/session/uncheck_spec.rb +7 -7
- data/lib/capybara/spec/session/unselect_spec.rb +14 -14
- data/lib/capybara/spec/session/visit_spec.rb +24 -17
- data/lib/capybara/spec/session/window/become_closed_spec.rb +84 -0
- data/lib/capybara/spec/session/window/current_window_spec.rb +25 -0
- data/lib/capybara/spec/session/window/open_new_window_spec.rb +28 -0
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +114 -0
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +83 -0
- data/lib/capybara/spec/session/window/window_spec.rb +141 -0
- data/lib/capybara/spec/session/window/windows_spec.rb +31 -0
- data/lib/capybara/spec/session/window/within_window_spec.rb +188 -0
- data/lib/capybara/spec/session/within_frame_spec.rb +9 -9
- data/lib/capybara/spec/session/within_spec.rb +16 -16
- data/lib/capybara/spec/spec_helper.rb +14 -4
- data/lib/capybara/spec/views/form.erb +7 -0
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/with_js.erb +2 -0
- data/lib/capybara/spec/views/with_windows.erb +38 -0
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +123 -0
- data/spec/basic_node_spec.rb +32 -32
- data/spec/capybara_spec.rb +6 -7
- data/spec/dsl_spec.rb +48 -48
- data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -2
- data/spec/fixtures/selenium_driver_rspec_success.rb +2 -2
- data/spec/rack_test_spec.rb +33 -19
- data/spec/result_spec.rb +13 -13
- data/spec/rspec/features_spec.rb +20 -15
- data/spec/rspec/matchers_spec.rb +109 -109
- data/spec/rspec_spec.rb +10 -10
- data/spec/selenium_spec.rb +31 -6
- data/spec/selenium_spec_chrome.rb +2 -2
- data/spec/server_spec.rb +13 -13
- metadata +51 -62
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/capybara/spec/session/within_window_spec.rb +0 -45
- data/lib/capybara/spec/views/within_popups.erb +0 -25
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9aa9a8cc20ae71dd404a731f98867ba19be9d4f2
|
4
|
+
data.tar.gz: 58b4097a52c34c878ceca8b9bf8477bc20a6e32a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f49792d051b3a87893c10becbb4866eff4cee8a6e9d146a3adfec388df1373c1fe382c390ac9f982de24845c8ea4297a0f168ade5318c628611d1043752cafb
|
7
|
+
data.tar.gz: c707670017ac8f9b9cd335c1cd006724f84d56747c79f7e4ebf4203b4cdac39fa3e211b11c7c8e2819dbd8556bb2c49876e945c37328c47e84bc465e679aa034
|
data/History.md
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
# Version 2.3.0
|
2
|
+
|
3
|
+
Release date: 2014-06-02
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* New window management API [Andrey Botalov]
|
7
|
+
* Speed improvement for visible text detection in RackTest [Thomas Walpole]
|
8
|
+
Thanks to Phillipe Creux for instigating this
|
9
|
+
* RSpec 3 compatability
|
10
|
+
* 'save_and_open_screenshot' functionality [Greg Lazarev]
|
11
|
+
* Server errors raised on visit and synchronize [Jonas Nicklas]
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
|
15
|
+
* CSSHandlers now derives from BasicObject so globally included functions (concat, etc) shouldn't cause issues [Thomas Walpole]
|
16
|
+
* touched reset after session is reset [lesliepc16]
|
17
|
+
|
18
|
+
# Version 2.2.1
|
19
|
+
|
20
|
+
Release date: 2014-01-06
|
21
|
+
|
22
|
+
### Fixed
|
23
|
+
|
24
|
+
* Reverted a change in 2.2.0 which navigates to an empty file on `reset`.
|
25
|
+
Capybara, now visits `about:blank` like it did before. [Jonas Nicklas]
|
26
|
+
|
1
27
|
# Version 2.2.0
|
2
28
|
|
3
29
|
Release date: 2013-11-21
|
data/README.md
CHANGED
@@ -23,10 +23,11 @@ GitHub): http://groups.google.com/group/ruby-capybara
|
|
23
23
|
|
24
24
|
## Setup
|
25
25
|
|
26
|
-
Capybara requires Ruby 1.9.3 or later. To install,
|
26
|
+
Capybara requires Ruby 1.9.3 or later. To install, add this line to your
|
27
|
+
`Gemfile` and run `bundle install`:
|
27
28
|
|
28
|
-
```
|
29
|
-
gem
|
29
|
+
```ruby
|
30
|
+
gem 'capybara'
|
30
31
|
```
|
31
32
|
|
32
33
|
If the application that you are testing is a Rails app, add this line to your test helper file:
|
@@ -342,7 +343,7 @@ You can get the [current path](http://rubydoc.info/github/jnicklas/capybara/mast
|
|
342
343
|
of the browsing session for test assertions:
|
343
344
|
|
344
345
|
```ruby
|
345
|
-
current_path.
|
346
|
+
expect(current_path).to eq(post_comments_path(post))
|
346
347
|
```
|
347
348
|
|
348
349
|
### Clicking links and buttons
|
@@ -399,12 +400,12 @@ has_selector?`. Read the section on asynchronous JavaScript for an explanation.
|
|
399
400
|
You can use these with RSpec's magic matchers:
|
400
401
|
|
401
402
|
```ruby
|
402
|
-
page.
|
403
|
-
page.
|
403
|
+
expect(page).to have_selector('table tr')
|
404
|
+
expect(page).to have_selector(:xpath, '//table/tr')
|
404
405
|
|
405
|
-
page.
|
406
|
-
page.
|
407
|
-
page.
|
406
|
+
expect(page).to have_xpath('//table/tr')
|
407
|
+
expect(page).to have_css('table tr.foo')
|
408
|
+
expect(page).to have_content('foo')
|
408
409
|
```
|
409
410
|
|
410
411
|
### Finding
|
@@ -431,7 +432,7 @@ to specific parts of the page:
|
|
431
432
|
|
432
433
|
```ruby
|
433
434
|
find('#navigation').click_link('Home')
|
434
|
-
find('#navigation').
|
435
|
+
expect(find('#navigation')).to have_button('Sign out')
|
435
436
|
```
|
436
437
|
|
437
438
|
### Scoping
|
@@ -466,6 +467,21 @@ within_table('Employee') do
|
|
466
467
|
end
|
467
468
|
```
|
468
469
|
|
470
|
+
### Working with windows
|
471
|
+
|
472
|
+
Capybara provides some methods to ease finding and switching windows:
|
473
|
+
|
474
|
+
```ruby
|
475
|
+
facebook_window = window_opened_by do
|
476
|
+
click_button 'Like'
|
477
|
+
end
|
478
|
+
within_window facebook_window do
|
479
|
+
find('#login_email').set('a@example.com')
|
480
|
+
find('#login_password').set('qwerty')
|
481
|
+
click_button 'Submit'
|
482
|
+
end
|
483
|
+
```
|
484
|
+
|
469
485
|
### Scripting
|
470
486
|
|
471
487
|
In drivers which support it, you can easily execute JavaScript:
|
@@ -506,6 +522,12 @@ Finally, in drivers that support it, you can save a screenshot:
|
|
506
522
|
page.save_screenshot('screenshot.png')
|
507
523
|
```
|
508
524
|
|
525
|
+
Or have it save and automatically open:
|
526
|
+
|
527
|
+
```ruby
|
528
|
+
save_and_open_screenshot
|
529
|
+
```
|
530
|
+
|
509
531
|
## Matching
|
510
532
|
|
511
533
|
It is possible to customize how Capybara finds elements. At your disposal
|
@@ -594,7 +616,7 @@ When issuing instructions to the DSL such as:
|
|
594
616
|
```ruby
|
595
617
|
click_link('foo')
|
596
618
|
click_link('bar')
|
597
|
-
page.
|
619
|
+
expect(page).to have_content('baz')
|
598
620
|
```
|
599
621
|
|
600
622
|
If clicking on the *foo* link triggers an asynchronous process, such as
|
@@ -626,15 +648,15 @@ Capybara's Rspec matchers, however, are smart enough to handle either form.
|
|
626
648
|
The two following statements are functionally equivalent:
|
627
649
|
|
628
650
|
```ruby
|
629
|
-
page.
|
630
|
-
page.
|
651
|
+
expect(page).not_to have_xpath('a')
|
652
|
+
expect(page).to have_no_xpath('a')
|
631
653
|
```
|
632
654
|
|
633
655
|
Capybara's waiting behaviour is quite advanced, and can deal with situations
|
634
656
|
such as the following line of code:
|
635
657
|
|
636
658
|
```ruby
|
637
|
-
find('#sidebar').find('h1').
|
659
|
+
expect(find('#sidebar').find('h1')).to have_content('Something')
|
638
660
|
```
|
639
661
|
|
640
662
|
Even if JavaScript causes `#sidebar` to disappear off the page, Capybara
|
data/lib/capybara.rb
CHANGED
@@ -13,6 +13,8 @@ module Capybara
|
|
13
13
|
class UnselectNotAllowed < CapybaraError; end
|
14
14
|
class NotSupportedByDriverError < CapybaraError; end
|
15
15
|
class InfiniteRedirectError < CapybaraError; end
|
16
|
+
class ScopeError < CapybaraError; end
|
17
|
+
class WindowError < CapybaraError; end
|
16
18
|
|
17
19
|
class << self
|
18
20
|
attr_accessor :asset_host, :app_host, :run_server, :default_host, :always_include_port
|
@@ -39,7 +41,7 @@ module Capybara
|
|
39
41
|
# [run_server = Boolean] Whether to start a Rack server for the given Rack app (Default: true)
|
40
42
|
# [default_selector = :css/:xpath] Methods which take a selector use the given type by default (Default: CSS)
|
41
43
|
# [default_wait_time = Integer] The number of seconds to wait for asynchronous processes to finish (Default: 2)
|
42
|
-
# [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default:
|
44
|
+
# [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: true)
|
43
45
|
# [automatic_reload = Boolean] Whether to automatically reload elements as Capybara is waiting (Default: true)
|
44
46
|
# [save_and_open_page_path = String] Where to put pages saved through save_and_open_page (Default: Dir.pwd)
|
45
47
|
#
|
@@ -86,7 +88,7 @@ module Capybara
|
|
86
88
|
# find(:row, 3)
|
87
89
|
# page.find('table#myTable').find(:row, 3).text
|
88
90
|
# page.find('table#myTable').has_selector?(:row, 3)
|
89
|
-
# within(:row, 3) { page.
|
91
|
+
# within(:row, 3) { expect(page).to have_content('$100.000') }
|
90
92
|
#
|
91
93
|
# Here is another example:
|
92
94
|
#
|
@@ -118,7 +120,7 @@ module Capybara
|
|
118
120
|
#
|
119
121
|
# By default, Capybara will try to run webrick.
|
120
122
|
#
|
121
|
-
# @yield [app, port] This block
|
123
|
+
# @yield [app, port] This block receives a rack app and port and should run a Rack handler
|
122
124
|
#
|
123
125
|
def server(&block)
|
124
126
|
if block_given?
|
@@ -316,6 +318,7 @@ module Capybara
|
|
316
318
|
require 'capybara/helpers'
|
317
319
|
require 'capybara/session'
|
318
320
|
require 'capybara/dsl'
|
321
|
+
require 'capybara/window'
|
319
322
|
require 'capybara/server'
|
320
323
|
require 'capybara/selector'
|
321
324
|
require 'capybara/query'
|
data/lib/capybara/driver/base.rb
CHANGED
@@ -51,10 +51,46 @@ class Capybara::Driver::Base
|
|
51
51
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#within_frame'
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
54
|
+
def current_window_handle
|
55
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#current_window_handle'
|
56
|
+
end
|
57
|
+
|
58
|
+
def window_size(handle)
|
59
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#window_size'
|
60
|
+
end
|
61
|
+
|
62
|
+
def resize_window_to(handle, width, height)
|
63
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#resize_window_to'
|
64
|
+
end
|
65
|
+
|
66
|
+
def maximize_window(handle)
|
67
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#maximize_current_window'
|
68
|
+
end
|
69
|
+
|
70
|
+
def close_window(handle)
|
71
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#close_window'
|
72
|
+
end
|
73
|
+
|
74
|
+
def window_handles
|
75
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#window_handles'
|
76
|
+
end
|
77
|
+
|
78
|
+
def open_new_window
|
79
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#open_new_window'
|
80
|
+
end
|
81
|
+
|
82
|
+
def switch_to_window(handle)
|
83
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#switch_to_window'
|
84
|
+
end
|
85
|
+
|
86
|
+
def within_window(locator)
|
55
87
|
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#within_window'
|
56
88
|
end
|
57
89
|
|
90
|
+
def no_such_window_error
|
91
|
+
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#no_such_window_error'
|
92
|
+
end
|
93
|
+
|
58
94
|
def invalid_element_errors
|
59
95
|
[]
|
60
96
|
end
|
data/lib/capybara/driver/node.rb
CHANGED
@@ -40,7 +40,15 @@ module Capybara
|
|
40
40
|
def click
|
41
41
|
raise NotImplementedError
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
|
+
def right_click
|
45
|
+
raise NotImplmentedError
|
46
|
+
end
|
47
|
+
|
48
|
+
def double_click
|
49
|
+
raise NotImplementedError
|
50
|
+
end
|
51
|
+
|
44
52
|
def hover
|
45
53
|
raise NotImplementedError
|
46
54
|
end
|
@@ -79,7 +87,7 @@ module Capybara
|
|
79
87
|
|
80
88
|
def inspect
|
81
89
|
%(#<#{self.class} tag="#{tag_name}" path="#{path}">)
|
82
|
-
rescue NotSupportedByDriverError
|
90
|
+
rescue NotSupportedByDriverError
|
83
91
|
%(#<#{self.class} tag="#{tag_name}">)
|
84
92
|
end
|
85
93
|
|
data/lib/capybara/helpers.rb
CHANGED
@@ -51,8 +51,10 @@ module Capybara
|
|
51
51
|
|
52
52
|
##
|
53
53
|
#
|
54
|
-
# Checks if the given count matches the given count options.
|
55
|
-
#
|
54
|
+
# Checks if the given count matches the given count options.
|
55
|
+
# Defaults to true if no options are specified. If multiple
|
56
|
+
# options are provided, it tests that all conditions are met;
|
57
|
+
# however, if :count is supplied, all other options are ignored.
|
56
58
|
#
|
57
59
|
# @param [Integer] count The actual number. Should be coercible via Integer()
|
58
60
|
# @option [Range] between Count must be within the given range
|
@@ -61,17 +63,23 @@ module Capybara
|
|
61
63
|
# @option [Integer] minimum Count must be larger than or equal to this value
|
62
64
|
#
|
63
65
|
def matches_count?(count, options={})
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
66
|
+
return (Integer(options[:count]) == count) if options[:count]
|
67
|
+
return false if options[:maximum] && (Integer(options[:maximum]) < count)
|
68
|
+
return false if options[:minimum] && (Integer(options[:minimum]) > count)
|
69
|
+
return false if options[:between] && !(options[:between] === count)
|
70
|
+
return true
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
#
|
75
|
+
# Checks if a count of 0 is valid for the given options hash.
|
76
|
+
# Returns false if options hash does not specify any count options.
|
77
|
+
#
|
78
|
+
def expects_none?(options={})
|
79
|
+
if [:count, :maximum, :minimum, :between].any? { |k| options.has_key? k }
|
80
|
+
matches_count?(0,options)
|
73
81
|
else
|
74
|
-
|
82
|
+
false
|
75
83
|
end
|
76
84
|
end
|
77
85
|
|
@@ -104,7 +112,7 @@ module Capybara
|
|
104
112
|
#
|
105
113
|
# A poor man's `pluralize`. Given two declensions, one singular and one
|
106
114
|
# plural, as well as a count, this will pick the correct declension. This
|
107
|
-
# way we can generate
|
115
|
+
# way we can generate grammatically correct error message.
|
108
116
|
#
|
109
117
|
# @param [String] singular The singular form of the word
|
110
118
|
# @param [String] plural The plural form of the word
|
data/lib/capybara/node/base.rb
CHANGED
@@ -40,14 +40,14 @@ module Capybara
|
|
40
40
|
|
41
41
|
##
|
42
42
|
#
|
43
|
-
# This method is Capybara's primary defence
|
43
|
+
# This method is Capybara's primary defence against asynchronicity
|
44
44
|
# problems. It works by attempting to run a given block of code until it
|
45
45
|
# succeeds. The exact behaviour of this method depends on a number of
|
46
46
|
# factors. Basically there are certain exceptions which, when raised
|
47
47
|
# from the block, instead of bubbling up, are caught, and the block is
|
48
48
|
# re-run.
|
49
49
|
#
|
50
|
-
# Certain drivers, such as RackTest, have no support for
|
50
|
+
# Certain drivers, such as RackTest, have no support for asynchronous
|
51
51
|
# processes, these drivers run the block, and any error raised bubbles up
|
52
52
|
# immediately. This allows faster turn around in the case where an
|
53
53
|
# expectation fails.
|
@@ -61,16 +61,19 @@ module Capybara
|
|
61
61
|
#
|
62
62
|
# As long as any of these exceptions are thrown, the block is re-run,
|
63
63
|
# until a certain amount of time passes. The amount of time defaults to
|
64
|
-
# {Capybara.default_wait_time} and can be
|
64
|
+
# {Capybara.default_wait_time} and can be overridden through the `seconds`
|
65
65
|
# argument. This time is compared with the system time to see how much
|
66
66
|
# time has passed. If the return value of `Time.now` is stubbed out,
|
67
67
|
# Capybara will raise `Capybara::FrozenInTime`.
|
68
68
|
#
|
69
69
|
# @param [Integer] seconds Number of seconds to retry this block
|
70
|
+
# @param options [Hash]
|
71
|
+
# @option options [Array<Exception>] :errors (driver.invalid_element_errors +
|
72
|
+
# [Capybara::ElementNotFound]) exception types that cause the block to be rerun
|
70
73
|
# @return [Object] The result of the given block
|
71
74
|
# @raise [Capybara::FrozenInTime] If the return value of `Time.now` appears stuck
|
72
75
|
#
|
73
|
-
def synchronize(seconds=Capybara.default_wait_time)
|
76
|
+
def synchronize(seconds=Capybara.default_wait_time, options = {})
|
74
77
|
start_time = Time.now
|
75
78
|
|
76
79
|
if session.synchronized
|
@@ -80,8 +83,9 @@ module Capybara
|
|
80
83
|
begin
|
81
84
|
yield
|
82
85
|
rescue => e
|
86
|
+
session.raise_server_error!
|
83
87
|
raise e unless driver.wait?
|
84
|
-
raise e unless catch_error?(e)
|
88
|
+
raise e unless catch_error?(e, options[:errors])
|
85
89
|
raise e if (Time.now - start_time) >= seconds
|
86
90
|
sleep(0.05)
|
87
91
|
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
|
@@ -95,8 +99,9 @@ module Capybara
|
|
95
99
|
|
96
100
|
protected
|
97
101
|
|
98
|
-
def catch_error?(error)
|
99
|
-
(driver.invalid_element_errors + [Capybara::ElementNotFound])
|
102
|
+
def catch_error?(error, errors = nil)
|
103
|
+
errors ||= (driver.invalid_element_errors + [Capybara::ElementNotFound])
|
104
|
+
errors.any? do |type|
|
100
105
|
error.is_a?(type)
|
101
106
|
end
|
102
107
|
end
|
@@ -118,6 +118,22 @@ module Capybara
|
|
118
118
|
synchronize { base.click }
|
119
119
|
end
|
120
120
|
|
121
|
+
##
|
122
|
+
#
|
123
|
+
# Right Click the Element
|
124
|
+
#
|
125
|
+
def right_click
|
126
|
+
synchronize { base.right_click }
|
127
|
+
end
|
128
|
+
|
129
|
+
##
|
130
|
+
#
|
131
|
+
# Double Click the Element
|
132
|
+
#
|
133
|
+
def double_click
|
134
|
+
synchronize { base.double_click }
|
135
|
+
end
|
136
|
+
|
121
137
|
##
|
122
138
|
#
|
123
139
|
# Hover on the Element
|
@@ -224,7 +240,7 @@ module Capybara
|
|
224
240
|
|
225
241
|
def inspect
|
226
242
|
%(#<Capybara::Element tag="#{tag_name}" path="#{path}">)
|
227
|
-
rescue NotSupportedByDriverError
|
243
|
+
rescue NotSupportedByDriverError
|
228
244
|
%(#<Capybara::Element tag="#{tag_name}">)
|
229
245
|
end
|
230
246
|
end
|
@@ -116,17 +116,38 @@ module Capybara
|
|
116
116
|
# page.all('a', :text => 'Home')
|
117
117
|
# page.all('#menu li', :visible => true)
|
118
118
|
#
|
119
|
+
# By default if no elements are found, an empty array is returned;
|
120
|
+
# however, expectations can be set on the number of elements to be
|
121
|
+
# found using:
|
122
|
+
#
|
123
|
+
# page.assert_selector('p#foo', :count => 4)
|
124
|
+
# page.assert_selector('p#foo', :maximum => 10)
|
125
|
+
# page.assert_selector('p#foo', :minimum => 1)
|
126
|
+
# page.assert_selector('p#foo', :between => 1..10)
|
127
|
+
#
|
128
|
+
# See {Capybara::Helpers#matches_count?} for additional information about
|
129
|
+
# count matching.
|
130
|
+
#
|
119
131
|
# @overload all([kind], locator, options)
|
120
132
|
# @param [:css, :xpath] kind The type of selector
|
121
133
|
# @param [String] locator The selector
|
122
134
|
# @option options [String, Regexp] text Only find elements which contain this text or match this regexp
|
123
135
|
# @option options [Boolean] visible Only find elements that are visible on the page. Setting this to false
|
124
136
|
# finds invisible _and_ visible elements.
|
137
|
+
# @option options [Integer] count Exact number of matches that are expected to be found
|
138
|
+
# @option options [Integer] maximum Maximum number of matches that are expected to be found
|
139
|
+
# @option options [Integer] minimum Minimum number of matches that are expected to be found
|
140
|
+
# @option options [Range] between Number of matches found must be within the given range
|
125
141
|
# @option options [Boolean] exact Control whether `is` expressions in the given XPath match exactly or partially
|
126
142
|
# @return [Capybara::Result] A collection of found elements
|
127
143
|
#
|
128
144
|
def all(*args)
|
129
|
-
|
145
|
+
query = Capybara::Query.new(*args)
|
146
|
+
synchronize(query.wait) do
|
147
|
+
result = resolve_query(query)
|
148
|
+
raise(Capybara::ExpectationNotMet, result.failure_message) unless result.matches_count?
|
149
|
+
result
|
150
|
+
end
|
130
151
|
end
|
131
152
|
|
132
153
|
##
|