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
其他详情:
<TR>
个元素的DOM ID包含其相应记录的DB ID,如<tr class="user" id="user_34">
。使用正则表达式提取记录在页面中显示的顺序可能不是最佳解决方案。你能建议一个更好的方法吗?stale
类然后等到它消失以确保页面被重新加载),但到目前为止我找不到另一种方法来确保Capybara等待直到重新加载页面(应用新的排序顺序)。你能建议一个更好的方法吗?答案 0 :(得分:2)
最简单的方法是使用控制测试数据的事实,相应地分配字符串然后使用正则表达式来测试用户实际看到的输出而不是特定的标记和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
Capybara会等,不需要JS hack等等。
答案 1 :(得分:1)
从this blog post获取想法,你可以做类似
的事情# get the index of the first occurrence of each users' email address in the response body
actual_order = User.order(:email).map { |user| page.body.index(user.email) }
# should already be in sorted order
expect(actual_order).to eq(actual_order.sort)
至于必须等待.stale
类被删除,我建议修改你的html,在你的th
上包含某种“这是当前排序的列”类或者a
代码。
<a id="email-sort-link" class="sorted asc">E-Mail</a>
然后你可以等到a#email-sort-link.sorted
。通常不喜欢修改代码以方便测试,但这似乎很小,并且允许您以不同方式设置链接的样式以提醒用户当前的排序。
答案 2 :(得分:0)
我有一个特定的案例,我想使用共享示例。所以我根据Thomas Walpole的回答创建了以下内容。
def sort_order_regex(*sort_by_attributes)
/#{User.order(sort_by_attributes)
.map { |u| Regexp.quote(u.email) }
.join(".+")}/
end
RSpec.shared_examples "sort link" do |link_text:, sort_by:|
# Make sure your factory creates unique values for all sortable attributes
before(:each) { FactoryGirl.create_list(:user, 3) }
it "sorts by #{sort_by} when the #{link_text} link is clicked" do
visit "/admin/users"
# Check the record's order by matching the order of their e-mails (unique).
initial_order = sort_order_regex(:first_name, :last_name)
tested_order = sort_order_regex(sort_by)
within_table "users_table" do
expect(page).to have_text(initial_order)
click_link(link_text, exact: false)
expect(page).to have_text(tested_order)
end
end
end
describe "User CRUD", type: :feature, js: true do
describe "sorting" do
include_examples "sort link", link_text: "E-mail", sort_by: :email
include_examples "sort link", link_text: "Role", sort_by: :role
include_examples "sort link", link_text: "Country", sort_by: :country
include_examples "sort link", link_text: "Quotes", sort_by: :quotes_count
end
#...
end
答案 3 :(得分:0)
我们可以用CSS东西对其进行测试。
一个例子:
|---------------------|------------------|
| username | email |
|---------------------|------------------|
| bot1 | bot1@mail.com |
|---------------------|------------------|
| bot2 | bot2@mail.com |
|---------------------|------------------|
我们的RSpec可以像:
RSpec.describe "returns expected sorted row data" do
it 'returns expected sorted row data' do
# the headers column name
within 'tr:nth-child(1)' do
expect(page).to have_text 'username password'
end
# the second row
within 'tr:nth-child(2)' do
expect(page).to have_text 'bot1 bot1@mail.com'
end
# the third row
within 'tr:nth-child(3)' do
expect(page).to have_text 'bot2 bot2@mail.com'
end
end
end