11

Capybara is confusing me. If I use Capybara in combination with Ruby on Rails 3 and RSpec 2, then in RSpec request tests, the following matcher works:

response.body.should have_selector "div.some_class"

The response object has the class ActionDispatch::TestResponse. But the following line, which should work officially, does not work:

page.should have_selector "div.some_class"

The page object has the class Capybara::Session. In which cases do you have to use the response.body object and when do you have to use a page object ?

0x4a6f4672
  • 27,297
  • 17
  • 103
  • 140

2 Answers2

18

So I just ran into similar, and this is I think what's going on:

It depends on code you didn't include here of how you visit the page. I'm writing an rspec request spec.

If I retrieve the page with rspec's own:

get '/some/path'

then response.body.should have_selector works as you say, but page.should does not.

To make Capybara 'page' work (and to make Capybara interactions like click_button or fill_in work), instead of retrieving with rspec's 'get', you need to retrieve with Capybara's 'visit':

visit '/some/path'
page.should have_selector("works")

'page', a capybara method, only gets set when using 'visit', a capybara method.

This does get confusing, all the mixing and matching of different libraries involved in rails testing.

jrochkind
  • 22,799
  • 12
  • 59
  • 74
  • 1
    Execellent answer. That is the difference. If you use rspec's get "/some/path", then response.body contains the resulting page and you can use response.body.should have_selector. If you Capybara's visit "/some/path", then page.body contains the resulting page and you can use page.should have_selector. – 0x4a6f4672 Mar 28 '12 at 16:48
  • the above fix didn't work for me - I still get the same error with visit ... and you are right it is damn confusing :-) – Sam Joseph Nov 22 '12 at 17:51
3

You would use response when you want to use the standard rails methods. And, alternately, you'd use page when you want to use the capybara methods. In capybara you'd most likely use have_css in the example given.

dogenpunk
  • 4,332
  • 1
  • 21
  • 29
  • 1
    Nevermind, I didn't realize that capybara has a have_selector method. But the answer remains, `page` for capybara, `response` for rails. – dogenpunk Aug 31 '11 at 18:59
  • but why does "page.should have something" does not work? we use require "capybara/rspec" and require "capybara/rails" in our Rails 3 app, and yet "page.should .." does not work in RSpec request tests. – 0x4a6f4672 Sep 01 '11 at 08:16
  • I wish I knew. Seems that mixing the RSpec and Capybara syntaxes causes some problem. I know that `page.body has_content?` works for me where `page.should have_content` rarely does. – dogenpunk Sep 01 '11 at 14:44
  • I've begun to just use `page.should have_xpath` everywhere. – Tass Feb 28 '12 at 14:45