Authlogic session in Capybara doesn't exist immediately - ruby-on-rails

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'

Related

Capybara does not waiting for ajax to finish

I am trying to test a signup flow using rspec and cpaybara within a feature spec. The signup happens via ajax and capybara doesn't wait for the request to complete. I am using the capybara matchers as specified in the documentation. If I add a sleep statement the test succeeds
let(:user) { create(:user, email: 'test#example.com', password: 'password') }
scenario 'visitor can sign up with valid email address and password', js: true do
sign_up_with('Name', 'test#example.com', 'password')
expect(page).to have_content(I18n.t( 'devise.registrations.signed_up'))
end
Helper Method to handle signup:
def sign_up_with(name, email, password)
visit root_path
find(:xpath,"//a[text()='Join']").click
within("#sign_up_choices") do
click_on "Sign up with Email"
end
within("#sign_up") do
fill_in 'user[name]', with: name
fill_in 'user[email]', with: email
fill_in 'user[password]', with: password
click_button 'Sign up'
end
end
When the user clicks on signup the form gets submitted via ajax.
Error I am getting occasionally:
Selenium::WebDriver::Error::StaleElementReferenceError:
stale element reference: element is not attached to the page document
(Session info: chrome=55.0.2883.95)
(Driver info: chromedriver=2.25.426935 (820a95b0b81d33e42712f9198c215f703412e1a1),platform=Mac OS X 10.11.4 x86_64)
Any help would be much appreciated!

Capybara loses cookies between requests

I have the follow test:
def login_user(email, password)
visit new_user_session_path
fill_in 'E-mail', with: email
fill_in 'Password', with: password
click_button 'go'
end
scenario 'some test' do
order = Fabricate(:order_one, company: user.company)
visit "http://127.0.0.1:49645/orders/#{order.id}" # change to visit "/orders/#{order.id}"
login_user(user.email, user.password)
#assert
end
Whats happen is that in first step (visit...) the user is not logged, so I set some informations using cookie. But, when login_user is executed, this cookie is empty.
Usigin selenium-webdriver
Any idea here ?
Thanks in advance
When using a JS capable driver #visit is not guaranteed to have finished loading the page when it returns. Since the cookie is not set in the browser until the response is processed, your login_user is actually telling the browser to stop processing it's current visit and visit somewhere else which stops the cookie from ever being set in the browser. After the first visit you need to wait for something visible on the page to be sure the cookies are correctly set.
scenario 'some test' do
order = Fabricate(:order_one, company: user.company)
visit "http://127.0.0.1:49645/orders/#{order.id}"
expect(page).to have_content('you are not logged in') #or whatever shows on the page visited
login_user(user.email, user.password)
#assert
end

Rspec/Capybara: Login page is being rendered again

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.

RSpec / Capybara - Failing to log in

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.

Sign in using Cucumber and Devise fails with no message

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.

Resources