1
0
Fork 0
mirror of https://github.com/teamcapybara/capybara.git synced 2022-11-09 12:08:07 -05:00

add Capybara.wait_on_first_by_default setting to control default behavior of Node#first

This commit is contained in:
Thomas Walpole 2015-04-21 10:52:49 -07:00
parent ba5ba340e8
commit a8c3812215
5 changed files with 36 additions and 4 deletions

View file

@ -22,7 +22,7 @@ module Capybara
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 @@ module Capybara
# [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 @@ Capybara.configure do |config|
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 file

@ -166,7 +166,13 @@ module Capybara
# @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 file

@ -150,7 +150,7 @@ end
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 @@ Capybara.add_selector(:select) do
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 file

@ -85,4 +85,28 @@ Capybara::SpecHelper.spec '#first' do
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 file

@ -33,6 +33,7 @@ module Capybara
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)