2014-01-23 1 views
8

У меня возникла проблема со спецификацией, которая посещает две формы с тем же полем («Электронная почта») в обеих формах , Если я не буду спать вручную, Capybara, похоже, находит поле «Email» от первого посещения во второй части теста.Правильный способ подождать, пока вторая страница загрузится с Capybara, когда первое имеет то же поле, что и второе

# visit the first form and fill out a subscription 
visit new_front_form_subscription_path(@web_form_1.id) 
fill_in "Email", with: "[email protected]" 
fill_in "Field 1", with: "my first data" 
click_button "Subscribe" 

# visit the second form and fill out a subscription 
visit new_front_form_subscription_path(@web_form_2.id) 
sleep 1 
fill_in "Email", with: "[email protected]" 
fill_in "Field 2", with: "my second data" 
click_button "Subscribe" 

С сон там спецификация проходит с летающими цветами. Без сна вторая подача формы получает ошибку проверки - обвинение в пустом значении «Электронная почта».

Есть ли правильный способ справиться с этим? Я ненавижу вводить ручные сны в наши спецификации. Я бы скорее хотел сказать Капибаре, чтобы игнорировать ее концепцию того, что уже есть на странице, или что-то в этом роде.

спасибо.

ответ

5

Вот несколько способов, с помощью которых вы можете решить:

  1. Используйте другой локатор, который присутствует только на второй странице, чтобы выбрать поле «Email»:

    find('#second_page #email').set('[email protected]') 
    
  2. Напишите заявление, которое будет ожидать загрузку второй страницы вместо сна:

    visit new_front_form_subscription_path(@web_form_2.id) 
    expect(page).to have_css('locator_present_only_at_second_page') 
    fill_in "Email", with: "[email protected]" 
    
+0

Это немного kludgey, но, вероятно, лучший способ это сделать. Спасибо за ответ! – Alex

+0

Возможно, я ошибаюсь, но разве не возможно, что строка 'expect' терпит неудачу, если вторая страница еще не загружена? – aceofbassgreg

+2

@aceofbassgreg Почти все методы capybara ждут автоматически (включая rspec matchers) - https://github.com/jnicklas/capybara#asynchronous-javascript-ajax-and-friends –

1

Если вы обратились к Андрею 2) выше, вы можете проверить holdon gem, что позволит вам написать блок, который будет ждать загрузки элемента, а затем перейти к методу fill_in после загрузки этого элемента.

+2

Эквивалент для 'e = HoldOn.until (тайм-аут: 60, интервал: 5) { s.first (: css, "div # bastard")} 'is' e = find ('div # bastard', wait: 60, match:: first) '. Холдон-камень совершенно не нужен. Но я предпочитаю не пропускать ': match' param:' find ('div # bastard', wait: 60) ' –

0

Как правило, это можно сделать таким образом. Например, чтобы щелкнуть по кнопкам, найденным после загрузки модального всплывающего окна (или другой страницы), добавьте следующий блок в свой файл макросов.

def wait_until_modal 
    page.has_css?('.modal') 
end 

Здесь класс .modal находится на всплывающей странице.

3

Вышеуказанные ответы верны, но их трудно реализовать, если у вас большой набор тестов, потому что вам нужно найти уникальный элемент на каждой странице. Если вы закончите школу рельсов Майкла Хартла, есть простой способ решить эту проблему. Hartl учит настройке другой переменной экземпляра @title для каждого действия контроллера. Затем он используется в application.html.erb для установки элемента заголовка html для каждой страницы.

Я, конечно, делаю это, и это позволило очень легко исправить все мои неудачные тесты, которые не удались, потому что страница не загрузилась должным образом. Вы не можете найти тег title, потому что он не отображается. Так что я сделал, был помещен в нижней части application.html.erb, следующий код;

<%= content_tag :div, "[#{title}]", class: 'rspec_eyes_only' if Rails.env.test? %> 

Это вставляет, если вы находитесь в тестовом режиме, div с текстом заголовка, окруженным квадратными скобками. Тогда я написал помощник, который идет в rails_helper.rb

def wait_for_page_load(title) 
    find('div.rspec_eyes_only', text: title) 
end 

Я уже есть еще один помощник, чтобы проверить для правильного названия, поэтому я изменил его, чтобы добавить в wait_for_page_load I.е;

def title_is_correct(title) 
    full_title = "#{BaseTitle} | #{title}" 
    wait_for_page_load "[#{full_title}]" 
    expect(page.title).to eq full_title 
end 

Эти простые изменения прояснили почти все мои непроницаемые тесты.

Смежные вопросы