Best way to debug rspec integration tests with capybara? - ruby-on-rails-3

I have an rspec test failing, but in development, when I perform the actions myself, the page renders correctly.
Here's the snippet:
describe "sign up process" do
let (:admin1) { FactoryGirl.create(:admin) }
describe "with valid information"
before do
visit new_admin_registration_path
fill_in "Email", with: admin1.email
fill_in "Password", with: admin1.password
fill_in "Password confirmation", with: admin1.password_confirmation
click_button "Sign up"
end
it { should have_selector('div.alert') }
end
It's not finding that selector at all, but I confirmed it exists when viewing the source using the development environment.
What I'd like to be able to do is inspect the page that's rendering to see what I'm missing. Is there a way to do that?

Capybara has a method save_and_open_page which will open a new browser window with the current state of the page (it requires the launchy gem).
For example:
before do
...
click_button "Sign up"
save_and_open_page
end

this is as easy as using the debugger or something different like pry in your spec.
i personally prefer pry, cause installing the debugger was kind of a hassle everytime i tried it with ruby 1.9...
with pry you would just add a require "pry" in your spec_helper.rb and then write a binding.pry the line before the problem occurs. you then have an irb session attached to your test.

Related

By filling in the code marked FILL_IN in Listing 3.42, write a test for the root route

Adding the root route in Listing 3.41 leads to the creation of a Rails helper called root_url (in analogy with helpers like static_pages_home_url). By filling in the code marked FILL_IN in Listing 3.42, write a test for the root route.
Listing 3.41: Setting the root route to the Home page.
config/routes.rb
Rails.application.routes.draw do
root 'static_pages#home'
end
Listing 3.42: A test for the root route. green
test/controllers/static_pages_controller_test.rb
require 'test_helper'
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
test "should get root" do
get FILL_IN
assert_response FILL_IN
end
end
What Should be the FILL_IN?
I tried static_pages_root_url, root_url.
rails test fails.
F
Failure:
StaticPagesControllerTest#test_should_get_root [/home/ubuntu/workspace/sample_app/test/controllers/static_pages_controller_test.rb:12]:
<Root | Ruby on Rails Tutorial Sample App> expected but was
<Home | Ruby on Rails Tutorial Sample App>..
Expected 0 to be >= 1.
E
Error:
StaticPagesControllerTest#test_should_get_root:
ArgumentError: Invalid response name: root_url
test/controllers/static_pages_controller_test.rb:11:in `block in <class:StaticPagesControllerTest>'
Try with:
test "should get root" do
get '/'
assert_response :success
end
More info on http://guides.rubyonrails.org/testing.html#implementing-an-integration-test
I was able to get it to work with root_url. You might want to check that you are serving the home page on routes.rb.
For anyone else in the future you're telling it to go to your home page which is in your static pages controller then we copy the syntax from the other tests... so it ends up being written like this...
test "should get root" do
get static_pages_home_url
assert_response :success
end
In your test you should be telling it to look for the <Home | Ruby on Rails Tutorial Sample App> since root and home will display the same.
this is the complete solution (guarantee it will work)
test "should get root" do
get root_url
assert_response :success
assert_select "title", "Home | #{#base_title}"
end

How do I configure Capybara to work with Poltergeist?

I have an RSpec integration test that needs to execute some JavaScript. I've included Poltergeist and installed PhantomJS, but whenever I run the example, I get this error:
Failure/Error: page.execute_script("$('form')[0].submit();")
Capybara::NotSupportedByDriverError:
Capybara::Driver::Base#execute_script
The spec is:
require 'spec_helper'
describe "Signup", :type => :feature do
describe "workflow" do
it "ensures entry of contact information" do
visit 'signup/action'
# snip - use Capybara to fill out form elements
page.execute_script("$('form')[0].submit();")
page.should have_content("Name can't be blank")
page.should have_content("Email can't be blank")
# snip - use Capybara to fill out more form elements
page.execute_script("$('form')[0].submit();")
page.should have_content("Next page")
end
end
end
I think the problem is that I'm not sure how to indicate that Capybara should use Poltergeist as its JavaScript driver. The Poltergeist documentation says:
Installation
Add poltergeist to your Gemfile, and in your test setup add:
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
But it doesn't say which file specifically it should go into. It also says:
Customization
You can customize the way that Capybara sets up Poltegeist via the following code in your test setup:
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, options)
end
But it's not clear to me if or when I would need to include this in my tests. And again, I'm not sure where to put it if I need to.
What am I missing?
Where do I need to put the configuration for Capybara and Poltergiest, and what exactly does it need to say (or how can I determine that for myself)?
Is there a step or piece of configuration that I missed?
Try putting js: true in your describe line. I know i had to do that for feature specs on an app at work:
describe "Signup", :type => :feature, :js => true do
I don't see any other configuration for it. Was a while ago when I set it up :)
You can just call the Capybara driver config methods once before your RSpec.configure block:
Capybara.default_selector = :css
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, :window_size => [1920, 1080], :phantomjs_logger => nil)
end
Capybara.javascript_driver = :poltergeist
RSpec.configure do |config|
Also be sure to use truncation not transaction with database cleaner. Poltergeist runs on a separate thread, so you'll likely have weird db issues if you use transactional.
Edit
Ah the js true thing is mentioned under here: https://github.com/jnicklas/capybara#using-capybara-with-rspec in the capybara readme.

Capybara 2.0.0.beta4 has undefined paths

I just upgraded to Capybara 2.0.0.beta4 with rspec-rails 2.11.4 and I moved my request spec (I only have one) to spec/features as advised by the Capybara-Readme in the RSpec-Rails repository.
When I run the tests now it does not find any paths. So for the following test block:
it "should be able to access the signup page through the front page" do
visit root_path
click_link "Signup For Free Now"
page.should have_content("Signup")
end
I get the error message:
Failure/Error: visit root_path
NameError: undefined local variable or method `root_path' for #<RSpec...>
When I try to run the test with visit "/" it works fine. Other gem versions are:
rails 3.2.1
rspec 2.11.0
rack-test 0.6.2
Any ideas for a reason for the path problem?
Running "bundle update rspec-rails" to get version 2.12.0 solved the same issue for me.

RSpec View testing with Rails3 and RSpec2

RSpec2 does not include an have_tag test helper. Using webrat's have_tag or have_selector matchers instead is not possible because Webrat and Rails 3 are not compatible yet. Is there a way to write useful RSpec view tests? It is possible to use assert_select instead of have_tag, but then one could Test::Unit tests in the first place. Or is it no longer recommendable to write RSpec view tests, because integration tests with Capybara or Cucumber are better?
Actually, Webrat works with Rails 3. I have tested this and I was able to use the have_selector matcher (have_tag didn't work).
You can take a look at this Google group discussion. Basically, you don't need the Webrat.configure block mentioned in the webrat readme, and following the mailing list solution, add these lines in your spec_helper.rb:
include Webrat::Methods
include Webrat::Matchers
As you can see, Webrat is not so updated anymore, so yes, you might be better off with integration testing with Cucumber (+ Capybara).
Webrat caused too much trouble, it is also possible to use Capybara with RSpec. The Capybara DSL (with the functions has_selector?, has_content?, etc.) is available for the following RSpec tests: spec/requests, spec/acceptance, or spec/integration.
If you use the latest version of Capybara (~> 1.0.1) - older versions like 0.4.0 won't support this - and add the following lines to your spec_helper.rb file
require "capybara/rspec"
require "capybara/rails"
then you could write for example the following RSpec request test
require 'spec_helper'
describe "Posts" do
describe "GET /blog" do
it "should get blog posts" do
get blog_path
response.status.should be(200)
response.body.should have_selector "div#blog_header"
response.body.should have_selector "div#blog_posts"
end
end
end

RSpec and getting puts or logger.info to work

When I'm running my specs like "rspec ." from the command line, I can see puts or logger.info in the console, if i call that code in my spec. However, if the call to logger.info or puts is in my controller which I'm testing, it doesn't output to the test.log file or the console window.
I'm using RSpec 2 and Rails 3.0.4
Also, this is a refinerycms site, but we have a couple of controllers external to the Refinery CMS we are trying to test. When I do a puts or logger.info in a normal site, it seems to work fine, even running RSpec.
Thanks.
Okay so we finally figured this out.
The issue is that Refinery requires a default user to be created or it does not let you hit front end pages. When you first fire it up, it prompts the user to create a default admin login. So when we were running our tests, our code was never getting hit. Refinery was redirecting the "browser" during test time to the "create a first user" page.
We created a seed with a default user and then everything worked again. So the issue was never that doing a "puts" or "logger.info" didn't work in refinery or rspec. It was that during testing, we never were getting to our controller.