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