代码之家  ›  专栏  ›  技术社区  ›  BrunoF

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

  •  2
  • BrunoF  · 技术社区  · 7 年前

    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">
    • 我不喜欢JavaScript黑客(使用JQuery添加 stale
    • 该应用程序使用Devise,因此我们需要创建一个用户记录才能登录。注意,为登录目的创建的用户不可避免地出现在我们的测试数据中。
    4 回复  |  直到 7 年前
        1
  •  4
  •   Thomas Walpole    7 年前

    最简单的方法是使用控制测试数据的事实,相应地分配字符串,然后使用正则表达式测试用户实际看到的输出,而不是特定的标记和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
    

    水豚将等待,没有JS黑客需要等。

        2
  •  1
  •   Simple Lime    7 年前

    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 。通常不喜欢修改代码以方便测试,但这似乎很小,允许您以不同的方式设置链接样式,以提醒用户当前的排序。

        3
  •  0
  •   BrunoF    7 年前

    我有一个具体的案例,我想使用共享的例子。因此,我根据托马斯·沃尔波尔的答案创建了以下内容。

    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
    
        4
  •  0
  •   Philip lambok    5 年前

    例如:

    |---------------------|------------------|
    |     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