2009-12-09 18:03:55 +00:00
|
|
|
module Capybara
|
|
|
|
# this is a class for generating XPath queries, use it like this:
|
|
|
|
# Xpath.text_field('foo').link('blah').to_s
|
|
|
|
# this will generate an XPath that matches either a text field or a link
|
|
|
|
class XPath
|
|
|
|
class << self
|
2009-12-12 20:46:08 +00:00
|
|
|
def wrap(path)
|
|
|
|
if path.is_a?(self)
|
|
|
|
path
|
|
|
|
else
|
|
|
|
new(path.to_s)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-12-09 18:03:55 +00:00
|
|
|
def respond_to?(method)
|
|
|
|
new.respond_to?(method)
|
|
|
|
end
|
|
|
|
|
|
|
|
def method_missing(*args)
|
|
|
|
new.send(*args)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
attr_reader :paths
|
|
|
|
|
|
|
|
def initialize(*paths)
|
|
|
|
@paths = paths
|
|
|
|
end
|
|
|
|
|
|
|
|
def field(locator)
|
|
|
|
fillable_field(locator).file_field(locator).checkbox(locator).radio_button(locator).select(locator)
|
|
|
|
end
|
|
|
|
|
|
|
|
def fillable_field(locator)
|
|
|
|
text_field(locator).password_field(locator).text_area(locator)
|
|
|
|
end
|
2009-12-09 18:11:52 +00:00
|
|
|
|
|
|
|
def content(locator)
|
|
|
|
append("//*[contains(.,#{s(locator)})]")
|
|
|
|
end
|
|
|
|
|
|
|
|
def table(locator)
|
|
|
|
append("//table[@id=#{s(locator)} or contains(caption,#{s(locator)})]")
|
|
|
|
end
|
|
|
|
|
|
|
|
def fieldset(locator)
|
|
|
|
append("//fieldset[@id=#{s(locator)} or contains(legend,#{s(locator)})]")
|
|
|
|
end
|
2009-12-09 18:17:01 +00:00
|
|
|
|
|
|
|
def link(locator)
|
|
|
|
append("//a[@id=#{s(locator)} or contains(.,#{s(locator)}) or @title=#{s(locator)}]")
|
|
|
|
end
|
|
|
|
|
|
|
|
def button(locator)
|
|
|
|
xpath = append("//input[@type='submit' or @type='image'][@id=#{s(locator)} or @value=#{s(locator)}]")
|
|
|
|
xpath.append("//button[@id=#{s(locator)} or @value=#{s(locator)} or contains(.,#{s(locator)})]")
|
|
|
|
end
|
2009-12-09 18:03:55 +00:00
|
|
|
|
|
|
|
def text_field(locator)
|
2009-12-09 19:20:40 +00:00
|
|
|
add_field(locator) { |id| "//input[@type='text'][@id=#{id}]" }
|
2009-12-09 18:03:55 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def password_field(locator)
|
2009-12-09 19:20:40 +00:00
|
|
|
add_field(locator) { |id| "//input[@type='password'][@id=#{id}]" }
|
2009-12-09 18:03:55 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def text_area(locator)
|
2009-12-09 19:20:40 +00:00
|
|
|
add_field(locator) { |id| "//textarea[@id=#{id}]" }
|
2009-12-09 18:03:55 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def radio_button(locator)
|
2009-12-09 19:20:40 +00:00
|
|
|
add_field(locator) { |id| "//input[@type='radio'][@id=#{id}]" }
|
2009-12-09 18:03:55 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def checkbox(locator)
|
2009-12-09 19:20:40 +00:00
|
|
|
add_field(locator) { |id| "//input[@type='checkbox'][@id=#{id}]" }
|
2009-12-09 18:03:55 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def select(locator)
|
2009-12-09 19:20:40 +00:00
|
|
|
add_field(locator) { |id| "//select[@id=#{id}]" }
|
2009-12-09 18:03:55 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def file_field(locator)
|
2009-12-09 19:20:40 +00:00
|
|
|
add_field(locator) { |id| "//input[@type='file'][@id=#{id}]" }
|
2009-12-09 18:03:55 +00:00
|
|
|
end
|
2009-12-12 20:46:08 +00:00
|
|
|
|
|
|
|
def scope(scope)
|
|
|
|
XPath.new(*paths.map { |p| scope + p })
|
|
|
|
end
|
2009-12-09 18:03:55 +00:00
|
|
|
|
|
|
|
def to_s
|
|
|
|
@paths.join(' | ')
|
|
|
|
end
|
|
|
|
|
2009-12-09 18:17:01 +00:00
|
|
|
protected
|
2009-12-09 18:11:52 +00:00
|
|
|
|
2009-12-09 19:20:40 +00:00
|
|
|
def add_field(locator)
|
|
|
|
xpath = append(yield(s(locator)))
|
2009-12-09 20:53:12 +00:00
|
|
|
xpath = xpath.append(yield("//label[contains(.,#{s(locator)})]/@for"))
|
2009-12-09 19:20:40 +00:00
|
|
|
xpath.prepend(yield("//label[text()=#{s(locator)}]/@for"))
|
|
|
|
end
|
|
|
|
|
2009-12-09 18:11:52 +00:00
|
|
|
# Sanitize a String for putting it into an xpath query
|
|
|
|
def s(string)
|
|
|
|
if string.include?("'")
|
|
|
|
string = string.split("'", -1).map do |substr|
|
|
|
|
"'#{substr}'"
|
|
|
|
end.join(%q{,"'",})
|
|
|
|
"concat(#{string})"
|
|
|
|
else
|
|
|
|
"'#{string}'"
|
|
|
|
end
|
|
|
|
end
|
2009-12-09 19:20:40 +00:00
|
|
|
|
|
|
|
def prepend(path)
|
|
|
|
XPath.new(*[path, @paths].flatten)
|
|
|
|
end
|
2009-12-09 18:03:55 +00:00
|
|
|
|
|
|
|
def append(path)
|
|
|
|
XPath.new(*[@paths, path].flatten)
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|