class Watir::Locators::Element::Locator

Attributes

driver_scope[R]
element_matcher[R]

Public Class Methods

new(element_matcher) click to toggle source
# File lib/watir/locators/element/locator.rb, line 9
def initialize(element_matcher)
  @query_scope = element_matcher.query_scope
  @selector = element_matcher.selector
  @element_matcher = element_matcher
end

Public Instance Methods

locate(built) click to toggle source
# File lib/watir/locators/element/locator.rb, line 15
def locate(built)
  @built = built.dup
  @driver_scope = locator_scope.wd
  @filter = :first
  matching_elements
rescue Selenium::WebDriver::Error::NoSuchElementError
  nil
end
locate_all(built) click to toggle source
# File lib/watir/locators/element/locator.rb, line 24
def locate_all(built)
  @built = built.dup
  @driver_scope = locator_scope.wd
  @filter = :all

  return [matching_elements].flatten unless @built.key?(:index)

  raise ArgumentError, "can't locate all elements by :index"
end

Private Instance Methods

locate_element(how, what, scope = driver_scope) click to toggle source
# File lib/watir/locators/element/locator.rb, line 69
def locate_element(how, what, scope = driver_scope)
  scope.find_element(how, what)
end
locate_elements(how, what, scope = driver_scope) click to toggle source
# File lib/watir/locators/element/locator.rb, line 73
def locate_elements(how, what, scope = driver_scope)
  scope.find_elements(how, what)
end
locator_scope() click to toggle source
# File lib/watir/locators/element/locator.rb, line 64
def locator_scope
  scope = @built.delete(:scope)
  @locator_scope ||= scope || @query_scope.browser
end
match_values() click to toggle source
# File lib/watir/locators/element/locator.rb, line 60
def match_values
  @match_values ||= @built.reject { |k, _v| wd_locator.keys.first == k }
end
matching_elements() click to toggle source
# File lib/watir/locators/element/locator.rb, line 36
def matching_elements
  return locate_element(*@built.to_a.flatten) if @built.size == 1 && @filter == :first

  # TODO: Wrap this to continue trying until default timeout
  retries = 0
  begin
    elements = locate_elements(*wd_locator.to_a.flatten)

    element_matcher.match(elements, match_values, @filter)
  rescue Selenium::WebDriver::Error::StaleElementReferenceError
    retries += 1
    sleep 0.5
    retry unless retries > 2
    target = @filter == :all ? 'element collection' : 'element'
    raise LocatorException, "Unable to locate #{target} from #{@selector} due to changing page"
  end
end
wd_locator() click to toggle source
# File lib/watir/locators/element/locator.rb, line 54
def wd_locator
  # SelectorBuilder only allows one of these
  wd_locator_key = (Watir::Locators::W3C_FINDERS & @built.keys).first
  @wd_locator ||= @built.select { |k, _v| wd_locator_key == k }
end