I am trying to get tests working after switching from Webrat to Capybara. When I try to sign in to the application I am getting a "Invalid username/password" error, despite just having created the user in a Factory using factory_girl. The way I understand it, the user should persist for the entirety of the fixture, right?
factories.rb:
Factory.define :user do |user|
user.firstname "Test"
user.lastname "Test"
user.email "test#test.com"
user.password "testtest"
user.password_confirmation "testtest"
end
layout_links.spec.rb:
describe "LayoutLinks" do
before(:each) do
wrong_user = Factory(:user)
integration_sign_in(wrong_user)
end
it "should have a dashboard page" do
get '/dashboard'
page.should have_css('h1', :text => "Navigation#dashboard")
end
spec_helper.rb
def integration_sign_in(user)
visit signin_path
fill_in :email, :with => user.email
fill_in :password, :with => user.password
click_button "Sign in"
puts page.body
end
Also in spec_helper.rb is the following:
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
Shouldn't the user persist and then be successful in the integration_sign_in function? I can still sign in correctly through the browser in the development environment, which has a user and the sign in was working correctly with webrat before the migration, so I am not sure what to think. Thanks!
UPDATE: It looks like the session isn't going to the server correctly. On the server, when I check the value of email and password in the session, the values are incorrect:
puts "Post Email: " + params[:session][:email]
puts "Post Password: " + params[:session][:password]
the email variable has the password variable, and the password variable has no value. Why would this be? The client integration test maps the fields correctly:
fill_in :email, :with => user.email
fill_in :password, :with => user.password
How can I test this further? Thanks.
So this worked for me
fill_in "Email", :with => user.email
fill_in "Password", :with => user.password
whereas using the symbols failed
It looks like the session wasn't going to the server correctly. I am not sure how to account for this.
Related
I´m learning Ruby on Rails and i´m working on an application that use stripe to create premium accounts. Also, i´m using Rspec and Capybara to do the integration tests.
require 'spec_helper'
feature "user upgrade account to a premium plan" do
scenario "user upgrade account", :js => true do
user = FactoryGirl.create :user
visit new_user_session_path
fill_in 'Email', :with => user.email
fill_in 'Password', :with => user.password
click_button 'Sign in'
visit new_charge_path
click_button "Pay with Card"
fill_in 'Email', :with => 'persona#example.com'
fill_in "Card number", :with => "4242424242424242"
fill_in 'CVC', :with => '123'
fill_in 'MM/YY', :with => '11/14'
click_button 'Pay $5.00'
end
I run the test and i get an error message that says:
Failure/Error: fill_in "Card number", :with => "4242424242424242"
Capybara::ElementNotFound:
Unable to find field "Card number"
Anyone knows, what can be the problem?
Thanks.
Depending on how you're integrating Stripe, it might be rendering the form inside an iframe. If that's the case, you'll need to use Capybara.within_frame to target the actions to the correct frame:
scenario "user upgrade account", :js => true do
user = FactoryGirl.create :user
visit new_user_session_path
fill_in 'Email', :with => user.email
fill_in 'Password', :with => user.password
click_button 'Sign in'
visit new_charge_path
click_button "Pay with Card"
Capybara.within_frame 'stripe_checkout_app' do
fill_in 'Email', :with => 'persona#example.com'
fill_in "Card number", :with => "4242424242424242"
fill_in 'CVC', :with => '123'
fill_in 'MM/YY', :with => '11/14'
click_button 'Pay $5.00'
end
end
Try to use element id instead of field label.
fill_in 'card_number', :with => '4242424242424242'
fill_in 'cvc', :with => '123'
(Being card_number and cvc the ids of input fields.)
= f.text_field :card_number, :class => 'span12', :id => :card_number
= f.text_field :cvc, :class => 'span12', :id => :cvc
I had the same problem and I used this solution, not sure if it's good practice, but works for me.
for capybara with stripe testing:
Capybara.within_frame 'stripe_checkout_app' do
fill_in "Card number", :with => "4242424242424242"
fill_in 'CVC', :with => '123'
fill_in 'Expiry', :with => '11/22'
click_button 'Pay $5.00'
end
edit the exipry date to a month and year of future always.
describe "create post", :js => true do
before :each do
a = User.create!(:email => 'any#gmail.com', :password => 'admin123', :password_confirmation => 'admin123', :firstname => "black")
a.confirm!
end
it "signs me in" do
get root_path
visit '/'
within(".form-inline") do
fill_in 'Email', :with => 'any#gmail.com'
fill_in 'Password', :with => 'admin123'
end
click_button 'Sign in'
save_and_open_page
end
end
when i execute with rake spec:requests
i'm unable to login, i'm getting invalid email or password error in browser.
please tell me what to do?
I cannot simulate my form_tag in Rspec. The form_tag will package the parameter hash as a simple hash while the Rspec will package as a hash of hashes with the parameters, in this case, inside of :session hash like:
{"session"=>{"email"=>"billy#example.com", "password"=>"foobar"}, "controller"=>"sessions", "action"=>"create"}
vs Rails form_tag:
{"utf8"=>"✓", "authenticity_token"=>"AiurjCANkzCJFl+oiJK2tQVzzxrET260bo1wxuDHB74=", "email"=>"billy#example.com", "password"=>"foobar", "commit"=>"Sign in", "action"=>"create", "controller"=>"sessions"}
The Sessions controller is using:
user = User.find_by_email(params[:email])
to extract the email parameter. This will work for the development but for the Rspec test I would have to use:
user = User.find_by_email(params[:session][:email])
Here is my latest Rspec test:
describe "success" do
before(:each) do
#user = Factory(:user)
#attr = {:email => #user.email, :password => #user.password }
end
it "should redirect to the user show page" do
#post :create, :session => #attr #same results
post sessions_path(:email => #user.email, :password => #user.password)
response.should have_selector('h1', :content => #user.full_name)
end
end
This will fail because of the difference in the parameter hashes above. Is there a way in Rspec to send parameters to the session controller in a single hash to match the form_tag as shown above?
You can try to pass the parameters manually in your tests
describe "success" do
before(:each) do
#user = Factory(:user)
#attr = {:email => #user.email, :password => #user.password }
end
it "should redirect to the user show page" do
post :create, :email => #user.email, :password => #user.password
response.should have_selector('h1', :content => #user.full_name)
end
end
This will send the parameters to your method in the controller as
{... "email"=>"billy#example.com", "password"=>"foobar" ...}
I'm doing the ruby on rails tutorial, I specifically adding listing 8.21 to spec/requests/users_spec.rb
require 'spec_helper'
describe "Users" do
describe "signup" do
describe "signup failure" do
lambda do
it "should not make a new user" do
visit signup_path
fill_in "Name", :with => ""
fill_in "Email", :with => ""
fill_in "Password", :with => ""
fill_in "Password confirmation", :with => ""
click_button
response.should render_template('users/new')
response.should have_selector("div#error_explanation")
end
end.should_not change(User, :count)
end
end
end
as far as I can tell, this is exactly like the listing in 8.21; however, when I run
rspec spec/requests/users_spec.rb -e "Users"
I got the following error ...
#> rspec spec/requests/users_spec.rb -e "Users" No DRb server is running. Running in local process instead ... /Users/bryanjamieson/rails_projects/sample_app/spec/requests/users_spec.rb:17:in `block (3 levels) in ': undefined method `change' for
# (NoMethodError)
any help would be appreciated.
I'd use User.count
end.should_not change(User.count)
Depending on which rails version and rspec version you're using (assuming Rails 3.1, Rspec2) the tutorial may be a little of out date
I am using capybara for an integration test and it looks like something is wrong with the session that gets passed to my controller for my "sign in" part of a test. The sign in works fine when going through a browser, but is failing in capybara.
def integration_sign_in(user)
visit signin_path
puts "Pre email: " + user.email
puts "Pre password: " + user.password
# When I use these, everything works correctly
fill_in "session_email", :with => user.email
fill_in "session_password", :with => user.password
# When I use these, the session is wrong
# The params[:session][:email] on the server has the password field
# The params[:session][:password] on the server is nil
#fill_in :email, :with => user.email
#fill_in :password, :with => user.password
click_button "Sign in"
end
Can I not use symbols for the capybara tests? My guess is that the first field (email) is being filled in for both fields in the failing case, which is why the session only has a value for email and that value is password.
It looks like the latest version of capybara doesn't accept symbols correctly. It only works when the full string of the field is entered.