Огурец: Подождите 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
, чтобы проверить что-то до его истины в течение некоторого времени.