Skip to content

Commit

Permalink
pick the matching type (equals/contains) based on the attribute name …
Browse files Browse the repository at this point in the history
…so that users aren't required to have that knowledge
  • Loading branch information
Sven Fuchs committed Feb 17, 2010
1 parent 92e96c0 commit 87e6796
Show file tree
Hide file tree
Showing 15 changed files with 54 additions and 23 deletions.
2 changes: 1 addition & 1 deletion TODO
@@ -1,4 +1,4 @@
somehow allow these?
Somehow allow these?

locate(html, :foo) { locate(:bar) }
within(html, :foo) { locate(:bar) }
6 changes: 3 additions & 3 deletions lib/locator/dom/htmlunit/element.rb
Expand Up @@ -21,9 +21,9 @@ def xpath
element.getCanonicalXPath
end

# def css_path
# element.css_path.to_s
# end
def css_path
raise 'not implemented'
end

def content
# TODO HtmlUnit has asText and getTextContent
Expand Down
6 changes: 3 additions & 3 deletions lib/locator/element.rb
Expand Up @@ -24,10 +24,10 @@ class Element
attr_reader :name, :css, :locatables, :attributes

def initialize(*args)
options, name = args.last.is_a?(Hash) ? args.pop : {}, args.pop
attributes, name = args.last.is_a?(Hash) ? args.pop : {}, args.pop
@name = name
@attributes = options.slice!(:equals, :matches)
@locatables = { :equals => :id, :matches => :content }.merge(options || {})
@attributes = attributes
@locatables = ((attributes.delete(:matches) || [:content]) + [:id]).uniq
end

def locate(*args)
Expand Down
2 changes: 1 addition & 1 deletion lib/locator/element/area.rb
Expand Up @@ -2,7 +2,7 @@ module Locator
class Element
class Area < Element
def initialize
super(:area, :equals => [:id], :matches => [:alt])
super(:area, :matches => [:alt])
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/locator/element/button.rb
Expand Up @@ -2,8 +2,8 @@ module Locator
class Element
class Button < ElementsList
def initialize
input = Element.new(:input, :equals => [:id, :name], :matches => [:value], :type => %w(submit button image))
button = Element.new(:button, :equals => [:id, :name], :matches => [:content])
input = Element.new(:input, :matches => [:value], :type => %w(submit button image))
button = Element.new(:button, :matches => [:content])
super(input, button)
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/locator/element/form.rb
Expand Up @@ -2,7 +2,7 @@ module Locator
class Element
class Form < Element
def initialize
super(:form, :equals => [:id, :name])
super(:form)
end
end
end
Expand Down
8 changes: 7 additions & 1 deletion lib/locator/element/form_element.rb
@@ -1,8 +1,14 @@
module Locator
class Element
class FormElement < Element
def initialize(name, attributes = {})
attributes[:matches] ||= []
attributes[:matches] << :name
super
end

def lookup(dom, selector, attributes)
super(dom, selector, attributes) + LabeledElement.new(name).send(:lookup, dom, selector, attributes)
super(dom, selector, attributes) + LabeledElement.new(name).send(:lookup, dom, selector, attributes.dup)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/locator/element/input.rb
Expand Up @@ -2,7 +2,7 @@ module Locator
class Element
class Input < FormElement
def initialize(attributes = {})
defaults = { :equals => [:id, :name], :type => [:text, :password , :email, :url, :search, :tel, :color] }
defaults = { :type => [:text, :password , :email, :url, :search, :tel, :color] }
super(:input, defaults.merge(attributes))
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/locator/element/label.rb
Expand Up @@ -2,7 +2,7 @@ module Locator
class Element
class Label < Element
def initialize
super(:label, :equals => [:id, :content])
super(:label, :matches => [:content])
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/locator/element/select.rb
Expand Up @@ -2,7 +2,7 @@ module Locator
class Element
class Select < FormElement
def initialize
super(:select, :equals => [:id, :name])
super(:select)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/locator/element/select_option.rb
Expand Up @@ -2,7 +2,7 @@ module Locator
class Element
class SelectOption < Element
def initialize
super(:option, :equals => [:id, :value, :content])
super(:option, :matches => [:value, :content])
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/locator/element/text_area.rb
Expand Up @@ -2,7 +2,7 @@ module Locator
class Element
class TextArea < FormElement
def initialize
super(:textarea, :equals => [:id, :name])
super(:textarea)
end
end
end
Expand Down
28 changes: 22 additions & 6 deletions lib/locator/result.rb
@@ -1,13 +1,29 @@
module Locator
class Result < Array
MATCH_TYPES = {
:alt => :contains,
:title => :contains,
:content => :contains
}

class << self
def matches?(name, value, selector)
value = normalize_whitespace(value)
case selector
when Regexp
value =~ selector
else
type = MATCH_TYPES[name] || :equals
send("#{type}?", value, selector)
end
end

def equals?(value, selector)
value == selector
end

def matches?(value, selector)
value = normalize_whitespace(value)
Regexp === selector ? value =~ selector : value.include?(selector)
def contains?(value, selector)
value.include?(selector)
end

def normalize_whitespace(value)
Expand All @@ -20,7 +36,7 @@ def filter!(selector, locatables)
end

def filter(selector, locatables)
selector ? locatables.map { |(type, attrs)| filter_by(type, selector, attrs) }.flatten : self
selector ? filter_by(selector, locatables) : self
end

def sort!
Expand All @@ -34,11 +50,11 @@ def +(other)

protected

def filter_by(type, selector, attributes)
def filter_by(selector, attributes)
select do |element|
Array(attributes).any? do |name|
value = name == :content ? element.content : element.attribute(name.to_s)
element.matches << value if self.class.send("#{type}?", value, selector)
element.matches << value if self.class.matches?(name, value, selector)
end
end
end
Expand Down
4 changes: 4 additions & 0 deletions lib/locator/xpath.rb
Expand Up @@ -46,6 +46,10 @@ def and!(other)
replace(self.map { |l| other.map { |r| "#{l}#{r}" } })
end

def or!(other)
other.empty? ? self : replace([self.dup, other])
end

def to_s
flatten.join(' | ')
end
Expand Down
5 changes: 5 additions & 0 deletions test/locator/element_test.rb
Expand Up @@ -29,6 +29,11 @@ class LocatorElementTest < Test::Unit::TestCase
assert_equal ".//div[@type=\"type\"] | .//p[@type=\"type\"]", xpath
end

test "xpath merges given attributes with element attributes" do
xpath = Element.new(:div, :foo => 'foo').xpath(:bar => 'bar')
assert_equal ".//div[@foo=\"foo\"][@bar=\"bar\"]", xpath
end

# all

test "all selects all elements when given no attributes" do
Expand Down

0 comments on commit 87e6796

Please sign in to comment.