如何使用Capybara测试Ajax响应?

时间:2016-02-07 03:43:50

标签: ruby-on-rails ajax capybara

我在Rails应用程序中有一个ajaxified链接,单击该链接会导致对DOM的更改。

我使用Capybara来测试这个DOM更改。测试失败,但在浏览器中,此用户交互会导致预期的DOM更改。

我怀疑测试不是在等待ajax请求完成。但是,我已经理解expect(page).to have_selector确实等到所述元素存在。

我做错了什么,测试这种互动的正确方法是什么?

代码如下:

#objects/show.html.erb
...
<div class='like-container'>
  <%= render partial: "shared/like_button" %>
</div>
...


#shared/like_button
<% if current_user.likes? @likable %>
  <%= link_to 'Unlike', 
    unlike_path(#params),
    id:"#{@likable.class.name.underscore }_#{ @likable.id }_like", 
    class: "unlike-btn",
    method: :delete, 
    remote: true 
    %>
<% else %>
  <%= link_to 'Like', 
    like_path(#params), 
    id: "#{@likable.class.name.underscore }_#{ @likable.id }_like",
    class: "like-btn",
    method: :post, 
    remote: true 
    %>
<% end %>


#likes/create.js
$('#<%= @likable.class.name.underscore %>_<%= @likable.id %>_like').replaceWith('<%= j render partial: "shared/like_button" %>');


#likes/destroy.js 
$('#<%= @likable.class.name.underscore %>_<%= @likable.id %>_like').replaceWith('<%= j render partial: "shared/like_button" %>');


#user_likes_object_spec.rb
feature 'likes object' do
  before :each do
    @object = create :object
    @user   = create :user
    login_as @user
    visit object_path @object
  end

  scenario 'it creates and then destroys like when clicked', js: true do
    expect(page).to have_link "Like", href: like_path(#params)
    click_link 'Like'
    # the test is failing on the following line
    # Failure/Error: expect(page).to have_selector("a.unlike-btn")
    # expected to find css "a.unlike-btn" but there were no matches
    expect(page).to have_selector("a.unlike-btn")
    click_link 'Unlike'
    expect(page).to have_selector("a.like-btn")
  end
end

为什么没有expect(page).to have_selector("a.unlike-btn")等待这个DOM元素存在?

1 个答案:

答案 0 :(得分:3)

This article解释了设置默认等待时间:

Capybara.default_wait_time = 10

进入RSpec配置文件。

This article解释了实际上等待DOM完全更新。