我经常遇到水豚问题,请求测试失败,因为水豚在继续前不等待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
这是水豚的错误还是我做错了什么?
感谢您的帮助......
答案 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