R – Finding a label with Webrat that contains a link

cucumberruby-on-railswebrat

So I'm doing BDD with Cucumber and have a form with checkboxes populated from a database. The labels for the checkboxes contain hyperlinks. So far, not too exotic (note, this is HAML and not Erb, but it should be readable enough for any Rails person):

I would like my donation to support:
%br
- for podcast in @podcasts
  = check_box_tag "donation[podcast_ids][]", podcast.id, true
  = donation.label "donation[podcast_ids][]", link_to(podcast.name, podcast.url), :value => podcast.id
  %br

The problem is that in my Cucumber features, I can't figure out how to find that checkbox to check it. The relevant part of the story is this:

  Scenario: Happy path
    Given I am on the home page
    When I fill in "My email address" with "john@example.org"
     # Skipped for brevity...
     And I check the "Escape Pod" podcast
     And I check the "PodCastle" podcast
     And I press "I'm ready!"
    Then I should see "Thank you!"
     And there should be 2 podcast donation records

If I'm using the bare webrat_steps.rb file I get the following error:

Could not find field: "Escape Pod" (Webrat::NotFoundError)

I'm quite certain it's because of that link_to() method, which I'm using to make "Escape Pod" a hyperlink to the actual Web site. But I can't easily access link_to from my Cucumber step, and I can't figure out any reasonable way of pointing Webrat at the right checkbox short of kludging up a whole bunch of hyperlink code in my step (which makes it very brittle).

My BDD is stalled at this point. I don't want to take out the link just because it's hard to test. And it feels like it shouldn't be hard to test. Webrat is just limiting what I can pass into the checks() method. Can anyone suggest an elegant answer for this?

Best Answer

The short answer is the to use field_by_xpath or one of the other Webrat::Locators methods to select what element to manipulate in your step:

When(/^I check the "(.+?)" podcast$/) do |name|
  check(field_by_xpath("//label/a[.=#{name}]")
end

You might need to play with that xpath a little, or use field_by_id instead. Remember it is looking got the html id of the tag not the id from the database.

Related Topic