Раньше у меня это работало, теперь загадочным образом нет. ruby 2.4.1, rails 5.0.1.rc2, capybara 3.6, rspec_rails 3.5, factorygirl 4.7 (проект 2017 г.)
Контроллеру страницы (root_path) требуется SiteCounter.find(1) (seed), что и делает factorygirl.
Если я запускаю все 3 примера одновременно (или любую комбинацию из 2 из них), работает только первый, потому что для остальных SiteCounter.find(1) не существует
Если я запускаю каждую по отдельности, они все проходят.
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
ОБНОВЛЯТЬ
Согласно предложениям Томаса Уолпола (кстати, я ценю все ваши сообщения), я изменил код, чтобы он был более мягким, а также убрал задачу factorygirl по созданию SiteCounter и добавил его в контроллер страницы. Я также сделал вторые два примера более позитивными:
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
если этот код соответствует номиналу, я перейду ко второму системному тесту из 50, который мне нужно написать к 17:00.
=================
ОБНОВЛЯТЬ
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
это работает и является настолько положительным, насколько я могу получить на этой странице, мистер Уолпол. expect(page).to have_content("Email or password fail.")
вызвал странную ошибку, которая была устранена только путем удаления <!DOCTYPE html>
из моих макетов/приложения, как подробно описано в комментариях.
Тай. В моем стремлении оставаться позитивным я добавил expect(page).to have_content("Email or password fail.")
, который представляет собой предупреждение о начальной загрузке, которое приходит и уходит неловко, но теперь я получаю Capybara::Ambiguous: Ambiguous match, found 2 elements matching visible xpath "/html"
У меня нет других положительных вариантов, только одно предупреждение. Поэтому я удалил expect(page).to have_content("Email or password fail.")
и добавил expect(page).to have_current_path new_fan_session_path
из-за нехватки времени, ожидая дальнейших отзывов. Я читаю, что это может быть любая небольшая случайная неуместная синтаксическая ошибка, вызывающая сбой капибары с этой ошибкой, на поиск которой могут уйти месяцы, месяцы и месяцы.
если я удалю <!DOCTYPE html>
из верхних макетов / приложений, тест пройдет нормально, но кто знает, что это делает. Я пытаюсь проследить код через все рендеры, чтобы найти неисправный html или что-то еще, не видя, где devise отображает новую страницу сеансов. должен быть какой-то драгоценный камень для сканирования кода на наличие подобных ошибок, нет? Я проверю
... согласно случайному сообщению, водосвинка не игнорирует <!DOCTYPE html>
, во что мне трудно поверить.
Я проследил и проверил путь от макетов/приложения, включая 16 случайных рендеров, нашел два мошеннических тега <html>, но это не помогло. Я искал в глобальном масштабе <!DOCTYPE html>, <html> и </html> и искал странности во всех файлах. ничего не нашел
Вы не можете просто установить переменную экземпляра и ожидать, что она будет использоваться вашим приложением. Ваше приложение запускается в своем собственном потоке или процессе (в зависимости от конфигурации) и не будет видеть переменные экземпляра, которые вы установили в своей спецификации.
Помимо этого, ваши тесты имеют ряд других проблем
find('#myNavbar > ul.nav.navbar-nav.navbar-right.signlogin > li:nth-child(2) > a').click
, а не просто делать click_link('LOG IN')
, что также устраняет необходимость делать expect(page).to have_link "LOG IN"
, поскольку click_link
потерпит неудачу, если ссылка не существуетclick_link
вернется сразу после нажатия и не гарантирует, что произойдет действие, вызванное этим щелчком. Это означает, что have_no_link
будет немедленно проверен на вашей странице входа (на которой не будет ссылки «Выход») и пройдет, фактически не дожидаясь сбоя входа. Вместо этого вам нужно сделать положительное ожидание против чего-то, что должно быть на странице, чтобы указать, что попытка входа не удалась.Очень признателен, спасибо. ... Вы говорите, что каждый пример (сценарий) запускает свой собственный процесс? Я бы подумал, что описание было процессом (не знаю, что такое процесс). Как бы то ни было, я учел отсутствие начального объекта в контроллере страницы rspec, который прошел тесты, хотя и медленнее, чем когда это делала factorygirl. У меня все они изначально работали с приведенным выше кодом, не могу понять, что произошло. click_link('LOG IN') дает мне Capybara::Ambiguous: .... Неоднозначное совпадение, найдено 2 элемента, соответствующих видимой ссылке "LOG IN". Хрупкий = любое незначительное изменение в дизайне rspec терпит неудачу, w3rd
Упс, 2 одинаковые ссылки на странице, попытаюсь сначала? и другие подобные тактики для начинающих немного
обновил вопрос, ти
К сожалению, ваши тестовые обновления на самом деле не решают проблему — вы уже находитесь на странице с кнопкой «Войти» — то есть в асинхронном мире, который может соответствовать странице, на которой вы сейчас находитесь. Вам действительно нужно проверить что-то положительное, что указывает на неудачный вход в систему (и не на текущей странице). Вы показываете флэш-сообщение при сбое? Изменится ли текущий путь? и т. д.