Огурец: Подождите ajax: успех

У меня есть следующие типичные шаги огурца в проекте Rails 3.1:

...
When I follow "Remove from cart"
Then I should see "Test Product removed from cart"

Сложность заключается в том, что кнопка "Удалить из корзины" - это ajax: удаленный вызов, который возвращает "Test Product removed from cart" в элемент #cart_notice через:

$('#cart_notice').append("<%= @product.name %> removed from cart");

Функция отлично работает в браузере, но не находит текст "Тестируемый продукт удален из корзины" в огурце. Я предполагаю, что это потому, что Cucumber ищет текст перед возвратом AJAX?

Итак, короче... Как обеспечить, чтобы огурец ожидал, что ajax вернет результат перед поиском желаемого контента?

Ответы

Ответ 1

Чтобы добавить к сказанному dexter, вы можете написать шаг, который выполняет JS в браузере, который ждет завершения запросов ajax. С помощью jQuery я использую этот шаг:

When /^I wait for the ajax request to finish$/ do
  start_time = Time.now
  page.evaluate_script('jQuery.isReady&&jQuery.active==0').class.should_not eql(String) until page.evaluate_script('jQuery.isReady&&jQuery.active==0') or (start_time + 5.seconds) < Time.now do
    sleep 1
  end
end

Затем вы можете включить шаг по мере необходимости или после каждого шага javascript:

AfterStep('@javascript') do
  begin
    When 'I wait for the ajax request to finish'
  rescue
  end
end

У меня возникли проблемы с автоматической синхронизацией, и это прояснилось.

Ответ 2

Я думаю, вы используете огурец с капибарой. В этом случае capybara поставляется с функцией resynchronize. "Capybara can block and wait for Ajax requests to finish after you’ve interacted with the page." - from capybara documentation

Вы можете включить его в features/support/env.rb

Capybara.register_driver :selenium do |app|
  Capybara::Driver::Selenium.new(app, :browser => browser.to_sym, :resynchronize => true) 
end

Но я видел, что это вызывает проблемы с таймаутом. Итак, если это не работает для вас, я бы рекомендовал ввести ручной этап ожидания перед утверждением результатов запроса ajax.

...
When I follow "Remove from cart"
And I wait for 5 seconds
Then I should see "Test Product removed from cart"

Вы можете определить шаг ожидания в step_definitions/web_steps.rb как

When /^I wait for (\d+) seconds?$/ do |secs|
  sleep secs.to_i
end

Ответ 3

Я полагаю, что wait_until должен выполнить эту работу. Он будет командовать capybara, чтобы проверить что-то до его истины в течение некоторого времени.