map7
map7

Reputation: 5126

capybara waiting for ajax without using sleep

I'm using Capybara 2.x for some integration tests for a large Rails/AngularJS app and I've come across a test in which I need to put a sleep to get it working.

My test:

describe "#delete", js: true do
  it "deletes a costing" do
    costing = Costing.make!

    visit "/api#/costings"
    page.should have_content("General")

    click_link "Delete"     # Automatically skips the confirm box when in capybara

    sleep 0.4
    page.should_not have_content("General")
  end
end

The code it tests is using ng-table which takes a split second to update, without that sleep it will fail. Capybara used to have a wait_until method for this but it's been taken out. I found this website: http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara but cannot get any of the recommended alternatives working for this problem.

Here is the code I'm testing.

  # --------------------------------------------------------------------------------
  # Delete
  # --------------------------------------------------------------------------------
  $scope.destroy = (id) ->
    Costing.delete (id: id), (response) -> # Success
      $scope.tableParams.reload()
      flash("notice", "Costing deleted", 2000)

This updates the ng-table (tableParams variable) which is this code

  $scope.tableParams = new ngTableParams({
    page: 1,
    count: 10,
    sorting: {name: 'asc'}
  },{
    total: 0,

    getData: ($defer, params) ->
      Costing.query {}, (data) ->
        # Once successfully returned from the server with my data process it.
        params.total(data.length)

        # Filter
        filteredData = (if params.filter then $filter('filter')(data, params.filter()) else data)

        # Sort
        orderedData = (if params.sorting then $filter('orderBy')(filteredData, params.orderBy()) else data)

        # Paginate
        $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()))
  })

Upvotes: 3

Views: 1154

Answers (1)

Sam
Sam

Reputation: 3067

Try bumping the Capybara.default_wait_time up to 3 seconds or 4.

If that fails, try changing the spec to look for the flash notice message before it checks to see if the item has been removed from the page. (Assuming the flash message gets rendered in the HTML body)

describe "#delete", js: true do
  it "deletes a costing" do
    costing = Costing.make!

    visit "/api#/costings"
    page.should have_content("General")

    click_link "Delete"

    page.should have_content("Costing deleted")
    page.should_not have_content("General")
  end
end

Edit - removed explanation because it was incorrect.

Upvotes: 1

Related Questions