Class: Watir::Locator

Inherits:
Object show all
Includes:
Watir, Exception, XpathLocator
Defined in:
lib/watir-classic/locator.rb

Direct Known Subclasses

InputElementLocator, TaggedElementLocator

Constant Summary

Constants included from Watir

VERSION

Instance Method Summary collapse

Methods included from XpathLocator

#direct_children, #element_by_css, #element_by_xpath, #elements_by_css, #elements_by_xpath, #xmlparser_document_object

Methods included from Exception

message_for_unable_to_locate

Methods included from Watir

options, options=, options_file, options_file=

Constructor Details

#initialize(container, specifiers, klass) ⇒ Locator

Returns a new instance of Locator.



7
8
9
10
11
12
# File 'lib/watir-classic/locator.rb', line 7

def initialize container, specifiers, klass
  @container = container
  @specifiers = {:index => Watir::IE.base_index}.merge(normalize_specifiers(specifiers))
  @tags = @specifiers.delete(:tag_name)
  @klass = klass
end

Instance Method Details

#create_element(ole_object) ⇒ Object



127
128
129
130
131
# File 'lib/watir-classic/locator.rb', line 127

def create_element ole_object
  element = @klass.new(@container, @specifiers.merge(:ole_object => ole_object))
  def element.locate; @o; end
  element
end

#documentObject



30
31
32
# File 'lib/watir-classic/locator.rb', line 30

def document
  @document ||= @container.document
end

#eachObject



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/watir-classic/locator.rb', line 14

def each
  if has_excluding_specifiers?
    locate_elements_by_xpath_css_ole.each do |element|
      yield element
    end
  else
    @tags.each do |tag|
      each_element(tag) do |element| 
        next unless type_matches?(element.ole_object) && match_with_specifiers?(element)
        yield element          
      end 
    end
  end
  nil
end

#has_excluding_specifiers?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/watir-classic/locator.rb', line 83

def has_excluding_specifiers?
  @specifiers.keys.any? {|specifier| [:css, :xpath, :ole_object].include? specifier}
end

#locate_by_idObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/watir-classic/locator.rb', line 87

def locate_by_id
  # Searching through all elements returned by __ole_inner_elements
  # is *significantly* slower than IE's getElementById() and
  # getElementsByName() calls when how is :id.  However
  # IE doesn't match Regexps, so first we make sure what is a String.
  # In addition, IE's getElementById() will also return an element
  # where the :name matches, so we will only return the results of
  # getElementById() if the matching element actually HAS a matching
  # :id.

  the_id = @specifiers[:id]
  if the_id && the_id.class == String 
    element = document.getElementById(the_id) rescue nil
    # Return if our fast match really HAS a matching :id
    return element if element && element.invoke('id') == the_id && type_matches?(element) && match_with_specifiers?(create_element element)
  end

  nil
end

#locate_elements_by_xpath_css_oleObject



107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/watir-classic/locator.rb', line 107

def locate_elements_by_xpath_css_ole
  els = []

  if @specifiers[:xpath]
    els = elements_by_xpath(@specifiers[:xpath])
  elsif @specifiers[:css]
    els = elements_by_css(@specifiers[:css])
  elsif @specifiers[:ole_object]
    return [@specifiers[:ole_object]]
  end      

  els.select {|element| type_matches?(element) && match_with_specifiers?(create_element element)}
end

#match?(element, how, what) ⇒ Boolean

return true if the element matches the provided how and what

Returns:

  • (Boolean)


72
73
74
75
76
77
78
79
80
81
# File 'lib/watir-classic/locator.rb', line 72

def match? element, how, what
  begin
    attribute = element.send(how)
  rescue NoMethodError
    raise MissingWayOfFindingObjectException,
      "#{how} is an unknown way of finding a <#{@tags.join(", ")}> element (#{what})"
  end

  what.matches(attribute)
end

#match_class?(element, what) ⇒ Boolean

Returns:

  • (Boolean)


66
67
68
69
# File 'lib/watir-classic/locator.rb', line 66

def match_class? element, what
  classes = element.class_name.split(/\s+/)
  classes.any? {|clazz| what.matches(clazz)}
end

#match_with_specifiers?(element) ⇒ Boolean

Returns:

  • (Boolean)


57
58
59
60
61
62
63
64
# File 'lib/watir-classic/locator.rb', line 57

def match_with_specifiers?(element)
  return true if has_excluding_specifiers?
  @specifiers.all? do |how, what|
    how == :index || 
      (how == :class_name && match_class?(element, what)) ||
      match?(element, how, what)
  end
end

#normalize_specifiers(specifiers) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/watir-classic/locator.rb', line 34

def normalize_specifiers(specifiers)
  specifiers.reduce({}) do |memo, pair|
    how, what = *pair
    case how
    when :index
      what = what.to_i
    when :url
      how = :href
    when :class
      how = :class_name
    when :caption
      how = :value
    when :method
      how = :form_method
    when :value
      what = what.is_a?(Regexp) ? what : what.to_s
    end

    memo[how] = what
    memo
  end
end

#type_matches?(el) ⇒ Boolean

Returns:

  • (Boolean)


121
122
123
124
125
# File 'lib/watir-classic/locator.rb', line 121

def type_matches?(el)
  @tags == ["*"] || 
    @tags.include?(el.tagName.downcase) || 
    @tags.include?(el.invoke('type').downcase) rescue false
end