Rails 4 Rspec expects {}. Change registration even though the test is working as planned

I am working with Rails 4, RSpec, Capybara and selenium. I ran into an oddity that I can't seem to solve after trying it on the last day or so. I have a fairly simple query specification because the test doesn't register the model change. Here's my spec:

describe "manage pages", :js => true do
    before :each do
        @fake_page = FactoryGirl.create(:page_with_block, name: "Foobar")
        @fake_page2 = FactoryGirl.create(:page_with_block, name: "sdfdf")
        visit admin_pages_path
        save_page
    end

    it "should delete an image when link is clicked" do
        expect {
            within "#page_#{@fake_page.id}" do
                click_link 'Destroy'
            end
            wait = Selenium::WebDriver::Wait.new ignore: Selenium::WebDriver::Error::NoAlertPresentError
            alert = wait.until { page.driver.browser.switch_to.alert }
            alert.accept
        }.to change(Page, :count).by(-1)
        expect(page).to have_content "Listing Pages"
        expect(page).not_to have_content "Foobar"   
        save_page           
    end
end 

      

As you can see, this is the main kill click and validation js alert test. The problem is, it always fails:

......F

Failures:

  1) Pages manage pages should delete an image when link is clicked
     Failure/Error: expect {
       expected #count to have changed by -1, but was changed by 0
     # ./spec/requests/admin/pages_spec.rb:116:in `block (3 levels) in <top (required)>'

Finished in 11.74 seconds (files took 3.81 seconds to load)
7 examples, 1 failure

      

According to the save_page files that I placed in my application earlier and another at the end of the test, when I comment out "wait", everything works as intended, fake pages are created in before the test passes and clicks, destroys and receives a warning. the page is destroyed and the index page is reloaded without it on the content. What I don't understand is why the Change helper doesn't see that it is, in fact, working.

I've read that it may have something to do with my rails_helper.rb file, but everything I've been looking for has a similar, if not precise, setup:

    ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  config.use_transactional_fixtures = false

  config.infer_spec_type_from_file_location!

  config.include Capybara::DSL

    config.before(:suite) do
        DatabaseCleaner.strategy = :truncation
        DatabaseCleaner.clean_with(:truncation)
    end
    config.before(:each) do
        DatabaseCleaner.strategy = :transaction
    end
    config.before(:each, :js => true) do
        DatabaseCleaner.strategy = :truncation
    end
    config.before(:each) do
        DatabaseCleaner.start
    end 
    config.after(:each) do
        DatabaseCleaner.clean
    end 

    config.after(:suite) do
        FileUtils.rm_rf(Dir["#{Rails.root}/public/test/system/"])
    end


end

      

Since I can't find any other event of this on google or this site, I should just be doing something wrong. Can anyone point me to a flaw in my code? Thank you in advance.

+3


source to share


1 answer


I am struggling with the same problem. You expect the logic to be flawed. I've used this approach and it worked well for me.

Copied from this article - basically you need to create a helper:

# spec/support/wait_for_ajax.rb
module WaitForAjax
  def wait_for_ajax
    Timeout.timeout(Capybara.default_max_wait_time) do
      loop until finished_all_ajax_requests?
    end
  end

  def finished_all_ajax_requests?
    page.evaluate_script('jQuery.active').zero?
  end
end

RSpec.configure do |config|
  config.include WaitForAjax, type: :feature
end

      

Include all support files automatically in spec_helper.rb

spec/support/**/*.rb in our spec_helper.rb

      



or do it manually like me:

#rails_helper.rb
require_relative 'support/wait_for_ajax'

      

Now my test is passing!

require 'rails_helper'

RSpec.feature "Call Me Back contact front feature spec >", :type => :feature, js: true do
feature 'valid form' do
  scenario "with name and phone" do
    visit '/'
    execute_script '$("#call-popup").fadeIn(300)'

    fill_in 'call_me_back_request_name', with: 'Clark Kent'
    fill_in 'call_me_back_request_phone', with: '1234445566'

    within '#new_call_me_back_request' do
      expect{
        find("input[type='submit']").click
        wait_for_ajax #<- the magic is here!
      }.to change(Request, :count).by(1)
    end
  end
end

      

+1


source







All Articles