Read more

RSpec: Expect one of multiple matchers to match

Henning Koch
May 18, 2018Software engineer at makandra GmbH

RSpec let's you chain a matcher with .or. The expectation will then pass if at least one matcher matches:

expect(color).to eq("red").or eq("green")

Real-world example

Illustration online protection

Rails professionals since 2007

Our laser focus on a single technology has made us a leader in this space. Need help?

  • We build a solid first version of your product
  • We train your development team
  • We rescue your project in trouble
Read more Show archive.org snapshot

A real-world use case would be to test if the current page has a button with the label "Foo". There are many ways to render a button with CSS:

<input type="button" value="Foo">
<input type="submit" value="Foo">
<button>Foo</button>

We cannot express it with a single have_css() matcher, since we need the { text: 'Foo' } option for some cases (<input>), but not for others (<button>).

What we can do is chain multiple have_css() matchers with .or like this:

match_button = have_css("button", text: 'Foo')
match_button_input = have_css("input[type='button'][value='Foo']")
match_submit_input = have_css("input[type='submit'][value='Foo']")

expect(page)
  .to match_button
  .or match_button_input
  .or match_submit_input

Tip

Capybara also has a find_button Show archive.org snapshot method that takes care of all these details for you.

You can also require multiple matchers on the same object by chaining them with .and, although you might just want to use multiple expect() statements for readability and mergability.

Posted by Henning Koch to makandra dev (2018-05-18 11:02)