Capybara is not waiting for ajax to finish

capybara, rspec, ruby-on-rails

Solution

The main problem, as you said, it's Capybara didn't wait. But the main reason is the test doesn't use a consistent style.

If using Capybara, the test acts like a real user, and you should expect some UI change instead of database change, for real user can't see what happens in db.

In this test, the db assertion is executed right away, even faster than the browser driver sending data to server, so the data is nil.

To fix,

Remove the `within` block at first. This seems unimportant. If I remembered correctly, the expectation should better not in different block of the action. So do it for safety.

Add UI expectation. Then Capybara will wait until the effect appears.

So,

scenario 'Creating job', js: true do
  fill_in 'Email', with: @customer.email
  fill_in 'Password', with: @customer.password
  click_button 'Login'
  # Assume your page will show user name after signing in
  expect(page).to have_content(@customer.name)
end

If you really want to test db change, you can add that expectation after UI expectation, but I don't recommend that.

Problem

I'm working on a application which consist of a EmberJS frontend, which talk to a Rails server via REST. In my application goes through a wizard to create a job, so i would like to test if that job is created, this is my test. ``` feature 'Processing step three', :js => true do background do to_step_2 to_step_3 end scenario 'Creating job', js: true do within '#login' do fill_in 'Email', with: @customer.email fill_in 'Password', with: @customer.password click_button 'Login' end expect { click_link 'Create job' }.to change(Job, :count).by(1) end end ``` So when the user has filled in everything, lastly they click on create job, just like my test describes. This works fine when i do it manually, but when i run my spec i get. ``` 1) Creating a new job Processing step three Creating job Failure/Error: expect { click_link 'Create job' }.to change(Job, :count).by(1) count should have been changed by 1, but was changed by 0 # ./spec/features/creating_a_new_job_spec.rb:103:in `block (3 levels) in <top (required)>' ``` Now if i look at my test log i can see, that capybara runs the count, before my job is inserted ``` Completed 200 OK in 36ms (Views: 6.0ms | ActiveRecord: 11.2ms) Started POST "/api/jobs" for 127.0.0.1 at 2013-12-08 14:15:00 +0100 Processing by Api::JobsController#create as JSON Parameters: {"job"=>{"description"=>"This is a test description of the service i would like to receive.", "zip"=>"2400", "available_from"=>"24 - 12 - 2013", "available_next"=>false, "customer_id"=>"1", "service_id"=>"1", "service_field_id"=>"1"}} Unpermitted parameters: zip (11.3ms) SELECT COUNT(*) FROM "jobs" (1.2ms) BEGIN SQL (2.5ms) INSERT INTO "jobs" ("available_from", "available_next", "created_at", "customer_id", "description", "service_field_id", "service_id", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["available_from", Tue, 24 Dec 2013 00:00:00 UTC +00:00], ["available_next", false], ["created_at", Sun, 08 Dec 2013 13:15:00 UTC +00:00], ["customer_id", 1], ["description", "This is a test description of the service i would like to receive."], ["service_field_id", 1], ["service_id", 0], ["updated_at", Sun, 08 Dec 2013 13:15:00 UTC +00:00]] (0.5ms) COMMIT ``` How do i force Capybara to hold the sails a bit?

Original source