Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you use the rspec have_selector method to verify XML?

I want to do some basic checking to ensure that an XML sitemap is being produced correctly but have_selector doesn't seem to be able to detect tags:

require 'spec_helper'

describe SitemapController do

  render_views

  before(:all) do
    # code to generate factory data
    # ...
  end

  # illustrating the problem
  it "should be able detect nodes that are definitely present" do
    get :index
    response.should have_selector('url')
  end
end

Every time I run the test I get the following error:

RSpec::Expectations::ExpectationNotMetError: expected css "url" to return something

The sitemap is being produced and when I debug the RSpec test and look at the response object I can see xml content:

ruby-1.9.2-p180 :001 > response.body
 => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n  <url>\n    <loc>http://test.host/panel ... 

My sitemap is produced by the SitemapController and the view is located in views/sitemap/index.builder.xml.

Why isn't have_selector kicking in?

like image 321
Peter Nixey Avatar asked Nov 29 '11 10:11

Peter Nixey


3 Answers

Capybara doesn't support XML responses. It always uses Nokogiri::HTML to parse the content, which produces unexpected results when given XML.

Adding XML support has been requested but was rejected by Capybara's maintainer.

like image 150
John Avatar answered Oct 21 '22 01:10

John


Use should have_xpath('//url') instead. have_selector is for CSS.

See the Capybara README for more info.

like image 35
David Chelimsky Avatar answered Oct 21 '22 00:10

David Chelimsky


As far as I can tell the have_selector (or have_xpath) can only come from Webrat or Capybara. You're right in your comment to John that you don't need a browser simulator to test the API.

You may be invoking Webrat or Capybara by mistake as they use visit instead of get AFAIK. So the variables they match against may never have been populated by the page and so will always return false.

Rails should handle the XML document natively if the response content-type is correctly set to XML. Try using the assert_tag or assert_content test helper as a basic check.

I would just use Nokogiri to parse the XHTML and run normal RSpec tests against that:

xml = Nokogiri::XML(response.body)
xml.css("expression").size.should == 1
like image 20
Andrew France Avatar answered Oct 21 '22 01:10

Andrew France