Skip to content

Instantly share code, notes, and snippets.

@Lordnibbler
Created August 16, 2013 05:28
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lordnibbler/6247531 to your computer and use it in GitHub Desktop.
Save Lordnibbler/6247531 to your computer and use it in GitHub Desktop.
RSpec::Matchers.define :have_meta do |name, expected|
match do |actual|
has_css?("meta[name='#{name}'][content='#{expected}']")
end
failure_message_for_should do |actual|
actual = first("meta[name='#{name}']")
if actual
"expected that meta #{name} would have content='#{expected}' but was '#{actual[:content]}'"
else
"expected that meta #{name} would exist with content='#{expected}'"
end
end
end
RSpec::Matchers.define :have_title do |expected|
match do |actual|
has_css?("title", :text => expected)
end
failure_message_for_should do |actual|
actual = first("title")
if actual
"expected that title would have been '#{expected}' but was '#{actual.text}'"
else
"expected that title would exist with '#{expected}'"
end
end
end
@geetotes
Copy link

Awesome helper! If you're using a more modern version of Capybara, make sure to set :visible => false on your has_css? and first selectors.

@kulte
Copy link

kulte commented Sep 1, 2015

Yes, awesome helper indeed! This is also a nice addition to make Open Graph meta matching possible:

RSpec::Matchers.define :have_meta do |name, expected|
  match do |actual|
    if name.include?('og:')
      has_css?("meta[property='#{name}'][content='#{expected}']", visible: false)
    else
      has_css?("meta[name='#{name}'][content='#{expected}']", visible: false)
    end
  end

  failure_message_for_should do |actual|
    if name.include?('og:')
      actual = first("meta[property='#{name}']", visible: false)
    else
      actual = first("meta[name='#{name}']", visible: false)
    end

    if actual
      "expected that meta #{name} would have content='#{expected}' but was '#{actual[:content]}'"
    else
      "expected that meta #{name} would exist with content='#{expected}'"
    end
  end
end

@jasonyork
Copy link

jasonyork commented Jul 4, 2022

Adding my version derived from above:

RSpec::Matchers.define :have_meta do |name, expected|
  match do |actual|
    key = name.start_with?("og:") ? "property" : "name"
    element = find("meta[#{key}='#{name}']", visible: false)
    return element[:content].match?(expected) if expected.is_a?(Regexp)

    element[:content].eql?(expected)
  end

  failure_message do |actual|
    key = name.start_with?("og:") ? "property" : "name"
    element = first("meta[#{key}='#{name}']", visible: false)
    return "expected that meta #{name} would have content='#{expected}' but was '#{element[:content]}'" if element

    "expected that meta #{name} would exist with content='#{expected}'"
  end
end

This allows me to pass regex as well, eg:

expect(page).to have_meta("og:image", %r{http://www.example.com/assets/logo/logo-.*.svg})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment