views:

823

answers:

2

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 "[email protected]"
     # 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?

+2  A: 

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.

John F. Miller
Thanks John -- I knew about the `field\_by\_` locators, but being able to pass them as a parameter was a clue I was missing. They make a lot more sense now, and I appreciate the insight.Unfortunately, the XPath you offered doesn't work because it points to the label, not the checkbox. Trying to combine it with `field\_labeled\_` didn't work. I could write an XPath query to locate the element just _before_ the label--but then I realized hyperlinks as the entirety of a label is a bad idea anyway, as you can't click on the label to check the box. So rethinking the whole idea. Still--thank you!
SFEley
A: 

Can you post what your HTML looks like in the rendered page near the problematic checkbox(es)? Sometimes you have to play with naming the field... I had all sorts of trouble with a login form... I ended up doing this:

<%= submit_tag 'Enter', {:id => "login_button"} %>

So that the following worked:

Given /^I am logged in as admin$/ do
    visit login_path
    fill_in "login", :with => "admin"
    fill_in "password", :with => "password"
#    click_button "login_button"
    click_button
end

I know it's not a checkbox example, but maybe fiddling with your name/id/etc will work

Jon Kern