I had this working previous, now it mysteriously does not. ruby 2.4.1, rails 5.0.1.rc2, capybara 3.6, rspec_rails 3.5, factorygirl 4.7 (2017 project)
The page controller (root_path) needs SiteCounter.find(1) (seeded), which factorygirl is doing.
If I run all 3 examples at the same time (or any combination of 2 of them) only the first one works, because for the rest SiteCounter.find(1) does not exist
If I run each one individually, they all pass.
describe "Sign In", type: :system do
@site_counter = create_site_counter
before do
@fan = create :fan
visit root_path
end
scenario "valid with correct credentials" do
expect(page).to have_link "LOG IN"
find('#myNavbar > ul.nav.navbar-nav.navbar-right.signlogin > li:nth-child(2) > a').click
expect(page).to have_current_path new_fan_session_path
expect(page).to have_xpath('/html/body/div[1]/div/div/div/div/header/h3', text: 'Sign in')
expect(page).to have_button("Sign in")
expect(page).to have_button("Sign in").and have_xpath('/html/body/div[1]/div/div/div/div/header/h3', text: 'Sign in')
fill_in "Email", with: @fan.email
fill_in "Password", with: @fan.password
click_button "Sign in"
find('.dropdown-toggle').click
expect(page).to have_link "Logout"
expect(page).to have_current_path root_path
end
scenario "invalid with unregistered account" do
find('#myNavbar > ul.nav.navbar-nav.navbar-right.signlogin > li:nth-child(2) > a').click
fill_in "Email", with: Faker::Internet.email
fill_in "Password", with: "FakePassword123"
click_button "Sign in"
expect(page).to have_no_link "Logout"
end
scenario "invalid with invalid password" do
find('#myNavbar > ul.nav.navbar-nav.navbar-right.signlogin > li:nth-child(2) > a').click
fill_in "Email", with: @fan.email
fill_in "Password", with: "FakePassword123"
click_button "Sign in"
expect(page).to have_no_link "Logout"
end
end
UPDATE
As per Thomas Walpole suggestions (I appreciate all your posts btw), I have modified the code to be more soft baked, and also took away factorygirl's task of creating SiteCounter and added it into the page controller. I have also made the second two example expects more positive:
scenario "valid with correct credentials" do
#fist LOG IN link
within('#myNavbar') do
expect(page).to have_link "LOG IN"
end
#second LOG IN link
within('.follow-login') do
expect(page).to have_link "LOG IN"
end
within('#myNavbar') do
click_link('LOG IN')
end
fill_in "Email", with: @fan.email
fill_in "Password", with: @fan.password
click_button "Sign in"
find('.dropdown-toggle').click
expect(page).to have_link "Logout"
expect(page).to have_current_path root_path
end
scenario "invalid with unregistered account" do
within('#myNavbar') do
click_link('LOG IN')
end
fill_in "Email", with: Faker::Internet.email
fill_in "Password", with: "FakePassword123"
click_button "Sign in"
expect(page).to have_selector(:link_or_button, 'Sign in')
end
scenario "invalid with invalid password" do
find('#myNavbar > ul.nav.navbar-nav.navbar-right.signlogin > li:nth-child(2) > a').click
fill_in "Email", with: @fan.email
fill_in "Password", with: "FakePassword123"
click_button "Sign in"
expect(page).to have_selector(:link_or_button, 'Sign in')
end
end
if this code is up to par I will move on to the second system test of 50 i need to write by 5pm.
=================
UPDATE
scenario "valid with correct credentials" do
#fist LOG IN link
within('#myNavbar') do
expect(page).to have_link "LOG IN"
end
#second LOG IN link
within('.follow-login') do
expect(page).to have_link "LOG IN"
end
within('#myNavbar') do
click_link('LOG IN')
end
fill_in "Email", with: @fan.email
fill_in "Password", with: @fan.password
click_button "Sign in"
find('.dropdown-toggle').click
expect(page).to have_link "Logout"
expect(page).to have_current_path root_path
end
scenario "invalid with unregistered account" do
within('#myNavbar') do
click_link('LOG IN')
end
fill_in "Email", with: Faker::Internet.email
fill_in "Password", with: "FakePassword123"
click_button "Sign in"
expect(page).to have_css '.alert'
expect(page).to have_selector(:link_or_button, 'Sign in')
end
scenario "invalid with invalid password" do
within('#myNavbar') do
click_link('LOG IN')
end
fill_in "Email", with: @fan.email
fill_in "Password", with: "FakePassword123"
click_button "Sign in"
expect(page).to have_css '.alert'
expect(page).to have_selector(:link_or_button, 'Sign in')
end
end
this works and is as close as positive as I can get on this page, Mr. Walpole. expect(page).to have_content("Email or password fail.")
caused a weird error that was removed only by deleting <!DOCTYPE html>
from my layouts/application, as thoroughly outlined in the comments.
You can't just set an instance variable and expect it to be used by your application. Your application is run in it's own thread or process (depending on config) and won't see instance variables you set in your spec.
Beyond that your tests have a number of other issues
find('#myNavbar > ul.nav.navbar-nav.navbar-right.signlogin > li:nth-child(2) > a').click
rather than just doing click_link('LOG IN')
which also then obviates the need to do expect(page).to have_link "LOG IN"
since the click_link
would fail if the link didn't existclick_link
will return immediately after clicking and isn't guaranteed to wait for the actions triggered by that click to occur. That means the have_no_link
will immediately be validated against your login page (which wouldn't have a 'Logout' link on) and pass, never actually waiting for the login failure to occur. Instead you need to do a positive expectation against something that should be on the page to indicate the login attempt has failed.