When I run my 'webinar' specs alone they seem to always past, but if I try the whole suite it only passes one of the tests about 50% or the time. I tested this using the same seed each time to see if it had anything to do with the order in which the tests are being executed.
If I slow down my test by putting a sleep in the middle of it then it magically starts passing 100% again. Obviously I don't want to rely on a weak work-around like this and want to figure how to actually fix my problem. require "spec_helper"
require "spec_helper"
describe "ProgramManager::Webinars" do
let(:program) { create(:program) }
let(:superuser) { create(:superuser) }
describe "#index" do
before { login_as(superuser) }
let(:delete) { 'Delete' }
it "displays an edit and destroy link for all webinars" do
w1, w2, w3 = create(:webinar, program: program), create(:webinar, program: program), create(:webinar, program: program)
visit program_webinars_path(program)
[w1, w2, w3].each do |webinar|
expect(page).to have_link webinar.name, href: edit_program_webinar_path(program, webinar)
expect(page).to have_link '', href: destroy_warnings_program_webinar_path(program, webinar)
end
end
it "has a link to create a new webinar" do
visit program_webinars_path(program)
expect(page).to have_content 'New Webinar'
end
it "deletes a webinar", js: true do #THIS IS THE TEST THAT SOMETIMES FAILS
webinar = create(:webinar, program: program)
visit program_webinars_path(program)
all('.destroy').last.click
wait_for_ajax
sleep(1.second) #THIS IS THE SLEEP THAT FIXES THE FAILURE
expect { click_link delete }.to change(Webinar, :count).by(-1)
end
end
.
FactoryGirl.define do
factory :webinar do
program
name "some name"
url "some url"
description "some description"
speaker "some speaker"
starts_at Time.now
end
end
.
FactoryGirl.define do
factory :program do
contract
program_manager factory: :user
sequence(:name) { |n| "Program-#{n}" }
description { "Program description" }
starts_at { Time.now }
ends_at { Time.now + 10.days }
color { "#33f" }
program_type { "some program type" }
verified { false }
end
end
.
<div class="col-md-4">
<%= link_to "<span class='glyphicon glyphicon-plus'></span>".html_safe, new_program_webinar_path(@program), class: 'new-webinar', data: { toggle: 'tooltip', title: 'Add a Webinar' } %>
<h4>Current Webinars</h4>
<% if @webinars.empty? %>
<p>There are currently no webinars to display.</p>
<% else %>
<table class="table table-condensed">
<% @webinars.each do |webinar| %>
<tr>
<%= content_tag :td, class: pm_setup_classes(webinar, @webinar) do %>
<%= link_to "<span class='glyphicon glyphicon-remove'></span>".html_safe, destroy_warnings_program_webinar_path(@program, webinar), class: 'destroy', data: { toggle: 'modal', target: '#ajax-modal' } %>
<%= link_to webinar.name, edit_program_webinar_path(@program, webinar), class: 'webinar' %>
<% end %>
</tr>
<% end %>
</table>
<% end %>
<%= link_to 'New Webinar', new_program_webinar_path(@program), class: 'btn btn-success btn-block' %>
</div>
.
class ProgramManager::WebinarsController < ProgramManager::ApplicationController
before_filter :authenticate_user!
before_filter :webinars
def new
@webinar = @webinars.build
clean_webinars
end
def create
@webinar = @program.webinars.build(params[:webinar])
clean_webinars
if @webinar.save
redirect_to program_webinars_path(@program), success: "Webinar successfully created"
else
render :new
end
end
def edit
@webinar = @program.webinars.find(params[:id])
end
def update
@webinar = @program.webinars.find(params[:id])
if @webinar.update(params[:webinar])
redirect_to program_webinars_path(@program), success: "Webinar successfully updated"
else
render :edit
end
end
def destroy
@webinar = @program.webinars.find(params[:id])
if @webinar.destroy
redirect_to program_webinars_path(@program), success: "Webinar removed successfully"
else
render :index
end
end
def destroy_warnings
@webinar = @program.webinars.find(params[:id])
render layout: false
end
private
def clean_webinars
@webinars = @webinars.delete_if(&:new_record?)
end
def webinars
@webinars = @program.webinars
end
end
I am sorry there is so much code associated with this question. I'm just trying to provide as much info as I can since I have no idea where this bug is from or how to fix it
The problem seemed to ultimately be a javascript fade in. The delete button we are trying to press is on a modal that fades in to alert you of the repercussions of your deletion and asks you to confirm. Our wait_for_ajax() helper waited until all active jQuery connections were resolved. The connections would finish so it would move on to the next line of code which told it to click a link on the delete link. The html had a delete link in it so Capybara can find it, but since it is actively fading in... the click doesn't work and the test fails!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With