开发者

Cucumber: Wait for ajax:success

I have the following typical cucumber steps in a Rails 3.1 project:

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

The difficulty is that "Remove from cart" button is an ajax :remote call, which returns "Test Product removed from cart" to the #cart_notice element via:

$('#cart_notice').append("<%= @product.name %> removed from cart");开发者_Go百科

The function works fine in the browser, but doesn't find the "Test Product removed from cart" text in cucumber. I'm guessing this is because Cucumber is searching for the text before the AJAX returns it?

So, in short...how do I ensure cucumber waits for the ajax to return a result before searching for the desired content?


To add to what dexter said, you may want to write a step that executes JS in the browser which waits for ajax requests to finish. With jQuery, I use this step:

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

You can then include the step as needed, or after every javascript step:

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

I was having issues with the automatic synchronization, and this cleared it up.


I guess you are using cucumber with capybara. In that case, capybara comes with a resynchronize feature. "Capybara can block and wait for Ajax requests to finish after you’ve interacted with the page." - from capybara documentation

You can enable it in features/support/env.rb

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

But, I have seen this causing timeout issues. So, if that isn't working for you, I would recommend introducing a manual wait step before asserting the results of the ajax request.

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

You can define the wait step in step_definitions/web_steps.rb as

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


I suppose wait_until should do the job. It will command to capybara to check something until its true for some time.


Old question, but the Spreewald gem should help https://github.com/makandra/spreewald

You can use the patiently method from the Spreewald gem like so:

Then /^I should see "([^\"]*)" in the HTML$/ do |text|
  patiently do
    page.body.should include(text)
  end
end

The step will maintain a loop for a period of time until the desired text appears in the test dom, else the step will fail.

(taken from https://makandracards.com/makandra/12139-waiting-for-page-loads-and-ajax-requests-to-finish-with-capybara)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜