在 RSpec 功能规范中测试索引视图排序顺序 (Capybara)

Bru*_*cca 2 ruby testing rspec ruby-on-rails capybara

Rails 4.2 应用程序的索引视图有一个表,表头带有排序链接。如果用户单击“电子邮件”标题,记录将按电子邮件排序,依此类推。单击排序链接时,页面将重新加载(使用类似的查询字符串q=email+asc)。尚未使用 AJAX。

我写了以下测试。它有效,但我相信应该有更好的方法来测试它。

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
Run Code Online (Sandbox Code Playgroud)

额外细节:

  • <TR>元素具有 DOM ID,其中包含其相应记录的 DB ID,例如<tr class="user" id="user_34">. 使用正则表达式提取记录在页面中显示的顺序可能不是最好的解决方案。你能建议一个更好的方法吗?
  • 我不喜欢 JavaScript hack(使用 JQuery 添加stale类,然后等待它消失以确保页面重新加载),但到目前为止我找不到另一种方法来确保 Capybara 等待页面重新加载(新的应用排序顺序)。你能建议一个更好的方法吗?
  • 该应用程序使用 Devise,因此我们需要创建用户记录才能登录。请注意,为登录目的创建的用户不可避免地会出现在我们的测试数据中。

Tho*_*ole 5

最简单的方法是利用您控制测试数据的事实,相应地分配字符串,然后使用正则表达式来测试用户实际看到的输出,而不是特定的标签和 ID。

within_table('user_table') do # any method that will scope to the table
  expect(page).to have_text /user3@test\.com.+user2@test\.com.+user1@test\.com/ # initial expected ordering
  click_link("E-mail")
  expect(page).to have_text /user1@test\.com.+user2@test\.com.+user3@test\.com/ # sorted expected ordering
end
Run Code Online (Sandbox Code Playgroud)

Capybara 会等待,不需要 JS hack 等。