Capybara ajax比赛条件

时间:2012-08-02 10:50:42

标签: ruby-on-rails ruby-on-rails-3 rspec tdd capybara

我经常遇到水豚问题,请求测试失败,因为水豚在继续前不等待ajax事件完成。

谷歌似乎表明我应该使用:我的测试的resynchronize选项来解决这个问题。但它没有用。

为了证明这是一个问题,可以通过在ajax调用之后放入sleep语句来修复失败的测试。这看起来很糟糕,因为适当的延迟将根据运行测试的机器的速度而变化。选择一个适当大的值会严重降低运行带有大量ajax操作的测试套件的速度。

下面是失败/通过测试的一个例子。单击“保存”之前的睡眠会使页面上的传递/失败区别开来。应该是has_content('custom item'):

it "should be able create a new todo item", :js, :resynchronize, :focus do
  # Visit new action
  visit new_todo_list


  # Fill in the name
  fill_in "#name", "test list"

  # Click on add item to launch inline popup
  find('a.add-item').click
  within '#new_item' do
    fill_in 'todo_item_description', :with => 'custom item'
    # Run ajax action to add currrent item
    find('.btn').click
  end

  sleep(1)

  # Save
  find('a.save').click

  page.should have_content('test list')
  page.should have_content('custom item')

end

这是水豚的错误还是我做错了什么?

感谢您的帮助......

1 个答案:

答案 0 :(得分:4)

前段时间我遇到了这个问题,并使用这种方法来确定ajax请求何时完成:

wait_until do
  page.evaluate_script('$.active') == 0
end

仍然非常hacky,但比使用sleep稍微好一些。我是从here得到的。我将它用于Cucumber功能,但它也应该在rspec请求规范中使用。

更新(2013年6月19日)

wait_until已在版本2.0中从Capybara中删除,有关原因的详细信息,请参阅:Why wait_until was removed from Capybara

我已经按照其中一条建议进行了实施,只是针对这一个案例(我认为这是合理的):

def wait_until
  require "timeout"
  Timeout.timeout(Capybara.default_wait_time) do
    sleep(0.1) until value = yield
    value
  end
end