class Watir::Select

Public Instance Methods

clear() click to toggle source

Clears all selected options.

# File lib/watir-webdriver/elements/select.rb, line 9
def clear
  assert_exists

  raise Error, "you can only clear multi-selects" unless multiple?

  options.each do |o|
    click_option(o) if o.selected?
  end
end
include?(str_or_rx) click to toggle source

Returns true if the select list has one or more options where text or label matches the given value.

@param [String, Regexp] str_or_rx @return [Boolean]

# File lib/watir-webdriver/elements/select.rb, line 37
def include?(str_or_rx)
  assert_exists

  element_call do
    @element.find_elements(:tag_name, 'option').any? do |e|
      str_or_rx === e.text || str_or_rx === e.attribute(:label)
    end
  end
end
options() click to toggle source

Gets all the options in the select list

@return [Watir::OptionCollection]

Calls superclass method Watir::Container#options
# File lib/watir-webdriver/elements/select.rb, line 25
def options
  assert_exists
  super
end
select(str_or_rx) click to toggle source

Select the option(s) whose text or label matches the given string. If this is a multi-select and several options match the value given, all will be selected.

@param [String, Regexp] str_or_rx @raise [Watir::Exception::NoValueFoundException] if the value does not exist. @return [String] The text of the option selected. If multiple options match, returns the first match.

# File lib/watir-webdriver/elements/select.rb, line 56
def select(str_or_rx)
  select_by :text, str_or_rx
end
select_value(str_or_rx) click to toggle source

Selects the option(s) whose value attribute matches the given string.

@see select

@param [String, Regexp] str_or_rx @raise [Watir::Exception::NoValueFoundException] if the value does not exist. @return [String] The option selected. If multiple options match, returns the first match

# File lib/watir-webdriver/elements/select.rb, line 70
def select_value(str_or_rx)
  select_by :value, str_or_rx
end
selected?(str_or_rx) click to toggle source

Returns true if any of the selected options' text or label matches the given value.

@param [String, Regexp] str_or_rx @raise [Watir::Exception::UnknownObjectException] if the options do not exist @return [Boolean]

# File lib/watir-webdriver/elements/select.rb, line 82
def selected?(str_or_rx)
  assert_exists

  match_found = false

  element_call do
    @element.find_elements(:tag_name, 'option').each do |e|
      matched = str_or_rx === e.text || str_or_rx === e.attribute(:label)
      if matched
        return true if e.selected?
        match_found = true
      end
    end
  end

  raise(UnknownObjectException, "Unable to locate option matching #{str_or_rx.inspect}") unless match_found

  false
end
selected_options() click to toggle source

Returns an array of currently selected options.

@return [Array<Watir::Option>]

# File lib/watir-webdriver/elements/select.rb, line 121
def selected_options
  options.select { |e| e.selected? }
end
value() click to toggle source

Returns the value of the first selected option in the select list. Returns nil if no option is selected.

@return [String, nil]

# File lib/watir-webdriver/elements/select.rb, line 109
def value
  o = options.find { |e| e.selected? } || return
  o.value
end

Private Instance Methods

click_option(element) click to toggle source
# File lib/watir-webdriver/elements/select.rb, line 214
def click_option(element)
  element = Option.new(self, element: element) unless element.is_a?(Option)
  element.click
end
matches_regexp?(how, element, exp) click to toggle source
# File lib/watir-webdriver/elements/select.rb, line 203
def matches_regexp?(how, element, exp)
  case how
  when :text
    element.text =~ exp || element.attribute(:label) =~ exp
  when :value
    element.attribute(:value) =~ exp
  else
    raise Error, "unknown how: #{how.inspect}"
  end
end
no_value_found(arg, msg = nil) click to toggle source
# File lib/watir-webdriver/elements/select.rb, line 227
def no_value_found(arg, msg = nil)
  raise NoValueFoundException, msg || "#{arg.inspect} not found in select list"
end
option_xpath_for(how, string) click to toggle source
# File lib/watir-webdriver/elements/select.rb, line 190
def option_xpath_for(how, string)
  string = XpathSupport.escape string

  case how
  when :text
    ".//option[normalize-space()=#{string} or @label=#{string}]"
  when :value
    ".//option[@value=#{string}]"
  else
    raise Error, "unknown how: #{how.inspect}"
  end
end
safe_text(element) click to toggle source
# File lib/watir-webdriver/elements/select.rb, line 219
def safe_text(element)
  element.text
rescue Selenium::WebDriver::Error::StaleElementReferenceError, Selenium::WebDriver::Error::UnhandledAlertError
  # guard for scenario where selecting the element changes the page, making our element obsolete

  ''
end
select_by(how, str_or_rx) click to toggle source
# File lib/watir-webdriver/elements/select.rb, line 127
def select_by(how, str_or_rx)
  assert_exists

  case str_or_rx
  when String, Numeric
    select_by_string(how, str_or_rx.to_s)
  when Regexp
    select_by_regexp(how, str_or_rx)
  else
    raise TypeError, "expected String or Regexp, got #{str_or_rx.inspect}:#{str_or_rx.class}"
  end
end
select_by_regexp(how, exp) click to toggle source
# File lib/watir-webdriver/elements/select.rb, line 165
def select_by_regexp(how, exp)
  elements = element_call do
    @element.find_elements(:tag_name, 'option')
  end
  no_value_found(nil, "no options in select list") if elements.empty?

  if multiple?
    found = elements.select do |e|
      next unless matches_regexp?(how, e, exp)
      click_option(e) unless e.selected?
      true
    end

    no_value_found(exp) if found.empty?

    found.first.text
  else
    element = elements.find { |e| matches_regexp?(how, e, exp) }
    no_value_found(exp) unless element

    click_option(element) unless element.selected?
    safe_text(element)
  end
end
select_by_string(how, string) click to toggle source
# File lib/watir-webdriver/elements/select.rb, line 140
def select_by_string(how, string)
  xpath = option_xpath_for(how, string)

  if multiple?
    elements = element_call do
      @element.find_elements(:xpath, xpath)
    end
    no_value_found(string) if elements.empty?

    elements.each { |e| click_option(e) unless e.selected? }
    elements.first.text
  else
    begin
      e = element_call do
        @element.find_element(:xpath, xpath)
      end
    rescue Selenium::WebDriver::Error::NoSuchElementError
      no_value_found(string)
    end

    click_option(e) unless e.selected?
    safe_text(e)
  end
end