Capybara does not wait for ajax to finish

I am working on an application consisting of an EmberJS interface that talks to a Rails server through REST. A task creation wizard runs in my application, so I would like to check if this task 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 completed everything, finally, they click on the creation of the task, as described in my test. This works great 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 account before my work 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 to make Capybara hold the sails a bit?

+6
source share
1 answer

The main problem, as you said, is Capybara did not wait. But the main reason is that the test does not use a consistent style.

If you use Capybara, the test acts like a real user, and you should expect a change in the user interface instead of changing the database, since the real user cannot see what is happening in db.

In this test, the db statement is executed immediately, even faster than the browser driver sending data to the server, so the data is zero.

To fix it,

  • First remove the within block. It seems inconsequential. If I remembered correctly, waiting is better not in a different action block. So do it for security.

  • Add wait for user interface. Then Capybara will wait for the effect to appear.

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 check the db change, you can add this wait after waiting for the user interface, but I do not recommend this.

+10
source

All Articles