class Watir::ElementCollection

Base class for element collections.

Public Class Methods

new(query_scope, selector) click to toggle source
# File lib/watir/element_collection.rb, line 13
def initialize(query_scope, selector)
  @query_scope = query_scope
  @selector = selector
  @to_a = nil

  build unless @selector.key?(:element)
end

Public Instance Methods

==(other) click to toggle source

Returns true if two element collections are equal.

@example

browser.select_list(name: "new_user_languages").options == browser.select_list(id: "new_user_languages").options
#=> true

@example

browser.select_list(name: "new_user_role").options == browser.select_list(id: "new_user_languages").options
#=> false
# File lib/watir/element_collection.rb, line 148
def ==(other)
  to_a == other.to_a
end
Also aliased as: eql?
[](value) click to toggle source

Get the element at the given index or range.

Any call to an ElementCollection that includes an adjacent selector can not be lazy loaded because it must store the correct type

Ranges can not be lazy loaded

@param [Integer, Range] value Index (0-based) or Range of desired element(s) @return [Watir::Element, Watir::ElementCollection] Returns an instance of a Watir::Element subclass

# File lib/watir/element_collection.rb, line 62
def [](value)
  if value.is_a?(Range)
    to_a[value]
  elsif @selector.key? :adjacent
    to_a[value] || element_class.new(@query_scope, invalid_locator: true)
  elsif @to_a && @to_a[value]
    @to_a[value]
  else
    element_class.new(@query_scope, @selector.merge(index: value))
  end
end
browser() click to toggle source

Returns browser.

@return [Watir::Browser]

# File lib/watir/element_collection.rb, line 132
def browser
  @query_scope.browser
end
build() click to toggle source
# File lib/watir/element_collection.rb, line 46
def build
  selector_builder.build(@selector.dup)
end
each(&blk) click to toggle source

Relocates elements then yields each element in resulting collection.

@example

divs = browser.divs(class: 'kls')
divs.each do |div|
  puts div.text
end

@yieldparam [Watir::Element] element Iterate through the elements in this collection.

# File lib/watir/element_collection.rb, line 33
def each(&blk)
  reset!
  to_a.each(&blk)
end
eql?(other)
Alias for: ==
first() click to toggle source

First element of the collection

@return [Watir::Element] Returns an instance of a Watir::Element subclass

# File lib/watir/element_collection.rb, line 80
def first
  self[0]
end
last() click to toggle source

Last element of the collection

@return [Watir::Element] Returns an instance of a Watir::Element subclass

# File lib/watir/element_collection.rb, line 90
def last
  self[-1]
end
locate() click to toggle source

Locate all elements and return self.

@return ElementCollection

# File lib/watir/element_collection.rb, line 121
def locate
  to_a
  self
end
reset!() click to toggle source

Removes cache of previously located elements in the collection.

@example

options = browser.select_list(name: "new_user_languages").options
options.reset!
options[0]
#=> nil
# File lib/watir/element_collection.rb, line 163
def reset!
  @to_a = nil
end
to_a() click to toggle source

This collection as an Array.

@return [Array<Watir::Element>]

# File lib/watir/element_collection.rb, line 100
def to_a
  hash = {}
  @to_a ||=
    elements_with_tags.map.with_index do |(el, tag_name), idx|
      selector = @selector.dup
      selector[:index] = idx unless idx.zero?
      element = element_class.new(@query_scope, selector)
      if [HTMLElement, Input].include? element.class
        construct_subtype(element, hash, tag_name).tap { |e| e.cache = el }
      else
        element.tap { |e| e.cache = el }
      end
    end
end

Private Instance Methods

construct_subtype(element, hash, tag_name) click to toggle source
# File lib/watir/element_collection.rb, line 212
def construct_subtype(element, hash, tag_name)
  selector = element.selector
  hash[tag_name] ||= 0
  hash[tag_name] += 1
  selector[:index] = hash[tag_name] - 1
  selector[:tag_name] = tag_name
  Watir.element_class_for(tag_name).new(@query_scope, selector)
end
element_class() click to toggle source
# File lib/watir/element_collection.rb, line 208
def element_class
  Watir.const_get(self.class.name.sub(/Collection$/, ''))
end
elements() click to toggle source
# File lib/watir/element_collection.rb, line 169
def elements
  ensure_context
  if selector_builder.built.key?(:scope)
    @query_scope.send(:element_call) { locate_all }
  else
    locate_all
  end
end
elements_with_tags() click to toggle source
# File lib/watir/element_collection.rb, line 178
def elements_with_tags
  els = elements
  if @selector[:tag_name]
    els.map { |e| [e, @selector[:tag_name]] }
  else
    retries = 0
    begin
      els.zip(execute_js(:getElementTags, els))
    rescue Selenium::WebDriver::Error::StaleElementReferenceError
      retries += 1
      sleep 0.5
      retry unless retries > 2
      raise LocatorException, "Unable to locate element collection from #{@selector} due to changing page"
    end
  end
end
ensure_context() click to toggle source
# File lib/watir/element_collection.rb, line 195
def ensure_context
  if @query_scope.is_a?(Browser) || !@query_scope.located? && @query_scope.is_a?(IFrame)
    @query_scope.browser.locate
  elsif @query_scope.located? && @query_scope.stale?
    @query_scope.locate
  end
  @query_scope.switch_to! if @query_scope.is_a?(IFrame)
end
locate_all() click to toggle source
# File lib/watir/element_collection.rb, line 204
def locate_all
  locator.locate_all(selector_builder.built)
end