capybara 2.9.0 → 2.10.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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +23 -0
  3. data/README.md +37 -30
  4. data/lib/capybara/node/actions.rb +18 -15
  5. data/lib/capybara/node/base.rb +2 -2
  6. data/lib/capybara/node/element.rb +1 -1
  7. data/lib/capybara/node/finders.rb +37 -32
  8. data/lib/capybara/node/matchers.rb +187 -171
  9. data/lib/capybara/queries/match_query.rb +1 -3
  10. data/lib/capybara/queries/selector_query.rb +48 -19
  11. data/lib/capybara/rack_test/driver.rb +3 -3
  12. data/lib/capybara/rails.rb +1 -1
  13. data/lib/capybara/rspec/features.rb +1 -1
  14. data/lib/capybara/rspec/matchers.rb +31 -22
  15. data/lib/capybara/selector/css.rb +30 -0
  16. data/lib/capybara/selector/selector.rb +24 -1
  17. data/lib/capybara/selector.rb +22 -23
  18. data/lib/capybara/session.rb +4 -4
  19. data/lib/capybara/spec/session/accept_alert_spec.rb +4 -4
  20. data/lib/capybara/spec/session/accept_confirm_spec.rb +1 -1
  21. data/lib/capybara/spec/session/accept_prompt_spec.rb +5 -5
  22. data/lib/capybara/spec/session/all_spec.rb +27 -27
  23. data/lib/capybara/spec/session/assert_current_path.rb +2 -2
  24. data/lib/capybara/spec/session/assert_selector.rb +28 -28
  25. data/lib/capybara/spec/session/assert_text.rb +20 -20
  26. data/lib/capybara/spec/session/assert_title.rb +2 -2
  27. data/lib/capybara/spec/session/attach_file_spec.rb +2 -2
  28. data/lib/capybara/spec/session/check_spec.rb +19 -10
  29. data/lib/capybara/spec/session/choose_spec.rb +4 -4
  30. data/lib/capybara/spec/session/click_button_spec.rb +18 -5
  31. data/lib/capybara/spec/session/click_link_or_button_spec.rb +6 -6
  32. data/lib/capybara/spec/session/click_link_spec.rb +13 -13
  33. data/lib/capybara/spec/session/current_url_spec.rb +2 -2
  34. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +1 -1
  35. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +1 -1
  36. data/lib/capybara/spec/session/element/matches_selector_spec.rb +21 -8
  37. data/lib/capybara/spec/session/evaluate_script_spec.rb +1 -1
  38. data/lib/capybara/spec/session/execute_script_spec.rb +2 -2
  39. data/lib/capybara/spec/session/fill_in_spec.rb +30 -30
  40. data/lib/capybara/spec/session/find_button_spec.rb +5 -5
  41. data/lib/capybara/spec/session/find_by_id_spec.rb +2 -2
  42. data/lib/capybara/spec/session/find_field_spec.rb +11 -7
  43. data/lib/capybara/spec/session/find_link_spec.rb +2 -2
  44. data/lib/capybara/spec/session/find_spec.rb +57 -48
  45. data/lib/capybara/spec/session/first_spec.rb +9 -9
  46. data/lib/capybara/spec/session/go_back_spec.rb +1 -1
  47. data/lib/capybara/spec/session/go_forward_spec.rb +1 -1
  48. data/lib/capybara/spec/session/has_button_spec.rb +12 -12
  49. data/lib/capybara/spec/session/has_css_spec.rb +73 -73
  50. data/lib/capybara/spec/session/has_current_path_spec.rb +2 -2
  51. data/lib/capybara/spec/session/has_field_spec.rb +78 -68
  52. data/lib/capybara/spec/session/has_link_spec.rb +8 -8
  53. data/lib/capybara/spec/session/has_select_spec.rb +70 -61
  54. data/lib/capybara/spec/session/has_selector_spec.rb +28 -28
  55. data/lib/capybara/spec/session/has_text_spec.rb +6 -6
  56. data/lib/capybara/spec/session/has_title_spec.rb +2 -2
  57. data/lib/capybara/spec/session/has_xpath_spec.rb +26 -26
  58. data/lib/capybara/spec/session/headers.rb +1 -1
  59. data/lib/capybara/spec/session/html_spec.rb +3 -3
  60. data/lib/capybara/spec/session/node_spec.rb +15 -15
  61. data/lib/capybara/spec/session/reset_session_spec.rb +4 -4
  62. data/lib/capybara/spec/session/response_code.rb +1 -1
  63. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +3 -3
  64. data/lib/capybara/spec/session/screenshot_spec.rb +1 -1
  65. data/lib/capybara/spec/session/select_spec.rb +30 -30
  66. data/lib/capybara/spec/session/selectors_spec.rb +6 -2
  67. data/lib/capybara/spec/session/uncheck_spec.rb +2 -2
  68. data/lib/capybara/spec/session/unselect_spec.rb +14 -14
  69. data/lib/capybara/spec/session/visit_spec.rb +2 -2
  70. data/lib/capybara/spec/session/within_frame_spec.rb +2 -2
  71. data/lib/capybara/spec/session/within_spec.rb +6 -6
  72. data/lib/capybara/spec/spec_helper.rb +1 -1
  73. data/lib/capybara/spec/test_app.rb +1 -1
  74. data/lib/capybara/spec/views/form.erb +6 -3
  75. data/lib/capybara/version.rb +1 -1
  76. data/lib/capybara.rb +2 -2
  77. data/spec/basic_node_spec.rb +5 -5
  78. data/spec/capybara_spec.rb +1 -1
  79. data/spec/dsl_spec.rb +1 -1
  80. data/spec/rack_test_spec.rb +7 -7
  81. data/spec/rspec/matchers_spec.rb +6 -6
  82. data/spec/rspec_spec.rb +1 -1
  83. data/spec/selector_spec.rb +94 -3
  84. data/spec/selenium_firefox_spec.rb +1 -1
  85. data/spec/selenium_spec_chrome.rb +1 -1
  86. data/spec/shared_selenium_session.rb +10 -10
  87. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 074717523be47e7a162c2d4bc45f5ff49737e6a8
4
- data.tar.gz: 25c95e6c9273c09663933921ba177067e622ea65
3
+ metadata.gz: 0e04794fbb1724e14269beeff9388b53a6f8603b
4
+ data.tar.gz: 377ee4cf8d61e2c1420ad7bc44b400e1f991ac30
5
5
  SHA512:
6
- metadata.gz: d1db39b289e31ac1432a30cbe5ff8ce957867e1b3fd854813d8bfa954af0babb5a89ac1ccfa21ff6d5074b112a69e4b6deb751bc9c054026bad65d9a2f7d6e0d
7
- data.tar.gz: 635c3bfb9e2d366ad8bc87a2abe075f2286e496fd2171bf32e6ef6628a55f8f95dfee2fd8e326819ca81d1dc0c85ac0dfee86d0491c5710e5c53f6e756e50c65
6
+ metadata.gz: afcaeaf6eb1aa0690b74ffa21acbaea6282b2ed0aba4382bc926ec6a6fbdd43bff3facc886e2d5558f7cf9af167a8278ef9ded0e946dbc9052168fc6583e94f4
7
+ data.tar.gz: b6be9f0cd07cc125a46f14c9a322b789547eb875252a10d217b4c1410080bf4be0c146c83361846a17a114b1c648416dca1a3301eefdb26087f215a0fa120872
data/History.md CHANGED
@@ -1,3 +1,26 @@
1
+ #2.10.0
2
+ Release date: 2016-10-05
3
+
4
+ ### Added
5
+ * Select `<button>` elements with descendant images with `alt` attributes matching the locator [Ian Lesperance]
6
+ * Locator string is optional in selector based matchers [Thomas Walpole]
7
+ * Selectors can specify their default visible setting [Thomas Walpole]
8
+ * Selector based finders and matchers can be passed a block to filter the results within the retry behavior [Thomas Walpole]
9
+
10
+ #Version 2.9.2
11
+ Release date: 2016-09-29
12
+
13
+ ### Fixed
14
+ * :label built-in selector finds nested label/control by control id if the label has no 'for' attribute [Thomas Walpole]
15
+ * Warning issued if an unknown selector type is specified [Thomas Walpole]
16
+
17
+ #Version 2.9.1
18
+ Release date: 2016-09-23
19
+
20
+ ### Fixed
21
+ * allow_label_click option did not work in some cases with Poltergeist - Issue #1762 [Thomas Walpole]
22
+ * matches_selector? should have access to all of a selectors options except the count options [Thomas Walpole]
23
+
1
24
  #Version 2.9.0
2
25
  Release date: 2016-09-19
3
26
 
data/README.md CHANGED
@@ -13,7 +13,7 @@ through an external gem.
13
13
  **Need help?** Ask on the mailing list (please do not open an issue on
14
14
  GitHub): http://groups.google.com/group/ruby-capybara
15
15
 
16
- **Note: Firefox 48** If you're using Firefox with selenium-webdriver, stay on either Firefox [45.0esr](https://ftp.mozilla.org/pub/firefox/releases/45.0esr/) or [47.0.1](https://ftp.mozilla.org/pub/firefox/releases/47.0.1/) and selenium-webdriver 2.53.4. Firefox 48 requires geckodriver and selenium-webdriver v3, the combo of which currently has multiple issues and is feature incomplete.
16
+ **Note: Firefox 48+** If you're using Firefox with selenium-webdriver, stay on either Firefox [45.0esr](https://ftp.mozilla.org/pub/firefox/releases/45.0esr/) or [47.0.1](https://ftp.mozilla.org/pub/firefox/releases/47.0.1/) and selenium-webdriver 2.53.4. Firefox 48+ requires geckodriver and selenium-webdriver v3, the combo of which currently has multiple issues and is feature incomplete.
17
17
 
18
18
  ## Table of contents
19
19
 
@@ -107,8 +107,8 @@ You can use the Capybara DSL in your steps, like so:
107
107
  ```ruby
108
108
  When /I sign in/ do
109
109
  within("#session") do
110
- fill_in 'Email', :with => 'user@example.com'
111
- fill_in 'Password', :with => 'password'
110
+ fill_in 'Email', with: 'user@example.com'
111
+ fill_in 'Password', with: 'password'
112
112
  end
113
113
  click_button 'Sign in'
114
114
  end
@@ -150,14 +150,14 @@ You can now write your specs like so:
150
150
  ```ruby
151
151
  describe "the signin process", :type => :feature do
152
152
  before :each do
153
- User.make(:email => 'user@example.com', :password => 'password')
153
+ User.make(email: 'user@example.com', password: 'password')
154
154
  end
155
155
 
156
156
  it "signs me in" do
157
157
  visit '/sessions/new'
158
158
  within("#session") do
159
- fill_in 'Email', :with => 'user@example.com'
160
- fill_in 'Password', :with => 'password'
159
+ fill_in 'Email', with: 'user@example.com'
160
+ fill_in 'Password', with: 'password'
161
161
  end
162
162
  click_button 'Sign in'
163
163
  expect(page).to have_content 'Success'
@@ -165,12 +165,12 @@ describe "the signin process", :type => :feature do
165
165
  end
166
166
  ```
167
167
 
168
- Use `:js => true` to switch to the `Capybara.javascript_driver`
168
+ Use `js: true` to switch to the `Capybara.javascript_driver`
169
169
  (`:selenium` by default), or provide a `:driver` option to switch
170
170
  to one specific driver. For example:
171
171
 
172
172
  ```ruby
173
- describe 'some stuff which requires js', :js => true do
173
+ describe 'some stuff which requires js', js: true do
174
174
  it 'will use the default js driver'
175
175
  it 'will switch to one specific driver', :driver => :webkit
176
176
  end
@@ -181,26 +181,26 @@ Capybara also comes with a built in DSL for creating descriptive acceptance test
181
181
  ```ruby
182
182
  feature "Signing in" do
183
183
  background do
184
- User.make(:email => 'user@example.com', :password => 'caplin')
184
+ User.make(email: 'user@example.com', password: 'caplin')
185
185
  end
186
186
 
187
187
  scenario "Signing in with correct credentials" do
188
188
  visit '/sessions/new'
189
189
  within("#session") do
190
- fill_in 'Email', :with => 'user@example.com'
191
- fill_in 'Password', :with => 'caplin'
190
+ fill_in 'Email', with: 'user@example.com'
191
+ fill_in 'Password', with: 'caplin'
192
192
  end
193
193
  click_button 'Sign in'
194
194
  expect(page).to have_content 'Success'
195
195
  end
196
196
 
197
- given(:other_user) { User.make(:email => 'other@example.com', :password => 'rous') }
197
+ given(:other_user) { User.make(email: 'other@example.com', password: 'rous') }
198
198
 
199
199
  scenario "Signing in as another user" do
200
200
  visit '/sessions/new'
201
201
  within("#session") do
202
- fill_in 'Email', :with => other_user.email
203
- fill_in 'Password', :with => other_user.password
202
+ fill_in 'Email', with: other_user.email
203
+ fill_in 'Password', with: other_user.password
204
204
  end
205
205
  click_button 'Sign in'
206
206
  expect(page).to have_content 'Invalid email or password'
@@ -308,7 +308,7 @@ Capybara.default_driver = :selenium
308
308
 
309
309
  However, if you are using RSpec or Cucumber, you may instead want to consider
310
310
  leaving the faster `:rack_test` as the __default_driver__, and marking only those
311
- tests that require a JavaScript-capable driver using `:js => true` or
311
+ tests that require a JavaScript-capable driver using `js: true` or
312
312
  `@javascript`, respectively. By default, JavaScript tests are run using the
313
313
  `:selenium` driver. You can change this by setting
314
314
  `Capybara.javascript_driver`.
@@ -344,7 +344,7 @@ RackTest can be configured with a set of headers like this:
344
344
 
345
345
  ```ruby
346
346
  Capybara.register_driver :rack_test do |app|
347
- Capybara::RackTest::Driver.new(app, :headers => { 'HTTP_USER_AGENT' => 'Capybara' })
347
+ Capybara::RackTest::Driver.new(app, headers: { 'HTTP_USER_AGENT' => 'Capybara' })
348
348
  end
349
349
  ```
350
350
 
@@ -448,14 +448,14 @@ click_on('Button Value')
448
448
  There are a number of tools for interacting with form elements:
449
449
 
450
450
  ```ruby
451
- fill_in('First Name', :with => 'John')
452
- fill_in('Password', :with => 'Seekrit')
453
- fill_in('Description', :with => 'Really Long Text...')
451
+ fill_in('First Name', with: 'John')
452
+ fill_in('Password', with: 'Seekrit')
453
+ fill_in('Description', with: 'Really Long Text...')
454
454
  choose('A Radio Button')
455
455
  check('A Checkbox')
456
456
  uncheck('A Checkbox')
457
457
  attach_file('Image', '/path/to/image.jpg')
458
- select('Option', :from => 'Select Box')
458
+ select('Option', from: 'Select Box')
459
459
  ```
460
460
 
461
461
  ### <a name="querying"></a>Querying
@@ -504,6 +504,13 @@ find("#overlay").find("h1").click
504
504
  all('a').each { |a| a[:href] }
505
505
  ```
506
506
 
507
+ If you need to find elements by additional attributes/properties you can also pass a filter block, which will be checked inside the normal waiting behavior.
508
+ If you find yourself needing to use this a lot you may be better off adding a [custom selector](http://www.rubydoc.info/github/jnicklas/capybara/Capybara#add_selector-class_method) or [adding a filter to an existing selector](http://www.rubydoc.info/github/jnicklas/capybara/Capybara#modify_selector-class_method).
509
+
510
+ ```ruby
511
+ find_field('First Name'){ |el| el['data-xyz'] == '123' }
512
+ ````
513
+
507
514
  **Note**: `find` will wait for an element to appear on the page, as explained in the
508
515
  Ajax section. If the element does not appear it will raise an error.
509
516
 
@@ -525,11 +532,11 @@ method. Optionally you can specify which kind of selector to use.
525
532
 
526
533
  ```ruby
527
534
  within("li#employee") do
528
- fill_in 'Name', :with => 'Jimmy'
535
+ fill_in 'Name', with: 'Jimmy'
529
536
  end
530
537
 
531
538
  within(:xpath, "//li[@id='employee']") do
532
- fill_in 'Name', :with => 'Jimmy'
539
+ fill_in 'Name', with: 'Jimmy'
533
540
  end
534
541
  ```
535
542
 
@@ -539,11 +546,11 @@ specific table, identified by either id or text of the table's caption tag.
539
546
 
540
547
  ```ruby
541
548
  within_fieldset('Employee') do
542
- fill_in 'Name', :with => 'Jimmy'
549
+ fill_in 'Name', with: 'Jimmy'
543
550
  end
544
551
 
545
552
  within_table('Employee') do
546
- fill_in 'Name', :with => 'Jimmy'
553
+ fill_in 'Name', with: 'Jimmy'
547
554
  end
548
555
  ```
549
556
 
@@ -781,9 +788,9 @@ module MyModule
781
788
  include Capybara::DSL
782
789
 
783
790
  def login!
784
- within("//form[@id='session']") do
785
- fill_in 'Email', :with => 'user@example.com'
786
- fill_in 'Password', :with => 'password'
791
+ within(:xpath, "//form[@id='session']") do
792
+ fill_in 'Email', with: 'user@example.com'
793
+ fill_in 'Password', with: 'password'
787
794
  end
788
795
  click_button 'Sign in'
789
796
  end
@@ -852,9 +859,9 @@ manually.
852
859
  require 'capybara'
853
860
 
854
861
  session = Capybara::Session.new(:webkit, my_rack_app)
855
- session.within("//form[@id='session']") do
856
- session.fill_in 'Email', :with => 'user@example.com'
857
- session.fill_in 'Password', :with => 'password'
862
+ session.within("form#session") do
863
+ session.fill_in 'Email', with: 'user@example.com'
864
+ session.fill_in 'Password', with: 'password'
858
865
  end
859
866
  session.click_button 'Sign in'
860
867
  ```
@@ -62,7 +62,7 @@ module Capybara
62
62
  # Locate a text field or text area and fill it in with the given text
63
63
  # The field can be found via its name, id or label text.
64
64
  #
65
- # page.fill_in 'Name', :with => 'Bob'
65
+ # page.fill_in 'Name', with: 'Bob'
66
66
  #
67
67
  #
68
68
  # @overload fill_in([locator], options={})
@@ -109,11 +109,12 @@ module Capybara
109
109
  allow_label_click = options.delete(:allow_label_click) { Capybara.automatic_label_click }
110
110
 
111
111
  begin
112
- find(:radio_button, locator, options).set(true)
113
- rescue Capybara::ElementNotFound => e
114
- raise unless allow_label_click
112
+ radio = find(:radio_button, locator, options)
113
+ radio.set(true)
114
+ rescue => e
115
+ raise unless allow_label_click && catch_error?(e)
115
116
  begin
116
- radio = find(:radio_button, locator, options.merge({wait: 0, visible: :hidden}))
117
+ radio ||= find(:radio_button, locator, options.merge({wait: 0, visible: :all}))
117
118
  label = find(:label, for: radio, wait: 0, visible: true)
118
119
  label.click unless radio.checked?
119
120
  rescue
@@ -145,11 +146,12 @@ module Capybara
145
146
  allow_label_click = options.delete(:allow_label_click) { Capybara.automatic_label_click }
146
147
 
147
148
  begin
148
- find(:checkbox, locator, options).set(true)
149
- rescue Capybara::ElementNotFound => e
150
- raise unless allow_label_click
149
+ cbox = find(:checkbox, locator, options)
150
+ cbox.set(true)
151
+ rescue => e
152
+ raise unless allow_label_click && catch_error?(e)
151
153
  begin
152
- cbox = find(:checkbox, locator, options.merge({wait: 0, visible: :hidden}))
154
+ cbox ||= find(:checkbox, locator, options.merge({wait: 0, visible: :all}))
153
155
  label = find(:label, for: cbox, wait: 0, visible: true)
154
156
  label.click unless cbox.checked?
155
157
  rescue
@@ -181,11 +183,12 @@ module Capybara
181
183
  allow_label_click = options.delete(:allow_label_click) { Capybara.automatic_label_click }
182
184
 
183
185
  begin
184
- find(:checkbox, locator, options).set(false)
185
- rescue Capybara::ElementNotFound => e
186
- raise unless allow_label_click
186
+ cbox = find(:checkbox, locator, options)
187
+ cbox.set(false)
188
+ rescue => e
189
+ raise unless allow_label_click && catch_error?(e)
187
190
  begin
188
- cbox = find(:checkbox, locator, options.merge({wait: 0, visible: :hidden}))
191
+ cbox ||= find(:checkbox, locator, options.merge({wait: 0, visible: :all}))
189
192
  label = find(:label, for: cbox, wait: 0, visible: true)
190
193
  label.click if cbox.checked?
191
194
  rescue
@@ -203,7 +206,7 @@ module Capybara
203
206
  # one option.
204
207
  # The select box can be found via its name, id or label text. The option can be found by its text.
205
208
  #
206
- # page.select 'March', :from => 'Month'
209
+ # page.select 'March', from: 'Month'
207
210
  #
208
211
  # @macro waiting_behavior
209
212
  #
@@ -225,7 +228,7 @@ module Capybara
225
228
  # box is a multiple select, +unselect+ can be called multiple times to unselect more than
226
229
  # one option. The select box can be found via its name, id or label text.
227
230
  #
228
- # page.unselect 'March', :from => 'Month'
231
+ # page.unselect 'March', from: 'Month'
229
232
  #
230
233
  # @macro waiting_behavior
231
234
  #
@@ -17,9 +17,9 @@ module Capybara
17
17
  #
18
18
  # session = Capybara::Session.new(:rack_test, my_app)
19
19
  # session.visit('/')
20
- # session.fill_in('Foo', :with => 'Bar') # from Capybara::Node::Actions
20
+ # session.fill_in('Foo', with: 'Bar') # from Capybara::Node::Actions
21
21
  # bar = session.find('#bar') # from Capybara::Node::Finders
22
- # bar.select('Baz', :from => 'Quox') # from Capybara::Node::Actions
22
+ # bar.select('Baz', from: 'Quox') # from Capybara::Node::Actions
23
23
  # session.has_css?('#foobar') # from Capybara::Node::Matchers
24
24
  #
25
25
  class Base
@@ -10,7 +10,7 @@ module Capybara
10
10
  # session = Capybara::Session.new(:rack_test, my_app)
11
11
  #
12
12
  # bar = session.find('#bar') # from Capybara::Node::Finders
13
- # bar.select('Baz', :from => 'Quox') # from Capybara::Node::Actions
13
+ # bar.select('Baz', from: 'Quox') # from Capybara::Node::Actions
14
14
  #
15
15
  # {Capybara::Node::Element} also has access to HTML attributes and other properties of the
16
16
  # element:
@@ -19,7 +19,7 @@ module Capybara
19
19
  #
20
20
  # page.find('#foo').find('.bar')
21
21
  # page.find(:xpath, '//div[contains(., "bar")]')
22
- # page.find('li', :text => 'Quox').click_link('Delete')
22
+ # page.find('li', text: 'Quox').click_link('Delete')
23
23
  #
24
24
  # @param (see Capybara::Node::Finders#all)
25
25
  #
@@ -28,8 +28,8 @@ module Capybara
28
28
  # @return [Capybara::Node::Element] The found element
29
29
  # @raise [Capybara::ElementNotFound] If the element can't be found before time expires
30
30
  #
31
- def find(*args)
32
- query = Capybara::Queries::SelectorQuery.new(*args)
31
+ def find(*args, &optional_filter_block)
32
+ query = Capybara::Queries::SelectorQuery.new(*args, &optional_filter_block)
33
33
  synchronize(query.wait) do
34
34
  if (query.match == :smart or query.match == :prefer_exact) and query.supports_exact?
35
35
  result = query.resolve_for(self, true)
@@ -74,9 +74,9 @@ module Capybara
74
74
  # @return [Capybara::Node::Element] The found element
75
75
  #
76
76
 
77
- def find_field(locator=nil, options={})
77
+ def find_field(locator=nil, options={}, &optional_filter_block)
78
78
  locator, options = nil, locator if locator.is_a? Hash
79
- find(:field, locator, options)
79
+ find(:field, locator, options, &optional_filter_block)
80
80
  end
81
81
  alias_method :field_labeled, :find_field
82
82
 
@@ -96,9 +96,9 @@ module Capybara
96
96
  # @option options [String, Array<String>] class Match links that match the class(es) provided
97
97
  # @return [Capybara::Node::Element] The found element
98
98
  #
99
- def find_link(locator=nil, options={})
99
+ def find_link(locator=nil, options={}, &optional_filter_block)
100
100
  locator, options = nil, locator if locator.is_a? Hash
101
- find(:link, locator, options)
101
+ find(:link, locator, options, &optional_filter_block)
102
102
  end
103
103
 
104
104
  ##
@@ -125,9 +125,9 @@ module Capybara
125
125
  # @option options [String, Array<String>] class Match links that match the class(es) provided
126
126
  # @return [Capybara::Node::Element] The found element
127
127
  #
128
- def find_button(locator=nil, options={})
128
+ def find_button(locator=nil, options={}, &optional_filter_block)
129
129
  locator, options = nil, locator if locator.is_a? Hash
130
- find(:button, locator, options)
130
+ find(:button, locator, options, &optional_filter_block)
131
131
  end
132
132
 
133
133
  ##
@@ -140,11 +140,12 @@ module Capybara
140
140
  #
141
141
  # @return [Capybara::Node::Element] The found element
142
142
  #
143
- def find_by_id(id, options={})
144
- find(:id, id, options)
143
+ def find_by_id(id, options={}, &optional_filter_block)
144
+ find(:id, id, options, &optional_filter_block)
145
145
  end
146
146
 
147
147
  ##
148
+ # @!method all([kind = Capybara.default_selector], locator = nil, options = {})
148
149
  #
149
150
  # Find all elements on the page matching the given selector
150
151
  # and options.
@@ -168,42 +169,45 @@ module Capybara
168
169
  # The set of found elements can further be restricted by specifying
169
170
  # options. It's possible to select elements by their text or visibility:
170
171
  #
171
- # page.all('a', :text => 'Home')
172
- # page.all('#menu li', :visible => true)
172
+ # page.all('a', text: 'Home')
173
+ # page.all('#menu li', visible: true)
173
174
  #
174
175
  # By default if no elements are found, an empty array is returned;
175
176
  # however, expectations can be set on the number of elements to be found which
176
177
  # will trigger Capybara's waiting behavior for the expectations to match.The
177
178
  # expectations can be set using
178
179
  #
179
- # page.assert_selector('p#foo', :count => 4)
180
- # page.assert_selector('p#foo', :maximum => 10)
181
- # page.assert_selector('p#foo', :minimum => 1)
182
- # page.assert_selector('p#foo', :between => 1..10)
180
+ # page.assert_selector('p#foo', count: 4)
181
+ # page.assert_selector('p#foo', maximum: 10)
182
+ # page.assert_selector('p#foo', minimum: 1)
183
+ # page.assert_selector('p#foo', between: 1..10)
183
184
  #
184
185
  # See {Capybara::Helpers#matches_count?} for additional information about
185
186
  # count matching.
186
187
  #
187
- # @overload all([kind], locator, options)
188
- # @param [:css, :xpath] kind The type of selector
189
- # @param [String] locator The selector
190
- # @option options [String, Regexp] text Only find elements which contain this text or match this regexp
191
- # @option options [Boolean, Symbol] visible Only find elements with the specified visibility:
188
+ # @param [Symbol] kind Optional selector type (:css, :xpath, :field, etc.) - Defaults to Capybara.default_selector
189
+ # @param [String] locator The selector
190
+ # @option options [String, Regexp] text Only find elements which contain this text or match this regexp
191
+ # @option options [Boolean, Symbol] visible Only find elements with the specified visibility:
192
192
  # * true - only finds visible elements.
193
193
  # * false - finds invisible _and_ visible elements.
194
194
  # * :all - same as false; finds visible and invisible elements.
195
195
  # * :hidden - only finds invisible elements.
196
196
  # * :visible - same as true; only finds visible elements.
197
- # @option options [Integer] count Exact number of matches that are expected to be found
198
- # @option options [Integer] maximum Maximum number of matches that are expected to be found
199
- # @option options [Integer] minimum Minimum number of matches that are expected to be found
200
- # @option options [Range] between Number of matches found must be within the given range
201
- # @option options [Boolean] exact Control whether `is` expressions in the given XPath match exactly or partially
202
- # @option options [Integer] wait (Capybara.default_max_wait_time) The time to wait for element count expectations to become true
197
+ # @option options [Integer] count Exact number of matches that are expected to be found
198
+ # @option options [Integer] maximum Maximum number of matches that are expected to be found
199
+ # @option options [Integer] minimum Minimum number of matches that are expected to be found
200
+ # @option options [Range] between Number of matches found must be within the given range
201
+ # @option options [Boolean] exact Control whether `is` expressions in the given XPath match exactly or partially
202
+ # @option options [Integer] wait (Capybara.default_max_wait_time) The time to wait for element count expectations to become true
203
+ # @overload all([kind = Capybara.default_selector], locator = nil, options = {})
204
+ # @overload all([kind = Capybara.default_selector], locator = nil, options = {}, &filter_block)
205
+ # @yieldparam element [Capybara::Node::Element] The element being considered for inclusion in the results
206
+ # @yieldreturn [Boolean] Should the element be considered in the results?
203
207
  # @return [Capybara::Result] A collection of found elements
204
208
  #
205
- def all(*args)
206
- query = Capybara::Queries::SelectorQuery.new(*args)
209
+ def all(*args, &optional_filter_block)
210
+ query = Capybara::Queries::SelectorQuery.new(*args, &optional_filter_block)
207
211
  synchronize(query.wait) do
208
212
  result = query.resolve_for(self)
209
213
  raise Capybara::ExpectationNotMet, result.failure_message unless result.matches_count?
@@ -227,15 +231,16 @@ module Capybara
227
231
  # @param [Hash] options Additional options; see {#all}
228
232
  # @return [Capybara::Node::Element] The found element or nil
229
233
  #
230
- def first(*args)
234
+ def first(*args, &optional_filter_block)
231
235
  if Capybara.wait_on_first_by_default
232
236
  options = if args.last.is_a?(Hash) then args.pop.dup else {} end
233
237
  args.push({minimum: 1}.merge(options))
234
238
  end
235
- all(*args).first
239
+ all(*args, &optional_filter_block).first
236
240
  rescue Capybara::ExpectationNotMet
237
241
  nil
238
242
  end
243
+
239
244
  end
240
245
  end
241
246
  end