Class: Celerity::ElementLocator

Inherits:
Object
Includes:
Celerity::Exception
Defined in:
lib/celerity/element_locator.rb

Overview

Used internally to locate elements on the page.

Attribute Summary

Method Summary

Constructor Details

- (ElementLocator) initialize(container, element_class)

A new instance of ElementLocator

Returns:



12
13
14
15
16
17
18
19
20
21
# File 'lib/celerity/element_locator.rb', line 12

def initialize(container, element_class)
  container.assert_exists

  @container     = container
  @object        = container.object
  @element_class = element_class
  @attributes    = @element_class::ATTRIBUTES # could check for 'strict' here?
  @idents        = @element_class::TAGS
  @tags          = @idents.map { |e| e.tag.downcase }
end

Attribute Details

- (Object) idents

Returns the value of attribute idents



9
10
11
# File 'lib/celerity/element_locator.rb', line 9

def idents
  @idents
end

Method Details

- (Object) element_by_idents(idents = @idents)



113
114
115
# File 'lib/celerity/element_locator.rb', line 113

def element_by_idents(idents = @idents)
  get_by_idents(:find, idents)
end

- (Object) elements_by_idents(idents = @idents)



109
110
111
# File 'lib/celerity/element_locator.rb', line 109

def elements_by_idents(idents = @idents)
  get_by_idents(:select, idents)
end

- (Object) find_by_conditions(conditions)



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/celerity/element_locator.rb', line 23

def find_by_conditions(conditions) # TODO: refactor without performance hit
  return nil unless @object # probably means we're on a TextPage (content-type is "text/plain")

  @condition_idents = []
  attributes = Hash.new { |h, k| h[k] = [] }
  index = 0 # by default, return the first matching element
  text = nil

  conditions.each do |how, what|
    case how
    when :object
      unless what.is_a?(HtmlUnit::Html::HtmlElement) || what.nil?
        raise ArgumentError, "expected an HtmlUnit::Html::HtmlElement subclass, got #{what.inspect}:#{what.class}"
      end
      return what
    when :xpath
      return find_by_xpath(what)
    when :label
      return find_by_label(what) unless @attributes.include?(:label)
    when :class_name
      how = :class
    when :url
      how = :href
    when :caption
      how = :text
    end

    if how == :id && conditions.size == 1
      return find_by_id(what)
    elsif @attributes.include?(how = how.to_sym)
      attributes[how] << what
    elsif how == :index
      index = what.to_i - Celerity.index_offset
    elsif how == :text
      text = what
    else
      raise MissingWayOfFindingObjectException, "No how #{how.inspect}"
    end
  end

  @idents.each do |ident|
    merged = attributes.merge(ident.attributes) { |key, v1, v2| v1 | v2 }
    id = Identifier.new(ident.tag, merged)
    id.text = ident.text || text # «original» identifier takes precedence for :text
    @condition_idents << id
  end

  if index == 0
    element_by_idents(@condition_idents)
  else
    elements_by_idents(@condition_idents)[index]
  end

rescue HtmlUnit::ElementNotFoundException
  nil # for rcov
end

- (Object) find_by_id(what)



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/celerity/element_locator.rb', line 80

def find_by_id(what)
  case what
  when Regexp
    elements_by_tag_names.find { |elem| elem.getId =~ what }
  when String
    obj = @object.getElementById(what)
    return obj if @tags.include?(obj.getTagName)

    $stderr.puts "warning: multiple elements with identical id? (#{what.inspect})" if $VERBOSE
    elements_by_tag_names.find { |elem| elem.getId == what }
  else
    raise TypeError, "expected String or Regexp, got #{what.inspect}:#{what.class}"
  end
end

- (Object) find_by_label(what)



100
101
102
103
104
105
106
107
# File 'lib/celerity/element_locator.rb', line 100

def find_by_label(what)
  obj = elements_by_tag_names(%w[label]).find { |e| Util.matches?(e.asText, what) }

  return nil unless obj && (ref = obj.getReferencedElement)
  return ref if @tags.include?(ref.getTagName)

  find_by_id obj.getForAttribute
end

- (Object) find_by_xpath(what)



95
96
97
98
# File 'lib/celerity/element_locator.rb', line 95

def find_by_xpath(what)
  what = ".#{what}" if what[0].chr == "/"
  @object.getByXPath(what).to_a.first
end