Rspec Capybara test with ajax call not updating record

社会主义新天地 提交于 2019-12-24 05:31:31

问题


I have a form where when a user submits an ajax form with a single name field, a record is created that belongs to a Template object. This all works fine manually, but for some reason when I test this via rspec its telling me that the association was not created. Why isn't the template object updated here?

describe "edit page" do
  before(:each) do
    visit edit_admin_template_path(template)
  end

  context "form sections", js: true do  
    it "allows admin to create one" do
      find("#btn-add-section").click
      within('#new_form_section') do
        fill_in 'Name', with: "Personal Info"
        click_button "Create Section"
      end
      expect(template.form_sections.length).to eq(1)
    end
  end
end

This is the failure that I am getting

Failure/Error: expect(template.form_sections.length).to eq(1)

   expected: 1
        got: 0

   (compared using ==)

UPDATE: just noticed this in the rspec output

An error occurred in an after hook
    ActionView::Template::Error: undefined method `form_sections' for nil:NilClass

so its telling me that the template object does not exist, then its able to compare it afterwards?

UPDATE 2: So it appears that the issue is waiting for the ajax call to complete in capybara, before expecting. I added this to the spec and it now works, obviously I need to refacotr this to something better like a helper

it "allows admin to create one" do
  find("#btn-add-section").click
  within('#new_form_section') do
    fill_in 'Name', with: "Personal Info"
    click_button "Create Section"
  end
  sleep(10) #this waits for the request to complete
  expect(template.form_sections.length).to eq(1)
end

回答1:


The key is telling rspec to wait for the ajax call to complete before doing any expectations. This is a great post on the solution that I used.

Thoughtbot - automatically wait for ajax wioth capybara

http://robots.thoughtbot.com/automatically-wait-for-ajax-with-capybara ""




回答2:


Just in case others stumble upon this, rather than using sleep you could test based on the UI itself. Capybara will wait for that element to reload, if you use have_css or find matchers, like this:

expect(page).to have_css("#form-page-two", visible: :visible) #this will force test to wait for ajax call

Capybara.automatic_reload must not be set to false. (defaults to true)

This strategy will reduce the run time of your test suite; if the test only took 2 or 3 seconds to load it will only wait that long (not 10).

However, it can be frustrating to write because of intermittent failures. To avoid this you may need to bump up the wait time setting.

Capybara.default_max_wait_time = 10

https://github.com/teamcapybara/capybara#asynchronous-javascript-ajax-and-friends



来源:https://stackoverflow.com/questions/27967849/rspec-capybara-test-with-ajax-call-not-updating-record

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!