I'm having trouble getting Cucumber / Capybara to find a 'success' flash message on a page after a user is logged in. I'm able to see the message if I do it manually in the browser, so I'm thinking I'm doing something wrong in my steps.
user_login.feature
Feature: User login
Scenario: A user successfully logs in from the homepage
Given A user is on the homepage
When the user clicks "Login"
And they fill out the form
Then they should see a success message
step_definition
Given /^A user is on the homepage$/ do
#user = Factory.create(:user)
visit root_path
end
When /^the user clicks "(.*?)"$/ do |arg1|
click_link arg1
end
When /^they fill out the form$/ do
fill_in "email", with: #user.email
fill_in "password", with: "blahblah1"
click_button "Sign in"
end
Then /^they should see a success message$/ do
page.should have_selector ".alert", text: "Logged in!"
end
output
expected css ".alert" with text "Logged in!" to return something (RSpec::Expectations::ExpectationNotMetError)
Basically, I made a DERP. The credentials I was using (password) to fill in the form weren't the same as the user I was creating via FactoryGirl. This was causing an 'invalid email / password' message to appear when I was testing for a 'success' message.
To debug what the page was outputting, I added a page.should have_content "asdfsdfas" in my spec. When the test fails, Cucumber outputs the content it got on the page compared to what you expected it to receive.
Related
My spec:
let(:user) { FactoryGirl.create(:user) }
context 'When user is logged in' do
scenario 'Log in' do
visit login_path
within '.new_user_session' do
fill_in 'username', with: user.email
fill_in 'password', with: user.password
click_on 'Log in'
end
visit new_search_path
expect(page).to have_text "Welcome #{user.name}!"
end
end
The issue is that when visiting new_search_path, even though the login in successful, the page behaves as if there is no user logged in. If I add a sleep(1) call right before visit new_search_path, everything works fine.
Anyone know why this is happening?
I'm using authlogic, capybara, and selenium.
The action triggered.by click_on can occur asynchronously. Therefore, if you do a visit immediately after it can cause the login request to abort and the session cookies never get set. To solve that you need to check for page text/content that indicates the login has succeeded. Something like
expect(page).to have_text 'You are now logged in'
I'm trying to test the devise feature for reseting a password, but I'm having some issues trying to test the link in the mail and visiting the page that is linked to.
I've tried unsuccessfully 2 ways to do it:
1)
scenario "User resets his password" do
user2 = FactoryGirl.create(
:user, reset_password_token: "new_password",
)
visit new_user_password_path
fill_in "Email", with: user2.email
click_on "Send me reset password instructions"
open_email(user2.email)
click_first_link_in_email
expect(page).to have_content("Reset your password")
end
If I do this I get the error:
Failure/Error: click_first_link_in_email
ActionController::RoutingError:
No route matches [GET] "/1999/xhtml'"
2)
scenario "User resets his password" do
user2 = FactoryGirl.create( :user, reset_password_token: "new_password" )
visit edit_user_password_path(reset_password_token:
expect(page).to have_content("Reset your password")
end
If I do this it takes me to the initial page saying:
"You can't access this page without coming from a password reset email"
Solved!
there were more links inside the mail.
The way that I selected the one that I wanted was by using links_in_email(email).
I used pry to check the links inside the array (links_in_email(email) and then select the one that I was interested in.
scenario "User resets his password" do
visit new_user_password_path
fill_in "Email", with: #user.email
click_on "Send me reset password instructions"
mail = ActionMailer::Base.deliveries.last
link = links_in_email(mail)[1]
visit link
expect(page).to have_content("Reset your password")
end
I am testing my rails app with rspec, capybara. Tests are working fine for login.
After login am trying to visit some link, and I could go to the link also but after that it is coming back again to the login page. I am not sure whats wrong with my code. Please help me to figure out the issue.
My test spec file.
require 'spec_helper'
describe "User Login",:js => true do
let(:user) { FactoryGirl.create(:user)}
before(:each) do
visit login_path
fill_in "email", with: user.email
fill_in "password", with: user.password
click_button "Sign in"
end
describe "after login" do
it "should show the left navigation on the dashboard" do
visit "/todos"
visit employees_dashboard_path
page.should have_link('Todo', href: todos_path)
click_link "Todo"
end
end
end
describe "Display the todos list" do
let(:todo) { FactoryGirl.create(:todo)}
it "should disply no todos if the todos are nil" do
expect(Todo.count).to eq(0)
visit "/todos" # I could come till here.
expect(page).to have_content("Todos")
end
end
After vising "/todos" I should see "Todos" as the content on the page but instead am seeling the login page again.
My test trace error:
Display the todos list should disply no todos if the todos are nil
Failure/Error: expect(page).to have_content("Todos")
expected to find text "Todos" in "Please login to access the page Log In
Sign in Forgot Password Close Forgot Password Close"
So am coming back again to the login page. Please tell me why this unexpected behaviour is happening in my code.
Thank you.
In the "Display the todos list" block you are not logging in: you need to either have a similar before(:each) as in the "User login" block or move the entire "display todos" block inside the "User login" block.
I am trying to learn TDD, and can't get this integration test with Capybara and Rspec to work. The user visits the home page, clicks "Login", fills out the form with an "Email" and "Password", clicks "Log in", and then I expect the page to have the content "Signed in Successfully".
home_page_spec.rb
require 'spec_helper'
feature 'Login' do
scenario 'user logs in to the site' do
visit root_path
click_link 'Login'
expect(page).to have_content "Sign in to your account."
fill_in('Email', with: "test1#joijjoi.eud")
fill_in 'Password', with: "password"
click_button 'Log in'
expect(page).to have_content('Signed in Successfully')
end
end
I am getting "Failure/Error: expect(page).to have_content('Signed in Successfully'). Expected to find text "Signed in Successfully" in . . . . " The text that it finds is the sign in page. It is as if the test is finding the Log in button, but either not clicking it, or the button is not forwarding the page, but it works if I do this by hand in the browser. Any suggestions? Thanks.
you can use the gem capybara-screenshot that save the page html and screen shot when a test fails. That way you can debug the issues. Or you can temporarily switch to selenium webdriver for capybara which opens the default browser and executes your tests.
This feature worked a bit, then stopped working.
Background:
Given a user is logged in
Then I should see "Signed in successfully."
With
Given /^a user is logged in$/ do
#user = FactoryGirl.create(:user)
#user.confirm!
visit new_user_session_path
fill_in 'Email', :with => #user.email
fill_in 'Password', :with => #user.password
click_on 'Sign in'
end
Then /^I should see "(.*?)"$/ do |message|
page.should have_content(message)
end
Given a user is logged in passes but Then I should see "Signed in successfully." fails with the error expected there to be content "Signed in successfully.". It stays in the sign in page.
Anyone has an idea what might be the problem?
Solved!
I changed
click_on 'Sign in'
to
click_button 'Sign in'
It's weird that Capybara did not complain about not finding a Sign in to click on.
Thanks everyone for your comments and answers!
Try adding launchy to your test gemspec group and calling save_and_open_page after clicking on 'Sign in' - this should help you see whether anything is wrong with your login process.