module Capybara::Node::Finders

Public Instance Methods

all(*args) click to toggle source

Find all elements on the page matching the given selector and options.

Both XPath and CSS expressions are supported, but Capybara does not try to automatically distinguish between them. The following statements are equivalent:

page.all(:css, 'a#person_123')
page.all(:xpath, '//a[@id="person_123"]')

If the type of selector is left out, Capybara uses {Capybara.default_selector}. It's set to :css by default.

page.all("a#person_123")

Capybara.default_selector = :xpath
page.all('//a[@id="person_123"]')

The set of found elements can further be restricted by specifying options. It's possible to select elements by their text or visibility:

page.all('a', :text => 'Home')
page.all('#menu li', :visible => true)

@param [:css, :xpath, String] kind_or_locator Either the kind of selector or the selector itself @param [String] locator The selector @param [Hash{Symbol => Object}] options Additional options @option options [String, Regexp] text Only find elements which contain this text or match this regexp @option options [Boolean] visible Only find elements that are visible on the page @return [Capybara::Element] The found elements

# File lib/capybara/node/finders.rb, line 109
def all(*args)
  options = extract_normalized_options(args)

  selector = Capybara::Selector.normalize(*args)
  selector.xpaths.
    map    { |path| find_in_base(selector, path) }.flatten.
    select { |node| matches_options(node, options) }
end
field_labeled(locator)
Alias for: find_field
find(*args) click to toggle source

Find an {Capybara::Element} based on the given arguments. find will raise an error if the element is not found. The error message can be customized through the :message option.

If the driver is capable of executing JavaScript, find will wait for a set amount of time and continuously retry finding the element until either the element is found or the time expires. The length of time find will wait is controlled through {Capybara.default_wait_time} and defaults to 2 seconds.

find takes the same options as all.

page.find('#foo').find('.bar')
page.find(:xpath, '//div[contains(., "bar")]')
page.find('li', :text => 'Quox').click_link('Delete')

@param (see #all) @option options [String] :message An error message in case the element can't be found @return [Capybara::Element] The found element @raise [Capybara::ElementNotFound] If the element can't be found before time expires

# File lib/capybara/node/finders.rb, line 26
def find(*args)
  wait_until { first(*args) or raise_find_error(*args) }
end
find_button(locator) click to toggle source

Find a button on the page. The link can be found by its id, name or value.

@param [String] locator Which button to find @return [Capybara::Element] The found element

# File lib/capybara/node/finders.rb, line 60
def find_button(locator)
  find(:xpath, XPath::HTML.button(locator))
end
find_by_id(id) click to toggle source

Find a element on the page, given its id.

@param [String] locator Which element to find @return [Capybara::Element] The found element

# File lib/capybara/node/finders.rb, line 71
def find_by_id(id)
  find(:css, "##{id}")
end
find_field(locator) click to toggle source

Find a form field on the page. The field can be found by its name, id or label text.

@param [String] locator Which field to find @return [Capybara::Element] The found element

# File lib/capybara/node/finders.rb, line 37
def find_field(locator)
  find(:xpath, XPath::HTML.field(locator))
end
Also aliased as: field_labeled
first(*args) click to toggle source

Find the first element on the page matching the given selector and options, or nil if no element matches.

When only the first matching element is needed, this method can be faster than all(*args).first.

@param [:css, :xpath, String] kind_or_locator Either the kind of selector or the selector itself @param [String] locator The selector @param [Hash{Symbol => Object}] options Additional options; see {all} @return Capybara::Element The found element

# File lib/capybara/node/finders.rb, line 131
def first(*args)
  options = extract_normalized_options(args)
  found_elements = []

  selector = Capybara::Selector.normalize(*args)
  selector.xpaths.each do |path|
    find_in_base(selector, path).each do |node|
      if matches_options(node, options)
        found_elements << node
        return found_elements.last if not Capybara.prefer_visible_elements or node.visible?
      end
    end
  end
  found_elements.first
end

Protected Instance Methods

extract_normalized_options(args) click to toggle source
# File lib/capybara/node/finders.rb, line 163
def extract_normalized_options(args)
  options = if args.last.is_a?(Hash) then args.pop.dup else {} end

  if text = options[:text]
    options[:text] = Regexp.escape(text) unless text.kind_of?(Regexp)
  end

  if !options.has_key?(:visible)
    options[:visible] = Capybara.ignore_hidden_elements
  end

  if selected = options[:selected]
    options[:selected] = [selected].flatten
  end

  options
end
find_in_base(selector, xpath) click to toggle source
# File lib/capybara/node/finders.rb, line 157
def find_in_base(selector, xpath)
  base.find(xpath).map do |node|
    Capybara::Node::Element.new(session, node, self, selector)
  end
end
has_selected_options?(node, expected) click to toggle source
# File lib/capybara/node/finders.rb, line 191
def has_selected_options?(node, expected)
  actual = node.all(:xpath, './/option').select { |option| option.selected? }.map { |option| option.text }
  (expected - actual).empty?
end
matches_options(node, options) click to toggle source
# File lib/capybara/node/finders.rb, line 181
def matches_options(node, options)
  return false if options[:text]      and not node.text.match(options[:text])
  return false if options[:visible]   and not node.visible?
  return false if options[:with]      and not node.value == options[:with]
  return false if options[:checked]   and not node.checked?
  return false if options[:unchecked] and node.checked?
  return false if options[:selected]  and not has_selected_options?(node, options[:selected])
  true
end
raise_find_error(*args) click to toggle source
# File lib/capybara/node/finders.rb, line 149
def raise_find_error(*args)
  options = extract_normalized_options(args)
  normalized = Capybara::Selector.normalize(*args)
  message = options[:message] || "Unable to find #{normalized.name} #{normalized.locator.inspect}"
  message = normalized.failure_message.call(self, normalized) if normalized.failure_message
  raise Capybara::ElementNotFound, message
end