Broken controller tests after installing Capybara? - ruby-on-rails

I had a bunch of combined controller/view tests written with rspec. I added the Capybara gem and wrote some integrations tests which pass fine. The only problem is that now in all my controller tests, where I have
response.should have_selector("some selector")
rspec gives errors such as:
NoMethodError:
undefined method `has_selector?' for #<ActionController::TestResponse:0xa03e7ec>
when I run controller tests. I'm guessing that Capybara is being used in my controller tests and has overwritten some Rspec methods. How can I fix this?
# gemfile.rb
group :test do
gem 'rspec'
gem "capybara"
gem "launchy"
gem 'factory_girl_rails', '1.0'
end
# spec_helper.rb
RSpec.configure do |config|
config.include IntegrationSpecHelper, :type => :request
end
Here's an example of a failing test:
# spec/controllers/books_controller_spec.rb
require 'spec_helper'
describe BooksController do
render_views
it "should have the right page title" do
get :show, :id => #book.ean
response.should have_selector("title", :content => "Lexicase | " + #book.title)
end
end
and it's associated error:
1) BooksController GET 'show' should have the right page title
Failure/Error: response.should have_selector("title", :content => "Lexicase | " + #book.title)
NoMethodError:
undefined method `has_selector?' for #<ActionController::TestResponse:0xa8488c0>
# ./spec/controllers/books_controller_spec.rb:23:in `block (3 levels) in <top (required)>'

You were probably using Webrat earlier, and has_selector? is a Webrat matcher. Capybaras doesn't have a has_selector matcher, it has a matcher called has_css. You may want to replace the "has_selector" with "has_css".

Capybara helpers only works within requests specs. Either create a new request spec, or pass in :type => :request in the describe block part, like so:
describe "test for the testing test", :type => :request do
it "should work with capybara" do
visit root_path
click_link "Home"
page.should WHATEVA
end
end
I realize this question was asked a long time ago, but I thought I would share anyway. GLHF

Related

Rspec producing a undefined method `route_to' , despite having rspec/rails defined in gemfile/rails helper

QUESTION: What have I done wrong that the route_to method remains undefined?
I'm very new to this but I'm trying to develop some route tests via the rspec gem.
My issue is that I am obtaining the error:
undefined method `route_to' for #<RSpec::ExampleGroups::RouteToHomepage
I have already looked through the API for this query, and I've already done the following:
Install gem 'rspec-rails'
In rails_helper.rb
require 'rspec/rails'
In my routing_spec.rb (where I am writing the routes)
require 'rails_helper'
describe "route to homepage" do
it "routes /home to index" do
expect(:get => "/homes").to route_to(
action: "index"
)
end
end
What exactly do I need to change or add, so the "route_to" method is defined? I've already read around and apparently it's defined in the "rspec-rails" gem, which I have, and already included.
From the documentation:
Routing specs are marked by :type => :routing or if you have set
config.infer_spec_type_from_file_location! by placing them in spec/routing.
You didn't say where the routing_spec.rb is located, but if it's inside the folder spec/routing/ then you could choose to enable the above config option.
Otherwise, or in general, you must do this:
require 'rails_helper'
describe "route to homepage", type: :routing do
it "routes /home to index" do
expect(:get => "/homes").to route_to(
action: "index"
)
end
end
Doing this will include the necessary RSpec helper that defines route_to, among other methods.

Rspec undefined method `route_to' when testing one route?

I am new to Rspec and am trying to test the one route in my application. I have installed Rspec and have included the routing file in spec/routing/routes_spec.rb.
My spec is as follows:
require "spec_helper"
describe "Routes" do
it "routes get index" do
expect(:get => "simulations").to route_to(
:controller => "simulations",
:action => "index"
)
end
end
I get this error:
Routes routes get index
Failure/Error: expect(:get => "simulations").to route_to(
NoMethodError:
undefined method `route_to' for #<RSpec::ExampleGroups::Routes:0x007fc32d2f70b8 #__memoized=nil>
# ./spec/routing/routes_spec.rb:6:in `block (2 levels) in <top (required)>'
Any ideas as to why route_to would be undefined? I have verified that the route actually works.
In Rspec 3 you should require 'rails_helper' rather than require 'spec_helper'.
Based on documentation:
Routing specs are marked by :type => :routing or if you have set config.infer_spec_type_from_file_location! by placing them in spec/routing.
So, unless you set the previous option, you should begin your spec with:
describe "Routes", :type => :routing do
As Fire-Dragon-DoL suggests above, you might like to check that the rspec-rails gem is in place.
When you don't have rspec-rails installed and required, and you use to_route method, you will get the same error when running your specs: NoMethodError: undefined method 'route_to'
Given the same setup, when you use be_routable matcher, then you get another error, in the style of: expected {:get=>"/my_models/} to respond to 'routable?'
To remedy these errors
Add rspec-rails to Gemfile
Run bundle install
Add require 'rspec/rails' to spec_helper (or rails_helper)

Testing page title with Capybara 2.4 and rspec 3 and rails 4

I am trying to test the title of my static pages in rails. I'm using Capybara 2.4.4 and rspec 3.
My test looks like the following
static_pages_controller_spec.rb
require 'spec_helper'
require 'rails_helper'
describe StaticPagesController do
describe "GET 'Index'" do
it "should be successful" do
visit root_path
response.should be_success
end
it "should have the right title" do
visit root_path
expect(page).to have_selector('title',
:text => "Index",
:visible => false)
end
end
end
The page does have the correct title set.
The error I'm getting says the following
Failure/Error: expect(page).to have_selector('title',
expected to find css "title" with text "Index" but there were no matches
I spent quite a few hours trying to figure it out as well.
Ultimately what worked was this
Install capybara as a gem
group :test do
gem 'rspec'
gem 'capybara'
end
and run bundle install
Add the following to the top of spec/spec_helper.rb
require 'capybara/rails'
require 'capybara/rspec'
Then inside the RSpec.configure, add the config.include Capybara::DSL
RSpec.configure do |config|
.
.
.
config.include Capybara::DSL
end
Then in your pages_controller_spec.rb, modify to use as follows.
Notice that I have included Capybara.ignore_hidden_elements = false
describe PagesController do
render_views
Capybara.ignore_hidden_elements = false
describe "GET 'home'" do
it "should be successful" do
get 'home'
response.should be_success
end
it "should have the right title" do
get 'home'
response.body.should have_xpath("//title",:text => "ROR")
end
end
end
Check my repository if you want see anything else
The following cheatsheet should come handy as well
https://gist.github.com/them0nk/2166525

have_selector is failing test

I am having a problem including a should have_selector problem with rspec:
This is my code:
describe "GET 'home'" do
it "returns http success" do
get 'home'
expect(response).to be_success
end
it "should have the right title" do
should have_selector("title",
:content => "Ruby on Rails Tutorial Sample App | Home")
end
end
I have included the following at the top:
RSpec.describe PagesController, :type => :controller do
render_views
My html5 has the following:
<title>Ruby on Rails Tutorial Sample App | Home</title>
and I get an error message saying:
Failures:
1) PagesController GET 'home' should have the right title
Failure/Error: should have_selector("title",
expected #<PagesController:0x007fceef586a90> to respond to `has_selector?`
# ./spec/controllers/pages_controller_spec.rb:14:in `block (3 levels) in <top (required)>
Can someone help with that?
rspec -v
3.0.2
rails 4.1.1
thank you in advance.
Rspec 3 does not include the capybara matchers in controller specs by default. You can change this for an individual spec by doing
include Capybara::RSpecMatchers
Or, in your spec helper
config.include Capybara::RSpecMatchers, :type => :controller
Your next issue is that recent versions of capybara don't allow you to test for the presence of invisible elements by default, and the title element is considered to be invisible. You should use the have_title matcher instead.
Hollo rubyist pal!
I had this problem and that was because of two things, first I did not use capybara gem, and second have_selector only accepts one of :count, :minimum, :maximum, :between, :text, :visible, :exact, :match, :wait keys and does not understand :content.
I am sure you solved the problem, but for those who have started to learn Ruby on Rails recently and encountered such a problem I should say to eleminate it first put capybara gem in your Gemfile as below:
group :development, :test do
...
gem 'capybara'
end
and run command
bundle install
then to test that your view has a specific title, in pages_controller_spec.rb file write
describe "GET #home" do
...
it "should have the right title" do
get :home
expect(response.body).to have_selector('title', :text => 'Ruby on Rails rocks')
end
end
I hope it would help someone.
Cheerio!
Checking content is view spec...
And controller spec means checking response status/path, render page/partials, instance variable filters params.

Migrating from Webrat to Capybara...unsuccessfully

Hoping someone might see what I've overlooked...
I'm trying to get Capybara working in a small existing application...and I'm not having any luck.
Gemfile:
group :development, :test do
gem 'rspec-rails'
# gem 'webrat'
gem 'capybara', :git => 'git://github.com/jnicklas/capybara.git'
end
...
Similar specs in two places are failing for different reasons. Not sure why?
spec/controllers/pages_controller_spec.rb:
require 'spec_helper'
describe PagesController do
describe "GET 'about'" do
it "should be successful" do
# get 'about' #worked w/ webrat
# response.should be_success #worked w/ webrat
visit pages_about_path
# page.should have_content('About Us')
page.html.should match(/About/i)
end
it "should have title" do
# get 'about' #webrat
# response.should have_selector("title", :content => "About Us") #webrat
visit pages_about_path
page.should have_selector("title")
end
end
end
Failures:
(may be pulling in some generic page as doctype in browser is "<!DOCTYPE html>")
1) PagesController GET 'about' should be successful
Failure/Error: page.html.should match(/About/i)
expected "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n\n" to match /About/i
# ./spec/controllers/pages_controller_spec.rb:13:in `block (3 levels) in <top (required)>'
2) PagesController GET 'about' should have the right title
Failure/Error: page.should have_selector("title")
expected css "title" to return something
# ./spec/controllers/pages_controller_spec.rb:20:in `block (3 levels) in <top (required)>'
spec/views/pages/about.html.haml_spec.rb:
require 'spec_helper'
describe "pages/about.html.haml" do
it "renders attributes in <p>" do
# render #webrat
# rendered.should match(/About/) #webrat
visit pages_about_path
page.should have_content("About Us")
end
it "should have the right heading" do
# render #webrat
# rendered.should have_selector("h2", :content => "About Us") #webrat
visit pages_about_path
page.should have_selector("h2")
end
end
Failures:
1) pages/about.html.haml renders attributes in <p>
Failure/Error: visit pages_about_path
NoMethodError:
undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_1:0x00000101dc2970>
# ./spec/views/pages/about.html.haml_spec.rb:8:in `block (2 levels) in <top (required)>'
2) pages/about.html.haml should have the right heading
Failure/Error: visit pages_about_path
NoMethodError:
undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_1:0x000001034b1d98>
# ./spec/views/pages/about.html.haml_spec.rb:16:in `block (2 levels) in <top (required)>'
Just had the same issue and found that capybara needs:
response.body.should have_selector("title")
webrat does not need the .body
also, make sure you are rendering views eg:.
describe PagesController do
render_views
You should include capybara DSL in your test file :
require 'spec_helper'
describe PagesController do
include Capybara::DSL
describe "GET 'about'" do
it "should be successful" do
...
This won't fix all your problems, but Instead of:
page.html.should match(/About/i)
try:
page.should match(/About/i)
(you might not even need page).
Also, check that you have Capybara set to use CSS queries in env.rb (it defaults to XPath).
Ensure that your spec_helper.rb file has the following at the top:
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rspec'
I had a similar issue as yours (i.e., undefined method 'visit') and popping those lines solved the issue.

Resources