2

我经常在 capybara 中遇到请求测试失败的问题,因为 capybara 在继续之前没有等待 ajax 事件完成。

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

为了证明这是一个问题,可以通过在 ajax 调用之后放置一个 sleep 语句来修复失败的测试。这似乎是任何不好的做法,因为适当的延迟会根据运行测试的机器的速度而有所不同。并且选择一个适当大的值将严重减慢运行具有大量 ajax 操作的测试套件的速度。

下面是一个失败/通过测试的例子。单击保存之前的睡眠会影响 page.should have_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

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

谢谢你的帮助...

4

1 回答 1

4

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

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

仍然很 hacky,但比使用sleep. 我从这里得到的。我将它用于 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
于 2012-08-02T12:19:22.190 回答