Working on a new Rails 3.2.9 app with rspec and capybara.
I have the following in the Gemfile:
gem 'rspec-rails'
gem 'capybara'
and the following in spec/spec_helper.rb:
require 'rspec/rails'
require 'capybara/rspec'
and in spec/requests/asdf_spec.rb:
require 'spec_helper'
describe 'Asdf' do
describe "GET /asdfs" do
it "should list asdfs" do
visit asdfs_path
end
end
end
This test is failing:
Failure/Error: visit asdfs_path
NoMethodError:
undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_2::Nested_1:0x007fa7b68961a0>
# ./spec/requests/asdfs_spec.rb:19:in `block (4 levels) in <top (required)>'
So it looks like Capybara isn't getting loaded. Ack, why not? I feel like I've done this exact same thing a dozen times before... probably blanking on something stupid.
So it was a capybara version 2 change. I found this:
http://alindeman.github.com/2012/11/11/rspec-rails-and-capybara-2.0-what-you-need-to-know.html
which explains:
Upon upgrading to capybara 2.0, capybara will not be available by
default in RSpec request specs. Instead, a new type of spec--the
feature spec--has been created for use with capybara.
To upgrade to capybara 2.0, you'll need to do a few things:
Upgrade rspec-rails to 2.12.0 or greater
Move any tests that use capybara from spec/requests to spec/features. Capybara
tests use the visit method and usually assert against page.
Just some additional info for anybody having the same problem with the Capybara upgrade to 2.x. Check out rspec-rails docs under the Upgrading to Capybara 2 section.
Basically, In order to use the Capybara DSL(page & visit) you must move your existing specs into the spec/features directory. So you can only use page & visit in acceptance tests. No more page & visit in controller and request specs. Only the rack-test DSL (get|post|put|delete|head/response.body) is allowed in controller and request specs.
This is not recommended but there is a way to keep your specs working as they are:
RSpec.configure do |c|
c.include Capybara::DSL, :example_group => {
:file_path => "spec/requests"
}
end
The docs state that if you go this route then you are overriding the intended behavior and you are taking a risk.
And definitely don't make this as a reason not to upgrade to Capybara 2.x. Feature specs are easy to get used to and are easy to read. feature is just an alias for describe, background is an alias for before, scenario for it, and given for let.
Hope this helps anyone confused by the new changes.
The issue is in capybara gem itself.
gem 'capybara', '1.1.2' solves this issue ( Version 2.0.x fails )
I'm trying to test my cucumber scenarios with capybara and selenium but I get blank pages all the time.
I read this: Capybara + RSpec only sees blank pages in controller specs. Why?
But It's not exactly the same because that is with rspec.
My env.rb has:
Capybara.default_driver = :webkit
I have try to change it to :selenium but it's the same story.
Any help?
Why not use these drivers only for javascript, do you really need them as default driver?
Do you want to always use them?
It could just be a timeout issue..
If you want to set them for JavaScript only do this instead (env.rb):
Capybara.javascript_driver = :webkit
And decorate your scenarios with #javascript as such:
#javascript
Scenario: Customers List
Ive setup capybara-webkit for my integration tests and Im running into a very simple problem. My session is not being stored. The use case is pretty simple
1. Login
2. Go to a specific page
3. Check if it has the approp content
Now at step 2 my app is returning the test case to the login page - which means the session is not being set properly.
any help is much appreciated
If I use #culerity instead of #javascript then this test case passes so the problem seems to be the capybara-webkit setup
My env.rb for capybara-webkit support is as follows
Spork.prefork do
require 'cucumber/rails'
require 'capybara'
require 'capybara/dsl'
require 'capybara/cucumber'
require 'capybara-webkit'
Capybara.run_server = false
Capybara.javascript_driver = :webkit
Capybara.default_selector = :css
# Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
# order to ease the transition to Capybara we set the default here. If you'd
# prefer to use XPath just remove this line and adjust any selectors in your
# steps to use the XPath syntax.
# Capybara.default_host = "127.0.0.1:3000"
Capybara.app_host = "http://localhost:3000"
end
Update 1:
Looks like the sessions is being set. I used the following code to dump the session in my steps
puts(Capybara.current_session.driver.browser.get_cookies)
and I got the follwoing - so looks like cookie is being set but not being sent back
["_jqt_session=BAh7CEkiD3Nlc3Npb25faWQGOgZFRiIlYmMwYzNjYjY0MGU3NTg0OWFlNTcwODhmM2I2MzE1YmRJIhBfY3NyZl90b2tlbgY7AEZJIjEwRzN6NG1NTzZqamNCNC9FdWZWeXBCMHdoeThueXBnaTJDcTVzbmJqQlBZPQY7AEZJIgpmbGFzaAY7AEZJQzolQWN0aW9uRGlzcGF0Y2g6OkZsYXNoOjpGbGFzaEhhc2h7BjoKYWxlcnRJIh9JbnZhbGlkIGVtYWlsIG9yIHBhc3N3b3JkLgY7AFQGOgpAdXNlZG86CFNldAY6CkBoYXNoewY7B1Q%3D--3fbe1c2a77a433228e7b7f2d8c8f0aec3ad5fb5f; HttpOnly; domain=localhost; path=/"]
Update 2:
was barking up the wrong tree. Seems that the user I was creating in my test case was not being seen by the rails app as my database cleaner strategy was set to transactional. see more info at
https://groups.google.com/forum/#!msg/ruby-capybara/JI6JrirL9gM/R6YiXj4gi_UJ
To add more clarity,
Capybara webkit or selenium driver is running in a different thread then app, so if you are using transactional fixtures or database_cleaner with strategy :transaction and your data isn't commited to db and another thread won't see it.
Possible solutions are:
Use database_cleaner with strategy :truncation. (solid, but a slow)
Add code to force active record using single transaction for all threads. (faster, but may have some issues, ex.: after_commit hooks aren't called, as there's no commit)
#Capybara use the same connection
class ActiveRecord::Base
mattr_accessor :shared_connection
##shared_connection = nil
def self.connection
##shared_connection || retrieve_connection
end
end
# Forces all threads to share the same connection. This works on
# Capybara because it starts the web server in a thread.
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
I'm using 2-nd option, but it's arguable.
I've been using Capybara for integration/request testing, but have only just realised I can't do view testing with it.
This SO answer suggests Webrat and Capybara can be used in tandem; but the RSpec docs suggest one must choose between the two. Here's another github thread that suggests webrat can be used for views and capybara for integration.
I've found that if I include Webrat in my gemfile, I can use webrat for views with no problem, but my capybara-styled integration tests no longer work. Specifically, I get an error with the following simple example:
it "should have a Home page at '/'" do
visit '/'
page.should have_selector('title', :content => "Home page")
end
I get the error:
No response yet. Request a page first.
What's the best way (if any?) to get webrat and capybara to like eachother?
There's generally no reason to use both Webrat and Capybara. Pick one (probably Capybara). View tests are a bad idea and shouldn't be necessary in general; usually your integration tests should cover that ground.
In other words, fix your testing strategy and the problem will go away.
In general, I agree with Marnen about "just pick one of them, probably Capybara", but one possible reason to use both of them is gradual migration.
Say, you have a large test suite and you're migrating it to Capybara, but you'd like to let some of your old tests to stay "Webrat-driven" for some time.
Although, I didn't find ideal solution for this case, here's what I did:
# features/support/env.rb
...
if ENV['WITH_WEBRAT'].nil?
require 'capybara/rails'
require 'capybara/cucumber'
...
else
require 'webrat'
...
end
...
# config/cucumber.yml
...
default: --profile capybara
capybara: <% std_opts %> --tags ~#webrat features
webrat: <% std_opts %> --tags #webrat features WITH_WEBRAT=1
...
# features/webrat.feature
#webrat
...
# features/capybara.feature
...
Now, you can do cucumber to run your capybara-only test suite or cucumber -p webrat for your legacy Webrat features.
Not ideal, but it worked for me.
I'm trying to set up Factory Girl with Test::Unit and Shoulda in Ruby on Rails. I have installed the gem, created my factory file under the test/factories directory, and created my spec file under the test/models directory. The current error I'm getting is 'ArgumentError: No such factory: test', which leads me to believe that the test_factory.rb file is not being loaded? Any idea as to what I should change?
Here are my files.
#test/factories/test_factory.rb
Factory.define :test do |t|
t.name 'test_spotlight'
t.label 'test spotlight label'
end
and
#test/modes/test_spec.rb
require 'test_helper'
require 'factory_girl'
class TestTest < Test::Unit::TestCase
def setup
#test = Factory.build(:test)
end
context "A test" do
should "save with the minimum requirements" do
assert #test.save
end
end
end
I've run into this problem on one of my projects too. I'm not sure precisely what's causing the initialization code to be skipped but you can force load the factory definitions like this:
require 'factory_girl'
Factory.find_definitions
Hope this helps.
Try putting this in test_helper.rb:
require 'factory_girl'
Dir.glob(File.dirname(__FILE__) + "/factories/*").each do |factory|
require factory
end
Just discovered factory_girl_rails, where it says the autoloading is the only extra thing it has https://github.com/thoughtbot/factory_girl_rails
I had the same problem. Eventually I made do by putting all my factories in "/test/factories.rb" and writing the following lines in my "/test/test_helper.rb" file:
require 'factory_girl'
require File.dirname(__FILE__) + "/factories"
you could do the same thing for multiple files by requiring them in the test_helper. I haven't yet figured out why the auto-include that's mentioned in "factory_girl's" readme doesn't happen.
I also managed to get rid of this issue by putting this line into my environment.rb:
config.gem "factory_girl", :source => "http://gemcutter.org"
Make also sure you have the latest gem:
Name changed from "thoughtbot-factory_girl" to "factory_girl", source changed from "http://gems.github.com" to "http://gemcutter.org".
In case you had this issue with ruby 1.9.2, require expects the expanded path.
File.expand_path("test/factories.rb")
This patch solved my problem. I just sent a pull request.
After that you can add this to your test_helper.rb:
require 'factory_girl'
FactoryGirl.find_definitions
If I only required 'factory_girl' in test_helper.rb, I would get the same behavior you mentioned, yet if I required it in my config/test/environment.rb (note I use environmentalist) it would properly find the Factory definition without any issue.
I tried this after reading the factory girl rdoc where it says to put config.gem in your environment.
I also ran into the problem - after updating FactoryGirl to 1.3.2 - that factories from test/factories were not loaded automatically any more.
I could get rid of the problem by adding the code from dg into test_helper.rb:
Dir.glob(File.dirname(__FILE__) + "/factories/*.rb").each do |factory|
require factory
end
When running single tests in Textmate, everything worked fine, but running e.g. all unit tests from the command line using rake test:units failed with a DuplicateDefinitionError (I read that it has probably something to do with ruby 1.8.x). So I slightly changed the code:
if (!Factory.factories || Factory.factories.empty?)
Dir.glob(File.dirname(__FILE__) + "/factories/*.rb").each do |factory|
require factory
end
end
Have you tried moving the
require 'factory_girl'
to your test/test_helper.rb ?
The factory auto-loading mechanism may depend on where the the require is called. It could be trying to find factories *test/models/factories/** instead of *test/factories/**
Instead of naming your factory file test_factory.rb, try naming it factory.rb
Interesting. I had a similar problem trying to get cucumber to work with factory_girl. I had originally configured factory_girl to be looked for ('config.gem') but not loaded in the cucumber environment and fully required in 'features/support/env.rb', same as cucumber does for webrat, etc. That only started to work when I explicitly told factory_girl to find its definitions as Kenny suggested above.
When I removed the require statement from env.rb and fully required factory_girl in the cucumber environment, the effect went away and factory_girl worked out of the box.
So it really seems to be a question of when (or in which context) factory_girl gets loaded.
Since different people are using different versions of Rails (2.x and 3.x being the most common now), it is important to include the other pertinent pieces of your environment (the most important being which version of Rails you're on). From the factory_girl web page, version 1.3.0 documentation (http://rubydoc.info/gems/factory_girl/1.3.0/frames):
If you want to use factory_girl with Rails 3, use the
factory_girl_rails gem, not this one.
If you want to use factory_girl with Rails versions prior to Rails 3,
use version 1.2.4.
If you're having trouble with the loading, I'd suggest making sure that you are using the right version. The versions of factory_girl greater than 1.2.4, I'd assume, are brought in as dependencies for the 'factory_girl_rails' (Rails 3.0+) gem.
I added
require 'factory_girl'
require File.dirname(FILE) + "/factories"
to spec_helper.rb whiche helped, but then I rememberd Spork can sometimes ba a bit of a problem, so I restarted Spork without the require and then it worked fine.