class Capybara::Result

A {Capybara::Result} represents a collection of {Capybara::Node::Element} on the page. It is possible to interact with this collection similar to an Array because it implements Enumerable and offers the following Array methods through delegation:

@see Capybara::Node::Element

Public Class Methods

new(elements, query) click to toggle source
# File lib/capybara/result.rb, line 26
def initialize(elements, query)
  @elements = elements
  @result_cache = []
  @results_enum = lazy_select_elements { |node| query.matches_filters?(node) }
  @query = query
end

Public Instance Methods

[](*args) click to toggle source
# File lib/capybara/result.rb, line 49
def [](*args)
  if (args.size == 1) && ((idx = args[0]).is_a? Integer) && (idx >= 0)
    @result_cache << @results_enum.next while @result_cache.size <= idx
    @result_cache[idx]
  else
    full_results[*args]
  end
rescue StopIteration
  return nil
end
Also aliased as: at
at(*args)
Alias for: []
compare_count() click to toggle source
# File lib/capybara/result.rb, line 65
def compare_count
  # Only check filters for as many elements as necessary to determine result
  if @query.options[:count]
    count_opt = Integer(@query.options[:count])
    loop do
      break if @result_cache.size > count_opt
      @result_cache << @results_enum.next
    end
    return @result_cache.size <=> count_opt
  end

  if @query.options[:minimum]
    min_opt = Integer(@query.options[:minimum])
    begin
      @result_cache << @results_enum.next while @result_cache.size < min_opt
    rescue StopIteration
      return -1
    end
  end

  if @query.options[:maximum]
    max_opt = Integer(@query.options[:maximum])
    begin
      @result_cache << @results_enum.next while @result_cache.size <= max_opt
      return 1
    rescue StopIteration
    end
  end

  if @query.options[:between]
    min, max = @query.options[:between].minmax
    loop do
      break if @result_cache.size > max
      @result_cache << @results_enum.next
    end
    return 0 if @query.options[:between].include?(@result_cache.size)
    return -1 if @result_cache.size < min
    return 1
  end

  return 0
end
each() { |next_result| ... } click to toggle source
# File lib/capybara/result.rb, line 37
def each(&block)
  return enum_for(:each) unless block_given?

  @result_cache.each(&block)
  loop do
    next_result = @results_enum.next
    @result_cache << next_result
    yield next_result
  end
  self
end
empty?() click to toggle source
# File lib/capybara/result.rb, line 61
def empty?
  !any?
end
failure_message() click to toggle source
# File lib/capybara/result.rb, line 112
def failure_message
  message = @query.failure_message
  if count.zero?
    message << " but there were no matches"
  else
    message << ", found #{count} #{Capybara::Helpers.declension('match', 'matches', count)}: " << full_results.map(&:text).map(&:inspect).join(", ")
  end
  unless rest.empty?
    elements = rest.map { |el| el.text rescue "<<ERROR>>" }.map(&:inspect).join(", ")
    message << ". Also found " << elements << ", which matched the selector but not all filters."
  end
  message
end
matches_count?() click to toggle source
# File lib/capybara/result.rb, line 108
def matches_count?
  compare_count.zero?
end
negative_failure_message() click to toggle source
# File lib/capybara/result.rb, line 126
def negative_failure_message
  failure_message.sub(/(to find)/, 'not \1')
end

Private Instance Methods

full_results() click to toggle source
# File lib/capybara/result.rb, line 132
def full_results
  loop { @result_cache << @results_enum.next }
  @result_cache
end
lazy_select_elements(&block) click to toggle source
# File lib/capybara/result.rb, line 141
def lazy_select_elements(&block)
  # JRuby has an issue with lazy enumerators which
  # causes a concurrency issue with network requests here
  # https://github.com/jruby/jruby/issues/4212
  if RUBY_PLATFORM == 'java'
    @elements.select(&block).to_enum # non-lazy evaluation
  else
    @elements.lazy.select(&block)
  end
end
rest() click to toggle source
# File lib/capybara/result.rb, line 137
def rest
  @rest ||= @elements - full_results
end