Case insensitive Rspec match

后端 未结 6 671
温柔的废话
温柔的废话 2021-02-12 10:00

I\'m writing a Capybara test and using Rspec for the assertions. My test is failing because there is a CSS style being applied that is causing the text to be in all caps. How ca

相关标签:
6条回答
  • 2021-02-12 10:09

    Rspec syntax has changed significantly in 4 years, but this underlying problem still seems like a problem. My solution was to build a custom matcher has_content_i, which was like has_content but is case insensitive. The resulting call looks like:

    expect(page).to have_content_i("All Caps")
    

    Here's the source:

    RSpec::Matchers.define :have_content_i do |expected|
      match do |actual|
        actual.text =~ /#{Regexp.quote expected}/i
      end
    
      failure_message do |actual|
         "expected to find text #{expected.inspect} case insensitively in #{actual.text.inspect}"
      end
    
      failure_message_when_negated do |actual|
        "expected to not to find text #{expected.inspect} case insensitively in #{actual.text.inspect}"
      end
    end
    

    http://danielchangnyc.github.io/blog/2014/01/15/tdd2-RSpecMatchers/ has information on where to stash the custom matcher definitions in your project tree.

    0 讨论(0)
  • 2021-02-12 10:15

    How about downcasing both ends of the assertion?

    "ALL CAPS".downcase.should include('All Caps'.downcase)
    
    0 讨论(0)
  • 2021-02-12 10:16

    how about using a regex to do this?

    "ALL CAPS".should match(/#{Regexp.escape('All Caps')}/i)
    
    0 讨论(0)
  • 2021-02-12 10:23

    Here's improving on phoet's solution:

    page.body.should match(%r{#{string}}i)
    

    Unfortunately the syntax highlighting here isn't doing it much justice (it looks perfectly fine in Sublime Text)

    0 讨论(0)
  • 2021-02-12 10:27

    Also, if you are using Capybara, you can use the have_content matcher which is case insensitive:

    <h1>ALL CAPS</h1>
    
    find('h1').should have_content('All Caps')
    

    Update: I guess I was partly wrong. Consider this:

    <h1 style="text-transform: uppercase">Title Case</h1>
    
    puts find('h1').text
    # TITLE CASE  < notice all caps
    
    puts find('h1').has_content?('Title Case')  # true
    
    puts find('h1').has_content?('TITLE CASE')  # false
    
    puts find('h1').has_content?('title case')  # false
    

    It's strange to me that the text returned is in all caps (how it's styled after CSS), but the matcher is actually testing against the text in the unstyled HTML. I spent a while digging through the source code and I still can't figure out why this works.

    0 讨论(0)
  • 2021-02-12 10:30

    I only run into this issue when:

    • Using poltergeist driver. (I don't know if this also happens with other drivers)

    • Inspecting page, not page.body for expectations: expect(page).to ...

    So, If I do expect(page.body).to ... it just works and solved the issue.

    0 讨论(0)
提交回复
热议问题