lib/watir/locator.rb in watir-3.0.0.rc2 vs lib/watir/locator.rb in watir-3.0.0.rc3
- old
+ new
@@ -1,13 +1,15 @@
module Watir
class Locator
include Watir
include Watir::Exception
+ include XpathLocator
- def initialize container, tags, klass
+ def initialize container, specifiers, klass
@container = container
- @tags = tags
+ @specifiers = {:index => Watir::IE.base_index}.merge(normalize_specifiers(specifiers))
+ @tags = @specifiers.delete(:tag_name)
@klass = klass
end
def each
if has_excluding_specifiers?
@@ -27,12 +29,13 @@
def document
@document ||= @container.document
end
- def normalize_specifiers!(specifiers)
- specifiers.each do |how, what|
+ def normalize_specifiers(specifiers)
+ specifiers.reduce({}) do |memo, pair|
+ how, what = *pair
case how
when :index
what = what.to_i
when :url
how = :href
@@ -44,11 +47,12 @@
how = :form_method
when :value
what = what.is_a?(Regexp) ? what : what.to_s
end
- @specifiers[how] = what
+ memo[how] = what
+ memo
end
end
def match_with_specifiers?(element)
return true if has_excluding_specifiers?
@@ -78,16 +82,10 @@
def has_excluding_specifiers?
@specifiers.keys.any? {|specifier| [:css, :xpath, :ole_object].include? specifier}
end
- def set_specifier(how, what=nil)
- specifiers = what ? {how => what} : how
- @specifiers = {:index => Watir::IE.base_index} # default if not specified
- normalize_specifiers! specifiers
- end
-
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.
@@ -108,34 +106,29 @@
def locate_elements_by_xpath_css_ole
els = []
if @specifiers[:xpath]
- els = @container.send(:elements_by_xpath, @specifiers[:xpath])
+ els = elements_by_xpath(@specifiers[:xpath])
elsif @specifiers[:css]
- els = @container.send(:elements_by_css, @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
def type_matches?(el)
@tags == ["*"] ||
- @tags.include?(el.tagName) ||
- @tags.include?(el.invoke('type')) rescue false
+ @tags.include?(el.tagName.downcase) ||
+ @tags.include?(el.invoke('type').downcase) rescue false
end
def create_element ole_object
- if @klass == Element
- element = Element.new(ole_object)
- else
- element = @klass.new(@container, @specifiers, nil)
- element.ole_object = ole_object
- def element.locate; @o; end
- end
+ element = @klass.new(@container, @specifiers.merge(:ole_object => ole_object))
+ def element.locate; @o; end
element
end
end
class TaggedElementLocator < Locator
@@ -159,26 +152,37 @@
end
end
class FrameLocator < TaggedElementLocator
def each_element(tag)
- frames = document.frames
+ frames = @container.page_container.document.frames
i = 0
document.getElementsByTagName(tag).each do |ole_object|
frame = create_element ole_object
frame.document = frames.item(i)
yield frame
i += 1
end
end
def locate
- # do not locate frames by getElementById or by xpath since can't get the correct
- # 'document' related with that ole_object like it's done in #each_element
count = Watir::IE.base_index - 1
each do |frame|
count += 1
return frame.ole_object, frame.document if count == @specifiers[:index]
+ end
+ end
+
+ def locate_elements_by_xpath_css_ole
+ super.map do |frame|
+ frame = create_element frame
+ each_element(frame.tag_name) do |frame_with_document|
+ if frame_with_document == frame
+ frame = frame_with_document
+ break
+ end
+ end
+ frame
end
end
end
class FormLocator < TaggedElementLocator