Pulling attribute conditions up from have_selector to have_xpath
This commit is contained in:
parent
1625e3e9ba
commit
29c40bd73c
@ -18,6 +18,7 @@ module Webrat
|
||||
|
||||
def tag_inspect
|
||||
options = @options.dup
|
||||
count = options.delete(:count)
|
||||
content = options.delete(:content)
|
||||
|
||||
html = "<#{@expected}"
|
||||
@ -35,29 +36,7 @@ module Webrat
|
||||
end
|
||||
|
||||
def query
|
||||
options = @options.dup
|
||||
selector = @expected.to_s
|
||||
|
||||
options.each do |key, value|
|
||||
next if [:content, :count].include?(key)
|
||||
selector << "[#{key}='#{value}']"
|
||||
end
|
||||
|
||||
Nokogiri::CSS::Parser.parse(selector).map { |ast| ast.to_xpath }.first
|
||||
end
|
||||
|
||||
def xpath_escape(string)
|
||||
if string.include?("'") && string.include?('"')
|
||||
parts = string.split("'").map do |part|
|
||||
"'#{part}'"
|
||||
end
|
||||
|
||||
"concat(" + parts.join(", \"'\", ") + ")"
|
||||
elsif string.include?("'")
|
||||
"\"#{string}\""
|
||||
else
|
||||
"'#{string}'"
|
||||
end
|
||||
Nokogiri::CSS::Parser.parse(@expected.to_s).map { |ast| ast.to_xpath }.first
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -37,6 +37,21 @@ module Webrat
|
||||
@query = query
|
||||
end
|
||||
|
||||
attribute_conditions = []
|
||||
|
||||
@options.each do |key, value|
|
||||
next if [:content, :count].include?(key)
|
||||
attribute_conditions << "@#{key} = #{xpath_escape(value)}"
|
||||
end
|
||||
|
||||
if attribute_conditions.any?
|
||||
@query.first << "[#{attribute_conditions.join(' and ')}]"
|
||||
end
|
||||
|
||||
if @options[:content]
|
||||
@query.first << "[contains(., #{xpath_escape(@options[:content])})]"
|
||||
end
|
||||
|
||||
@document = Webrat.rexml_document(stringlike)
|
||||
|
||||
@query.map do |q|
|
||||
@ -55,8 +70,19 @@ module Webrat
|
||||
@query = query
|
||||
end
|
||||
|
||||
attribute_conditions = []
|
||||
|
||||
@options.each do |key, value|
|
||||
next if [:content, :count].include?(key)
|
||||
attribute_conditions << "@#{key} = #{xpath_escape(value)}"
|
||||
end
|
||||
|
||||
if attribute_conditions.any?
|
||||
@query.first << "[#{attribute_conditions.join(' and ')}]"
|
||||
end
|
||||
|
||||
if @options[:content]
|
||||
query << "[contains(., #{xpath_escape(@options[:content])})]"
|
||||
@query.first << "[contains(., #{xpath_escape(@options[:content])})]"
|
||||
end
|
||||
|
||||
@document = Webrat::XML.document(stringlike)
|
||||
@ -77,7 +103,24 @@ module Webrat
|
||||
# String:: The failure message to be displayed in negative matches.
|
||||
def negative_failure_message
|
||||
"expected following text to not match xpath #{@expected}:\n#{@document}"
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def xpath_escape(string)
|
||||
if string.include?("'") && string.include?('"')
|
||||
parts = string.split("'").map do |part|
|
||||
"'#{part}'"
|
||||
end
|
||||
|
||||
"concat(" + parts.join(", \"'\", ") + ")"
|
||||
elsif string.include?("'")
|
||||
"\"#{string}\""
|
||||
else
|
||||
"'#{string}'"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Matches HTML content against an XPath query
|
||||
|
@ -22,6 +22,34 @@ describe "have_xpath" do
|
||||
@body.should have_xpath("//div")
|
||||
end
|
||||
|
||||
it "should be able to match an XPATH with attributes" do
|
||||
@body.should have_xpath("//div", :class => "inner")
|
||||
end
|
||||
|
||||
it "should be able to match an XPATH with content" do
|
||||
@body.should have_xpath("//div", :content => "hello, world!")
|
||||
end
|
||||
|
||||
it "should not match an XPATH without content" do
|
||||
@body.should_not have_xpath("//div", :content => "not present")
|
||||
end
|
||||
|
||||
it "should be able to match an XPATH with content and class" do
|
||||
@body.should have_xpath("//div", :class => "inner", :content => "hello, world!")
|
||||
end
|
||||
|
||||
it "should not match an XPATH with content and wrong class" do
|
||||
@body.should_not have_xpath("//div", :class => "outer", :content => "hello, world!")
|
||||
end
|
||||
|
||||
it "should not match an XPATH with wrong content and class" do
|
||||
@body.should_not have_xpath("//div", :class => "inner", :content => "wrong")
|
||||
end
|
||||
|
||||
it "should not match an XPATH with wrong content and wrong class" do
|
||||
@body.should_not have_xpath("//div", :class => "outer", :content => "wrong")
|
||||
end
|
||||
|
||||
it "should not match a XPATH that does not exist" do
|
||||
@body.should_not have_xpath("//p")
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user