Rspec 3.X: native built in html matchers? Or do we have to use Capybara?

1.5k views Asked by At

I've been reading a ton of docs and SO questions/ answers on all the changes as Rspec has evolved, want to be sure of the answer...

My goal is to use native Rspec-rails (I have 3.2.2) to do integrated controller/view tests that look for 1) CSS classes and 2) ID selectors. In other words given this view snippet:

<!-- staticpages/dashboard -->
<div class="hidden">Something</div>
<div id="creation">This</div>

This should pass (however it should be semantically written):

describe StaticpagesController do
  render_views

  it "should find everything" do
    get :dashboard
    expect(response.body).to have_selector("div#creation")
    expect(response.body).to have_css("hidden")
    expect(response.body).to_not have_selector("div#nothinghere")
  end
end

I would like to do this without additional gems like Capybara; is that possible?

Here's a high level of what I've learned so far:

In my own experimentation, the code above generated:

Expect<long response.body here>.to respond to `has_selector?`

So that has indeed been deprecated. Still, I'd love to know if there's some other way to do this that I don't know about.

IF it turns out I need Capybara to do these fancy matchers, is there a way to do this in my integrated controller/view specs? My understanding is that I have to add type: :feature to the describe StaticpagesController line to use Capybara's matchers. However, the minute I do that, render_views is no longer available (since it's limited to type: :controller). Note, render_views also dies if, per this post (https://www.relishapp.com/rspec/rspec-rails/v/2-99/docs/controller-specs/use-of-capybara-in-controller-specs), I manually include Capybara::DSL into my controller spec. Anyway, I would really like to not have to rewrite my current controller specs into a bunch of feature specs...

1

There are 1 answers

2
Paul Fioravanti On

It would seem that you want feature specs (with Capybara) more than controller specs as you're not testing any of the things controller specs are typically used to test such as:

  • whether a template is rendered
  • whether a redirect occurs
  • what instance variables are assigned in the controller to be shared with the view
  • the cookies sent back with the response

Also, you probably want to consider writing feature specs for new apps over controller specs since controller tests will probably be dropped in Rails 5 in favor of the writing of integration/feature tests.

For a description of the different kinds of specs that you could write, and what they're typically used for, see this SO answer.