Cannot visit to the path i specified in rspec visit - ruby-on-rails

I have used rspec visit to go to a path but it takes me to the index. I have checked callbacks but still cannot find a clue. Any help would be appreciated.
describe "addon purchased" do
it "should send email when addons are purchased" do
skip_alpine
sign_in(#attendee)
visit manage_tickets_v2_kwivrr_event_path(#event)
close_cookies_notification
skip_login_interrupts(#attendee)
expect(page).to have_content(#event.name)
visit not taking me to this specified path
here is my controller action
def manage_tickets
authorize #event
#addon_success_msg = params[:addon_msg] if params[:addon_msg].present?
end

Related

Capybara::ElementNotFound: Unable to find visible link

I'm having trouble with my test for a method which lets an admin user promote other users to admin by the click of "Promote to Admin". It lies in my controller, I'm writing a feature test for it. I'm using Rails 5.1.4.
def promote
#user = User.find(params[:user_id])
if #user.toggle!(:admin)
flash[:success] = "User is promoted to admin."
redirect_to root_path
else
flash[:notice] = "Can't promote."
redirect_to root_path
end
end
This is the test:
describe "Promotion" do
before do
login_as(User.create!(name: "lala", email: Faker::Internet.email,
password: "lalala", admin: true))
visit users_path
end
context "to admin" do
it "promotes user to admin" do
click_link("Promote to Admin", :match => :first)
expect(current_path).to eq user_promote_path
end
end
end
It gives me the error: Capybara::ElementNotFound:
Unable to find visible link "Promote to Admin"
which I think is because I'm not accessing the right page, trying to log in as admin is perhaps not working.
Any suggestion would be very appreciated!
The most likely reason for your test failing is that you don't appear to have created any other users beyond the one you're logging in as. If you haven't then there wouldn't be any users to show "Promote to Admin" links for. You can always save the page or just do puts page.html to make sure what you think is on the page actually is.
A second issue with your test is that you should never use the eq matcher with current_path. You should be using the Capybara provided path matcher of you want stable tests
expect(page).to have_current_path(user_promote_path)
If you want to be sure that you're on the right page, you can do some debugging with:
save_and_open_page (opens your browser)
save_and_open_screenshot (takes a screenshot and opens it)
If it's all good, maybe Capybara can't find the link : Is it a screen size/responsive issue ? If yes, you can configure the window size that Capybara uses (see this link)
If the test still does not pass, maybe the link is not visible by default ?
You can add to option visible: false in click_link to precise that.

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

What is the difference between visit and current_path and use of .should in rails?

Then /^I should be on the free signup page$/ do
*current_path.should == free_signup_path*
end
Then /^I should be on the free signup page$/ do
*visit free_signup_path*
end
What is the difference between these two ?
#visit tells the browser to go to a new url and will initiate a get request to the app being tested. #current_path lets you read the current location the browser is at.
Note: you should stop using current_path.should == some_path, when verifying the current path, and instead use page.should have_current_path(some_path). The have_current_path matcher includes waiting behavior and will help make tests less flaky with JS capable drivers
You use visit to tell rspec to go to that path to validate if something works or is present. For example:
it 'contains the new sessions form' do
visit 'sessions/new'
current_path.should have_content("Sign In")
end
Granted that my sign in form has a button or whatever with the text 'sign in' this test will pass.
You generally have to declare what path the test hould go to in order to detect content.
Hope this helps!

How to test devise after sign in path with Capybara

I am trying to test what happens after logging in through Devise gem. For example, I have the controller to go to student_dashboard_path after users successfully login.
How can I test this with Capybara and Rspec?
I currently have this in:
/spec/features/user_signs_in_sees_dashboard_spec.rb
require 'rails_helper'
feature 'User sign in' do
scenario 'successfully from sign in page and sees student dashboard' do
sign_in
visit student_dashboard_path
expect(current_path).to eq(student_dashboard_path)
end
end
and I have this in:
/spec/support/features/sign_in.rb
module Features
def sign_in
visit user_session_path
fill_in 'Email', with: User.first.email
fill_in 'Password', with: User.first.password
click_button 'Log in'
end
end
and I am getting this error message:
1) User signs in successfully from sign in and sees dashboard
Failure/Error: expect(current_path).to eq(student_dashboard_path)
expected: "/student/dashboard"
got: "/student/login"
I am not sure why I am not able to log in and see the student dashboard.
I'm leaving my original answer below for anyone still on Capybara < 2.5.0 but in 2.5.0 you can now do
expect(page).to have_current_path(<expected path>)
and it will use Capybara's waiting behavior while checking for the path
---- Below is only for Capybara version < 2.5.0
expect(current_path).to eq(...) doesn't wait for the path to change, it just compares to the current path at the time it's called. If you put a sleep after the click button I bet it works. A better solution would be to have something like
expect(page).to have_text('You are now logged in')
after the click_button. That would cause capybara to wait until the log in has completed, the page loads (and the logged in notice appears), and therefore until the current_path has changed too.
Use capybara save_and_open_page in middle to figure out if the fields are properly set. If you work on the same machine you can switch to selenium to test out on the real browser.
Also be sure that this code does not need any JS to work because default capybara matchers will not be able to run it.

Rails - minitest - Testing pages that require login

I am working on tests but running in to a road block on pages that require a current_user. I am using minitest, capybara, factorygirl, and authlogic, in rails 3.2.9 with ruby 1.9.3p327. I installed minitest as a separate gem, and seem to have the test environment working correctly.
I have a factory that creates a valid user...I call that factory from in a test like this:
describe "UsersAcceptanceTest" do
it "must load and include content" do
FactoryGirl.create(:user)
visit users_path
page.must_have_content("cPanel")
end
end
The FAIL is correct in informing me that the content "cPanel" was not found (cPanel is a link available to logged in users). The fail error goes on to alert me that it was not found in "log in, forgot password, contact" ... which of course means that the test routed correctly to users_path, but was redirected by authlogic because the user is not logged in. Users cant create themselves in my system and therefor are not auto-logged in on create.
How to I also get the factory to create a new user session with the newly created user?
You can do it this way:
visit signin_path
fill_in 'email', with: user.email
fill_in 'password', with: user.password
click_button "Log in"
Just edit it according to your login page structure.
I don't know about minitest, but in rspec I'd create the separate method with this codedef sign_in...end and put it to support\utilities.rb.
Then your code would be looking like that:
describe "UsersAcceptanceTest" do
let(:user) { Factory(:user) }
subject { page }
it "must load and include content" do
sign_in user
visit users_path
it { should have_link("cPanel", href: cpanel_path) }
end
end
As you can see I've edited your code a little bit more.

Resources