Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #1506 from jnicklas/first_waiting

add Capybara.wait_on_first_by_default setting to control default behavior of Node#first
  • Loading branch information...
commit 37ee1a3cc3b942370b2d74108fa8bf8ad32c9fcd 2 parents ba5ba34 + a8c3812
@twalpole twalpole authored
View
5 lib/capybara.rb
@@ -22,7 +22,7 @@ class << self
attr_accessor :asset_host, :app_host, :run_server, :default_host, :always_include_port
attr_accessor :server_port, :exact, :match, :exact_options, :visible_text_only
attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements
- attr_accessor :save_and_open_page_path, :automatic_reload, :raise_server_errors, :server_errors
+ attr_accessor :save_and_open_page_path, :wait_on_first_by_default, :automatic_reload, :raise_server_errors, :server_errors
attr_writer :default_driver, :current_driver, :javascript_driver, :session_name, :server_host
attr_accessor :app
@@ -48,7 +48,7 @@ class << self
# [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: true)
# [automatic_reload = Boolean] Whether to automatically reload elements as Capybara is waiting (Default: true)
# [save_and_open_page_path = String] Where to put pages saved through save_and_open_page (Default: Dir.pwd)
- #
+ # [wait_on_first_by_default = Boolean] Whether Node#first defaults to Capybara waiting behavior for at least 1 element to match (Default: false)
# === DSL Options
#
# when using capybara/dsl, the following options are also available:
@@ -369,6 +369,7 @@ module Selenium; end
config.raise_server_errors = true
config.server_errors = [StandardError]
config.visible_text_only = false
+ config.wait_on_first_by_default = false
end
Capybara.register_driver :rack_test do |app|
View
6 lib/capybara/node/finders.rb
@@ -166,7 +166,13 @@ def all(*args)
# @return [Capybara::Node::Element] The found element or nil
#
def first(*args)
+ if Capybara.wait_on_first_by_default
+ options = if args.last.is_a?(Hash) then args.pop.dup else {} end
+ args.push({minimum: 1}.merge(options))
+ end
all(*args).first
+ rescue Capybara::ExpectationNotMet
+ nil
end
end
end
View
4 lib/capybara/selector.rb
@@ -150,7 +150,7 @@ def describe &block
Capybara.add_selector(:link) do
xpath { |locator| XPath::HTML.link(locator) }
filter(:href) do |node, href|
- node.first(:xpath, XPath.axis(:self)[XPath.attr(:href).equals(href.to_s)])
+ node.first(:xpath, XPath.axis(:self)[XPath.attr(:href).equals(href.to_s)], minimum: 0)
end
describe { |options| " with href #{options[:href].inspect}" if options[:href] }
end
@@ -210,7 +210,7 @@ def describe &block
actual = node.all(:xpath, './/option').map { |option| option.text }
options.sort == actual.sort
end
- filter(:with_options) { |node, options| options.all? { |option| node.first(:option, option) } }
+ filter(:with_options) { |node, options| options.all? { |option| node.first(:option, option, minimum: 0) } }
filter(:selected) do |node, selected|
actual = node.all(:xpath, './/option').select { |option| option.selected? }.map { |option| option.text }
[selected].flatten.sort == actual.sort
View
24 lib/capybara/spec/session/first_spec.rb
@@ -85,4 +85,28 @@
end
end
end
+
+ context "with Capybara.first_default_waiting", requires: [:js] do
+ before do
+ @session.visit('/with_js')
+ end
+
+ it "should not wait if false" do
+ Capybara.wait_on_first_by_default = false
+ @session.click_link('clickable')
+ expect(@session.first(:css, 'a#has-been-clicked')).to be_nil
+ end
+
+ it "should wait for at least one match if true" do
+ Capybara.wait_on_first_by_default = true
+ @session.click_link('clickable')
+ expect(@session.first(:css, 'a#has-been-clicked')).not_to be_nil
+ end
+
+ it "should return nil after waiting if no match" do
+ Capybara.wait_on_first_by_default = true
+ @session.click_link('clickable')
+ expect(@session.first(:css, 'a#not-a-real-link')).to be_nil
+ end
+ end
end
View
1  lib/capybara/spec/spec_helper.rb
@@ -33,6 +33,7 @@ def reset!
Capybara.raise_server_errors = true
Capybara.visible_text_only = false
Capybara.match = :smart
+ Capybara.wait_on_first_by_default = false
end
def filter(requires, metadata)
Please sign in to comment.
Something went wrong with that request. Please try again.