lundi 24 juillet 2017

Testing index view sort order in RSpec feature spec (Capybara)

An index view of a Rails 4.2 app has a table with sort links at its header. If the user clicks the "E-mail" header, records are sorted by E-mail, and so on. When a sort link is clicked, the page is reloaded (with a query string like q=email+asc). AJAX is not yet used.

I've written the following test. It works, but I believe there should be a better way to test this.

it "sorts by e-mail when the 'E-mail' column header is clicked", :focus do
  visit "/admin/users"
  expected_id_order = User.order(:email).map(&:id)
  # Once the page is reloaded (the new sort order is applied), the "stale"
  # class will disappear. Note that due to Turbolinks, only the part of
  # the DOM that is modified by a request will have its elements replaced.
  page.execute_script("$('tr.user:first').addClass('stale')")
  within "thead" do
    click_link("E-mail")
  end
  # Force Capybara to wait until the page is reloaded
  expect(page).to have_no_selector("tr.user.stale")
  actual_id_order = page.body.scan(/<tr.+id="user_(.+)".*>/).flatten
  expect(actual_id_order).to eq(expected_id_order)
end

Additional details:

  • <TR> elements have DOM IDs containing the DB IDs of their corresponding records, like <tr class="user" id="user_34">. Using regex to extract the order in which the records are displayed in the page is probably not the best solution. Can you suggest a better way?
  • I don't like the JavaScript hack (using JQuery to add the stale class and then waiting until it disappears to ensure the page was reloaded), but so far I could not find another way to ensure Capybara waits until the page is reloaded (the new sort order is applied). Can you suggest a better way?
  • The test data consists of 3 records created with FactoryGirl.

Aucun commentaire:

Enregistrer un commentaire