Reputation: 12663
I have an ajaxified link in a Rails app that, when clicked, results in changes to the DOM.
I'm using Capybara to test for this DOM change. The test is failing, but in the browser this user interaction results in the expected DOM change.
I suspect the test is not waiting for the ajax request to complete. However, I had understood that expect(page).to have_selector
does wait until said element exists.
What am I doing wrong, and what is the correct way to test this interaction?
The code is as follows:
#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
Why isn't expect(page).to have_selector("a.unlike-btn")
waiting until this DOM element exists?
Upvotes: 1
Views: 2803
Reputation: 187
This article explains setting a default wait time by putting:
Capybara.default_max_wait_time = 10
into your RSpec config file.
This article explains actually waiting for the DOM to completely update.
Upvotes: 3