Skip to content

Commit

Permalink
XPath escape value in select/unselect under rack-test
Browse files Browse the repository at this point in the history
  • Loading branch information
jnicklas committed Apr 26, 2010
1 parent 32b3b6a commit cbb42a1
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 14 deletions.
10 changes: 5 additions & 5 deletions lib/capybara/driver/rack_test_driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def [](name)

def set(value)
if tag_name == 'input' and type == 'radio'
driver.html.xpath("//input[@name='#{self[:name]}']").each { |node| node.remove_attribute("checked") }
driver.html.xpath("//input[@name=#{Capybara::XPath.escape(self[:name])}]").each { |node| node.remove_attribute("checked") }
node['checked'] = 'checked'
elsif tag_name == 'input' and type == 'checkbox'
if value
Expand All @@ -49,8 +49,8 @@ def select(option)
node.xpath(".//option[@selected]").each { |node| node.remove_attribute("selected") }
end

if option_node = node.xpath(".//option[text()='#{option}']").first ||
node.xpath(".//option[contains(.,'#{option}')]").first
if option_node = node.xpath(".//option[text()=#{Capybara::XPath.escape(option)}]").first ||
node.xpath(".//option[contains(.,#{Capybara::XPath.escape(option)})]").first
option_node["selected"] = 'selected'
else
options = node.xpath(".//option").map { |o| "'#{o.text}'" }.join(', ')
Expand All @@ -63,8 +63,8 @@ def unselect(option)
raise Capybara::UnselectNotAllowed, "Cannot unselect option '#{option}' from single select box."
end

if option_node = node.xpath(".//option[text()='#{option}']").first ||
node.xpath(".//option[contains(.,'#{option}')]").first
if option_node = node.xpath(".//option[text()=#{Capybara::XPath.escape(option)}]").first ||
node.xpath(".//option[contains(.,#{Capybara::XPath.escape(option)})]").first
option_node.remove_attribute('selected')
else
options = node.xpath(".//option").map { |o| "'#{o.text}'" }.join(', ')
Expand Down
6 changes: 6 additions & 0 deletions lib/capybara/spec/session/select_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
extract_results(@session)['title'].should == 'Mr'
end

it "should escape quotes" do
@session.select("John's made-up language", :from => 'Locale')
@session.click_button('awesome')
extract_results(@session)['locale'].should == 'jo'
end

context "with a locator that doesn't exist" do
it "should raise an error" do
running { @session.select('foo', :from => 'does not exist') }.should raise_error(Capybara::ElementNotFound)
Expand Down
6 changes: 6 additions & 0 deletions lib/capybara/spec/session/unselect_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
extract_results(@session)['underwear'].should include('Commando', 'Boxer Briefs')
extract_results(@session)['underwear'].should_not include('Briefs')
end

it "should escape quotes" do
@session.unselect("Frenchman's Pantalons", :from => 'Underwear')
@session.click_button('awesome')
extract_results(@session)['underwear'].should_not include("Frenchman's Pantalons")
end
end

context "with single select" do
Expand Down
2 changes: 2 additions & 0 deletions lib/capybara/spec/views/form.erb
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
<option selected="selected" value="en">English</option>
<option value="fi">Finish</option>
<option value="no">Norwegian</option>
<option value="jo">John's made-up language</option>
</select>
</p>

Expand Down Expand Up @@ -142,6 +143,7 @@
<option>Boxers</option>
<option selected="selected">Briefs</option>
<option selected="selected">Commando</option>
<option selected="selected">Frenchman's Pantalons</option>
</select>
</p>

Expand Down
21 changes: 12 additions & 9 deletions lib/capybara/xpath.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ module Capybara
class XPath

class << self
def escape(string)
if string.include?("'")
string = string.split("'", -1).map do |substr|
"'#{substr}'"
end.join(%q{,"'",})
"concat(#{string})"
else
"'#{string}'"
end
end

def wrap(path)
if path.is_a?(self)
path
Expand Down Expand Up @@ -161,15 +172,7 @@ def extract_postfix(options)

# 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

XPath.escape(string)
end

end
Expand Down

0 comments on commit cbb42a1

Please sign in to comment.