Capybara should have_content недостаточно долго ждет

#ruby-on-rails #ruby #capybara #bdd

#ruby-on-rails #ruby #capybara #bdd

Вопрос:

Итак, я пишу приемочный тест с использованием capybara. Сценарий состоял в том, чтобы подключить нашу систему рассылки новостей к внешней почтовой службе.

Мы будем перенаправлены на страницу нашей внешней службы, чтобы запросить доступ к внешней почтовой службе. И мы будем перенаправлены обратно на нашу системную страницу, когда добьемся успеха.

 When "I grant authorization" do
  fill_in "username", :with => "myapp"
  fill_in "password", :with => "secret"
  click_button "Allow Access"
end

Then "I should see 'Connection Established'" do
  page.should have_content "Connection Established"
end

And "I should see that I'm connected to Sample External Service" do
  page.should have_content "Connection Established: Sample External Service"
  page.should have_content "Deactivate Sample External Service syncing"
end
 

Но если я не использую sleep перед page.should have_content "Connection Established" . Спецификация завершится неудачей. Из того, что я знаю, использование sleep — не самая лучшая практика, потому что это замедлит выполнение нашего теста.

Как заставить его ждать, пока он не будет перенаправлен обратно в нашу систему

Ответ №1:

Существует 3 способа настроить максимальное количество времени, в течение которого методы Capybaras будут ждать, пока их ожидания оправдаются / элементы будут существовать

Capybara.default_max_wait_time = <seconds> — Это глобальная настройка, которая должна быть установлена достаточно высоко для подавляющего большинства вызовов вашего метода

Capybara.using_wait_time(<seconds>) do ... end — Это временно изменяется default_max_wait_time внутри блока, а затем возвращает его к первоначальным настройкам, когда все будет сделано. Это имеет смысл, когда у вас есть несколько методов, которые вы хотите вызвать с новым временем ожидания, или вам нужно вызвать вспомогательный метод с другим значением времени ожидания.

:wait опция — Все методы поиска и ожидания Capybara принимают :wait опцию, которая изменит максимальное время ожидания для вызова этого метода. Это имеет смысл использовать, когда у вас есть конкретный случай, требующий немного большего ожидания, чем обычно

 # This will wait up to 10 seconds for the content to exist in the page
page.should have_content "Connection Established: Sample External Service", wait: 10 
 

Примечание: В будущем при публикации вопросов, как правило, полезно, если вы предоставляете полное точное сообщение об ошибке, которое вы получаете как часть вашего вопроса.

Ответ №2:

Для переходов страниц мне нравится сначала дождаться изменения URL-адреса, а затем дождаться содержимого на странице. Это дает вам более конкретную ошибку, если перенаправление завершается неудачно, и, естественно, разбивает долгое ожидание на две части. При наличии двух возможностей default_max_wait_time время ожидания потенциально удваивается без фактического его изменения. Если этого все еще недостаточно, вы всегда можете передать пользовательский тайм-аут have_current_path с wait: параметром.

 expect(page).to have_current_path("externalservice.com")
expect(page).to have_content("Connection Established")
 

Возможно, существует page.should эквивалент, но я думаю, что официальное руководство состоит в том, чтобы перейти к expect синтаксису, поскольку should синтаксис устарел.

Комментарии:

1. Как и большинство других методов Capybara have_current_path , можно использовать :wait опцию, чтобы переопределить максимальное ожидание для этого сопоставления, поэтому нет необходимости увеличивать default_max_wait_time только для одного длительного перенаправления.

2. Привет, спасибо всем, я сначала попробую это и сообщу вам результат

3. Я пробовал, но это сработает только тогда, когда я добавлю wait опцию в сопоставителе have_current_path

Ответ №3:

Вы можете использовать capybara_watcher gem, это элегантный способ ожидания pege изменения содержимого. Проверьте это на RubyGems.org

Пример:

 wait_until_content_has "Connection Established" do |text|
  page.should have_content text
end
 

Преимущества использования этого заключается в том, что время ожидания — это фактическое время, необходимое странице для внесения изменений, и вы можете настроить его на выход через выбранную вами секунду, если страница не изменилась.

Ответ №4:

Мое решение подобных проблем:

 module WaitUntil
  def wait_until(max_wait_time = Capybara.default_max_wait_time)
    Timeout.timeout(max_wait_time) do
      sleep(0.2) until yield
    end
  end
end
 

Использование:

     wait_until { page.has_css?('li', text: 'test', visible: true) }
 

Ответ №5:

Вы можете использовать Capybara.using_wait_time(секунды), чтобы временно изменить значение Capybara.default_max_wait_time для особых случаев:

 Capybara.using_wait_time(10) do 
  page.should have_content "Connection Established"
end