mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
select_option/unselect_option are now called on option node
This means that we can move the find object into Capybara::Node instead of Capybara::Driver::Node which gives us AJAX waiting and preference for exact matches for free.
This commit is contained in:
parent
183da5278d
commit
8d341948fd
9 changed files with 62 additions and 74 deletions
|
@ -25,28 +25,19 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
|
|||
native.set(value)
|
||||
end
|
||||
|
||||
def select_option(option)
|
||||
native.select(option)
|
||||
rescue
|
||||
options = find("//option").map { |o| "'#{o.text}'" }.join(', ')
|
||||
raise Capybara::OptionNotFound, "No such option '#{option}' in this select box. Available options: #{options}"
|
||||
def select_option
|
||||
native.click
|
||||
end
|
||||
|
||||
def unselect_option(option)
|
||||
unless native.multiple?
|
||||
raise Capybara::UnselectNotAllowed, "Cannot unselect option '#{option}' from single select box."
|
||||
def unselect_option
|
||||
unless select_node.native.multiple?
|
||||
raise Capybara::UnselectNotAllowed, "Cannot unselect option from single select box."
|
||||
end
|
||||
|
||||
# FIXME: couldn't find a clean way to unselect, so clear and reselect
|
||||
selected_options = native.selected_options
|
||||
if unselect_option = selected_options.detect { |value| value == option } ||
|
||||
selected_options.detect { |value| value.index(option) }
|
||||
native.clear
|
||||
(selected_options - [unselect_option]).each { |value| native.select_value(value) }
|
||||
else
|
||||
options = find("//option").map { |o| "'#{o.text}'" }.join(', ')
|
||||
raise Capybara::OptionNotFound, "No such option '#{option}' in this select box. Available options: #{options}"
|
||||
end
|
||||
selected_nodes = select_node.find('.//option[@selected]')
|
||||
select_node.native.clear
|
||||
selected_nodes.each { |n| n.click unless n.path == path }
|
||||
end
|
||||
|
||||
def click
|
||||
|
@ -83,6 +74,14 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
|
|||
if all_nodes.empty? then [] else driver.find(all_nodes) end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# a reference to the select node if this is an option node
|
||||
def select_node
|
||||
find('./ancestor::select').first
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
attr_reader :app, :rack_server
|
||||
|
|
|
@ -24,11 +24,11 @@ module Capybara
|
|||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def select_option(option)
|
||||
def select_option
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def unselect_option(option)
|
||||
def unselect_option
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
|
|
|
@ -51,32 +51,18 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|||
end
|
||||
end
|
||||
|
||||
def select_option(option)
|
||||
if native['multiple'] != 'multiple'
|
||||
native.xpath(".//option[@selected]").each { |node| node.remove_attribute("selected") }
|
||||
def select_option
|
||||
if select_node['multiple'] != 'multiple'
|
||||
select_node.find(".//option[@selected]").each { |node| node.native.remove_attribute("selected") }
|
||||
end
|
||||
native["selected"] = 'selected'
|
||||
end
|
||||
|
||||
if option_node = native.xpath(".//option[text()=#{Capybara::XPath.escape(option)}]").first ||
|
||||
native.xpath(".//option[contains(.,#{Capybara::XPath.escape(option)})]").first
|
||||
option_node["selected"] = 'selected'
|
||||
else
|
||||
options = native.xpath(".//option").map { |o| "'#{o.text}'" }.join(', ')
|
||||
raise Capybara::OptionNotFound, "No such option '#{option}' in this select box. Available options: #{options}"
|
||||
end
|
||||
end
|
||||
|
||||
def unselect_option(option)
|
||||
if native['multiple'] != 'multiple'
|
||||
raise Capybara::UnselectNotAllowed, "Cannot unselect option '#{option}' from single select box."
|
||||
end
|
||||
|
||||
if option_node = native.xpath(".//option[text()=#{Capybara::XPath.escape(option)}]").first ||
|
||||
native.xpath(".//option[contains(.,#{Capybara::XPath.escape(option)})]").first
|
||||
option_node.remove_attribute('selected')
|
||||
else
|
||||
options = native.xpath(".//option").map { |o| "'#{o.text}'" }.join(', ')
|
||||
raise Capybara::OptionNotFound, "No such option '#{option}' in this select box. Available options: #{options}"
|
||||
def unselect_option
|
||||
if select_node['multiple'] != 'multiple'
|
||||
raise Capybara::UnselectNotAllowed, "Cannot unselect option from single select box."
|
||||
end
|
||||
native.remove_attribute('selected')
|
||||
end
|
||||
|
||||
def click
|
||||
|
@ -106,6 +92,11 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|||
|
||||
private
|
||||
|
||||
# a reference to the select node if this is an option node
|
||||
def select_node
|
||||
find('./ancestor::select').first
|
||||
end
|
||||
|
||||
def type
|
||||
native[:type]
|
||||
end
|
||||
|
|
|
@ -35,26 +35,15 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
|
|||
end
|
||||
end
|
||||
|
||||
def select_option(option)
|
||||
option_node = native.find_element(:xpath, ".//option[normalize-space(text())=#{Capybara::XPath.escape(option)}]") || native.find_element(:xpath, ".//option[contains(.,#{Capybara::XPath.escape(option)})]")
|
||||
option_node.select
|
||||
rescue
|
||||
options = native.find_elements(:xpath, ".//option").map { |o| "'#{o.text}'" }.join(', ')
|
||||
raise Capybara::OptionNotFound, "No such option '#{option}' in this select box. Available options: #{options}"
|
||||
def select_option
|
||||
native.select
|
||||
end
|
||||
|
||||
def unselect_option(option)
|
||||
if native['multiple'] != 'multiple'
|
||||
raise Capybara::UnselectNotAllowed, "Cannot unselect option '#{option}' from single select box."
|
||||
end
|
||||
|
||||
begin
|
||||
option_node = native.find_element(:xpath, ".//option[normalize-space(text())=#{Capybara::XPath.escape(option)}]") || native.find_element(:xpath, ".//option[contains(.,#{Capybara::XPath.escape(option)})]")
|
||||
option_node.clear
|
||||
rescue
|
||||
options = native.find_elements(:xpath, ".//option").map { |o| "'#{o.text}'" }.join(', ')
|
||||
raise Capybara::OptionNotFound, "No such option '#{option}' in this select box. Available options: #{options}"
|
||||
def unselect_option
|
||||
if select_node['multiple'] != 'multiple'
|
||||
raise Capybara::UnselectNotAllowed, "Cannot unselect option from single select box."
|
||||
end
|
||||
native.clear
|
||||
end
|
||||
|
||||
def click
|
||||
|
@ -79,6 +68,11 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
|
|||
|
||||
private
|
||||
|
||||
# a reference to the select node if this is an option node
|
||||
def select_node
|
||||
find('./ancestor::select').first
|
||||
end
|
||||
|
||||
def type
|
||||
self[:type]
|
||||
end
|
||||
|
|
|
@ -113,22 +113,18 @@ module Capybara
|
|||
|
||||
##
|
||||
#
|
||||
# Select the given option if the element is a select box
|
||||
# Select this node if is an option element inside a select tag
|
||||
#
|
||||
# @param [String] option The option to select
|
||||
#
|
||||
def select_option(option)
|
||||
base.select_option(option)
|
||||
def select_option
|
||||
base.select_option
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Unselect the given option if the element is a select box
|
||||
# Unselect this node if is an option element inside a multiple select tag
|
||||
#
|
||||
# @param [String] option The option to unselect
|
||||
#
|
||||
def unselect_option(option)
|
||||
base.unselect_option(option)
|
||||
def unselect_option
|
||||
base.unselect_option
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
@ -106,8 +106,10 @@ module Capybara
|
|||
# @param [String] locator Which check box to uncheck
|
||||
#
|
||||
def select(value, options={})
|
||||
msg = "cannot select option, no select box with id, name, or label '#{options[:from]}' found"
|
||||
find(:xpath, XPath.select(options[:from]), :message => msg).select_option(value)
|
||||
no_select_msg = "cannot select option, no select box with id, name, or label '#{options[:from]}' found"
|
||||
no_option_msg = "cannot select option, no option with text '#{value}' in select box '#{options[:from]}'"
|
||||
select = find(:xpath, XPath.select(options[:from]), :message => no_select_msg)
|
||||
select.find(:xpath, XPath.option(value), :message => no_option_msg).select_option
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -121,8 +123,10 @@ module Capybara
|
|||
# @param [String] locator Which check box to uncheck
|
||||
#
|
||||
def unselect(value, options={})
|
||||
msg = "cannot unselect option, no select box with id, name, or label '#{options[:from]}' found"
|
||||
find(:xpath, XPath.select(options[:from]), :message => msg).unselect_option(value)
|
||||
no_select_msg = "cannot unselect option, no select box with id, name, or label '#{options[:from]}' found"
|
||||
no_option_msg = "cannot unselect option, no option with text '#{value}' in select box '#{options[:from]}'"
|
||||
select = find(:xpath, XPath.select(options[:from]), :message => no_select_msg)
|
||||
select.find(:xpath, XPath.option(value), :message => no_option_msg).unselect_option
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
@ -59,7 +59,7 @@ shared_examples_for "select" do
|
|||
|
||||
context "with an option that doesn't exist" do
|
||||
it "should raise an error" do
|
||||
running { @session.select('Does not Exist', :from => 'form_locale') }.should raise_error(Capybara::OptionNotFound)
|
||||
running { @session.select('Does not Exist', :from => 'form_locale') }.should raise_error(Capybara::ElementNotFound)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ shared_examples_for "unselect" do
|
|||
|
||||
context "with an option that doesn't exist" do
|
||||
it "should raise an error" do
|
||||
running { @session.unselect('Does not Exist', :from => 'form_underwear') }.should raise_error(Capybara::OptionNotFound)
|
||||
running { @session.unselect('Does not Exist', :from => 'form_underwear') }.should raise_error(Capybara::ElementNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -137,6 +137,10 @@ module Capybara
|
|||
input_field(:file, locator, options)
|
||||
end
|
||||
|
||||
def option(name)
|
||||
append(".//option[normalize-space(text())=#{s(name)}]").append(".//option[contains(.,#{s(name)})]")
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def input_field(type, locator, options={})
|
||||
|
|
Loading…
Reference in a new issue