sajad torkamani

Suppose you want to test that an index page lists items by the created_at date in descending order. Here’s an approach.

Create custom matcher

Add the following custom matcher to a support file (e.g., in a file named spec/support/custom_matchers):

RSpec::Matchers.define :appear_before do |later_content|
  match do |earlier_content|
    earlier_content_index = page.body.index(earlier_content)
    later_content_index = page.body.index(later_content)

    @failure_message = "Expected \"#{earlier_content}\" to appear before \"#{later_content}\""

    def raise_missing_content_error(content)
      @failure_message += " but \"#{content}\" was not found on the page."
      raise RSpec::Expectations::ExpectationNotMetError
    end

    raise_missing_content_error(earlier_content) if earlier_content_index.nil?
    raise_missing_content_error(later_content) if later_content_index.nil?

    earlier_content_index < later_content_index
  end

  failure_message { @failure_message }
end

Use custom matcher

it 'lists the notes, with the most recently created at the top' do
  user = create(:user)
  old_note = create(:note, created_at: 2.minutes.ago, user:)
  new_note = create(:note, created_at: 1.minute.ago, user:)

  login_as(user)
  visit_page

  expect(new_note.content.to_plain_text)
    .to appear_before(old_note.content.to_plain_text)
end