capybara 2.2.1 → 2.3.0

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.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +26 -0
  3. data/README.md +36 -14
  4. data/lib/capybara.rb +6 -3
  5. data/lib/capybara/driver/base.rb +37 -1
  6. data/lib/capybara/driver/node.rb +10 -2
  7. data/lib/capybara/helpers.rb +21 -13
  8. data/lib/capybara/node/base.rb +12 -7
  9. data/lib/capybara/node/element.rb +17 -1
  10. data/lib/capybara/node/finders.rb +22 -1
  11. data/lib/capybara/node/matchers.rb +26 -5
  12. data/lib/capybara/node/simple.rb +9 -2
  13. data/lib/capybara/rack_test/css_handlers.rb +3 -1
  14. data/lib/capybara/rack_test/form.rb +3 -2
  15. data/lib/capybara/rack_test/node.rb +3 -3
  16. data/lib/capybara/rspec.rb +1 -0
  17. data/lib/capybara/rspec/features.rb +2 -1
  18. data/lib/capybara/rspec/matchers.rb +50 -5
  19. data/lib/capybara/selenium/driver.rb +76 -12
  20. data/lib/capybara/selenium/node.rb +8 -0
  21. data/lib/capybara/server.rb +1 -1
  22. data/lib/capybara/session.rb +234 -29
  23. data/lib/capybara/spec/public/jquery.js +1 -1
  24. data/lib/capybara/spec/public/test.js +7 -0
  25. data/lib/capybara/spec/session/all_spec.rb +88 -17
  26. data/lib/capybara/spec/session/assert_selector.rb +6 -0
  27. data/lib/capybara/spec/session/attach_file_spec.rb +15 -15
  28. data/lib/capybara/spec/session/body_spec.rb +4 -4
  29. data/lib/capybara/spec/session/check_spec.rb +16 -16
  30. data/lib/capybara/spec/session/choose_spec.rb +5 -5
  31. data/lib/capybara/spec/session/click_button_spec.rb +93 -84
  32. data/lib/capybara/spec/session/click_link_or_button_spec.rb +8 -8
  33. data/lib/capybara/spec/session/click_link_spec.rb +26 -19
  34. data/lib/capybara/spec/session/current_scope_spec.rb +3 -3
  35. data/lib/capybara/spec/session/current_url_spec.rb +8 -8
  36. data/lib/capybara/spec/session/evaluate_script_spec.rb +1 -1
  37. data/lib/capybara/spec/session/execute_script_spec.rb +2 -2
  38. data/lib/capybara/spec/session/fill_in_spec.rb +22 -22
  39. data/lib/capybara/spec/session/find_button_spec.rb +4 -4
  40. data/lib/capybara/spec/session/find_by_id_spec.rb +3 -3
  41. data/lib/capybara/spec/session/find_field_spec.rb +7 -7
  42. data/lib/capybara/spec/session/find_link_spec.rb +4 -4
  43. data/lib/capybara/spec/session/find_spec.rb +46 -46
  44. data/lib/capybara/spec/session/first_spec.rb +23 -23
  45. data/lib/capybara/spec/session/go_back_spec.rb +3 -3
  46. data/lib/capybara/spec/session/go_forward_spec.rb +4 -4
  47. data/lib/capybara/spec/session/has_button_spec.rb +13 -13
  48. data/lib/capybara/spec/session/has_css_spec.rb +87 -87
  49. data/lib/capybara/spec/session/has_field_spec.rb +87 -87
  50. data/lib/capybara/spec/session/has_link_spec.rb +11 -11
  51. data/lib/capybara/spec/session/has_select_spec.rb +58 -58
  52. data/lib/capybara/spec/session/has_selector_spec.rb +48 -48
  53. data/lib/capybara/spec/session/has_table_spec.rb +7 -7
  54. data/lib/capybara/spec/session/has_text_spec.rb +73 -73
  55. data/lib/capybara/spec/session/has_title_spec.rb +10 -10
  56. data/lib/capybara/spec/session/has_xpath_spec.rb +44 -44
  57. data/lib/capybara/spec/session/headers.rb +1 -1
  58. data/lib/capybara/spec/session/html_spec.rb +9 -9
  59. data/lib/capybara/spec/session/node_spec.rb +81 -65
  60. data/lib/capybara/spec/session/reset_session_spec.rb +15 -15
  61. data/lib/capybara/spec/session/response_code.rb +1 -1
  62. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +46 -0
  63. data/lib/capybara/spec/session/save_page_spec.rb +9 -9
  64. data/lib/capybara/spec/session/{screenshot.rb → screenshot_spec.rb} +4 -2
  65. data/lib/capybara/spec/session/select_spec.rb +22 -22
  66. data/lib/capybara/spec/session/text_spec.rb +15 -10
  67. data/lib/capybara/spec/session/title_spec.rb +2 -2
  68. data/lib/capybara/spec/session/uncheck_spec.rb +7 -7
  69. data/lib/capybara/spec/session/unselect_spec.rb +14 -14
  70. data/lib/capybara/spec/session/visit_spec.rb +24 -17
  71. data/lib/capybara/spec/session/window/become_closed_spec.rb +84 -0
  72. data/lib/capybara/spec/session/window/current_window_spec.rb +25 -0
  73. data/lib/capybara/spec/session/window/open_new_window_spec.rb +28 -0
  74. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +114 -0
  75. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +83 -0
  76. data/lib/capybara/spec/session/window/window_spec.rb +141 -0
  77. data/lib/capybara/spec/session/window/windows_spec.rb +31 -0
  78. data/lib/capybara/spec/session/window/within_window_spec.rb +188 -0
  79. data/lib/capybara/spec/session/within_frame_spec.rb +9 -9
  80. data/lib/capybara/spec/session/within_spec.rb +16 -16
  81. data/lib/capybara/spec/spec_helper.rb +14 -4
  82. data/lib/capybara/spec/views/form.erb +7 -0
  83. data/lib/capybara/spec/views/popup_one.erb +1 -1
  84. data/lib/capybara/spec/views/popup_two.erb +1 -1
  85. data/lib/capybara/spec/views/with_js.erb +2 -0
  86. data/lib/capybara/spec/views/with_windows.erb +38 -0
  87. data/lib/capybara/version.rb +1 -1
  88. data/lib/capybara/window.rb +123 -0
  89. data/spec/basic_node_spec.rb +32 -32
  90. data/spec/capybara_spec.rb +6 -7
  91. data/spec/dsl_spec.rb +48 -48
  92. data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -2
  93. data/spec/fixtures/selenium_driver_rspec_success.rb +2 -2
  94. data/spec/rack_test_spec.rb +33 -19
  95. data/spec/result_spec.rb +13 -13
  96. data/spec/rspec/features_spec.rb +20 -15
  97. data/spec/rspec/matchers_spec.rb +109 -109
  98. data/spec/rspec_spec.rb +10 -10
  99. data/spec/selenium_spec.rb +31 -6
  100. data/spec/selenium_spec_chrome.rb +2 -2
  101. data/spec/server_spec.rb +13 -13
  102. metadata +51 -62
  103. checksums.yaml.gz.sig +0 -0
  104. data.tar.gz.sig +0 -0
  105. data/lib/capybara/spec/session/within_window_spec.rb +0 -45
  106. data/lib/capybara/spec/views/within_popups.erb +0 -25
  107. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f461ce522452cc01f332856bf2d2adc68364c19a
4
- data.tar.gz: 2ecab34b9e3dfd9d2df9a027d094e52995fe33fc
3
+ metadata.gz: 9aa9a8cc20ae71dd404a731f98867ba19be9d4f2
4
+ data.tar.gz: 58b4097a52c34c878ceca8b9bf8477bc20a6e32a
5
5
  SHA512:
6
- metadata.gz: 68b4bca1f71303ea1d24aaf849615d89773fcfacdff28c506e1d93de4592ad5b3f12d5c01ba3ff09756c36094421361207e0345651aa55544d124c636409e88e
7
- data.tar.gz: 1bcafd2a83f248ccdfa86c5fe01b81b7865687b622464245594e307e875d4dba3c9acaddf909df84b1a392eb2f4fc012bd4457901d0e245b9dcebb291cf0d921
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, type:
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
- ```bash
29
- gem install capybara
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.should == post_comments_path(post)
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.should have_selector('table tr')
403
- page.should have_selector(:xpath, '//table/tr')
403
+ expect(page).to have_selector('table tr')
404
+ expect(page).to have_selector(:xpath, '//table/tr')
404
405
 
405
- page.should have_xpath('//table/tr')
406
- page.should have_css('table tr.foo')
407
- page.should have_content('foo')
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').should have_button('Sign out')
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.should have_content('baz')
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.should_not have_xpath('a')
630
- page.should have_no_xpath('a')
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').should have_content('Something')
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
@@ -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: false)
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.should have_content('$100.000') }
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 recieves a rack app and port and should run a Rack handler
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'
@@ -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 within_window(handle)
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
@@ -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, 'Capybara::Driver::Node#inspect'
90
+ rescue NotSupportedByDriverError
83
91
  %(#<#{self.class} tag="#{tag_name}">)
84
92
  end
85
93
 
@@ -51,8 +51,10 @@ module Capybara
51
51
 
52
52
  ##
53
53
  #
54
- # Checks if the given count matches the given count options. By default,
55
- # when no options are given, count should be larger than zero.
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
- case
65
- when options[:between]
66
- options[:between] === count
67
- when options[:count]
68
- Integer(options[:count]) == count
69
- when options[:maximum]
70
- Integer(options[:maximum]) >= count
71
- when options[:minimum]
72
- Integer(options[:minimum]) <= count
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
- count > 0
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 gramatically correct error message.
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
@@ -40,14 +40,14 @@ module Capybara
40
40
 
41
41
  ##
42
42
  #
43
- # This method is Capybara's primary defence agains asynchronicity
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 aynchronous
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 overriden through the `seconds`
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]).any? do |type|
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, 'Capybara::Node::Element#inspect'
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
- resolve_query(Capybara::Query.new(*args))
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
  ##