views:

621

answers:

1

I have the following html with multiple inputs:

<input type="submit" value="Save and close" name="commit"/>
<input type="submit" value="Save" name="commit"/>

and would like to use cucumber to test clicking on the "Save" button. However, when I do this in a cucumber test:

When I press "Save"

it clicks on the "Save and close" button, since it appears before the "Save" button.

Looking at the webrat source for finding the button:

def button_element
  button_elements.detect do |element|
    @value.nil?             ||
    matches_id?(element)    ||
    matches_value?(element) ||
    matches_html?(element)  ||
    matches_alt?(element)
  end
end

...

def matches_value?(element)
  element["value"] =~ /^\W*#{Regexp.escape(@value.to_s)}/i
end

...

it seems like webrat takes the first match, and only matches from the beginning of the content.

Is there any way of making an exact match, so cucumber finds "Save" and disregards "Save and close"?

+1  A: 

The click_button() method, which Cucumber uses for "When I press..." takes one of three parameters (text, name, id). You could simply differentiate the buttons using the id or name attribute to specify either.

<input type="submit" value="Save and close" name="commit" id="close_after_save"/>
<input type="submit" value="Save" name="commit" id="save"/>

Then say:

When I press "save"
When I press "close_after_save"

Alternatively, you could scope each button within a div.

<div id="save_and_close">
  <input type="submit" value="Save and close" name="commit"/>
</div>
<div id="save">
  <input type="submit" value="Save" name="commit" id="save"/>
</div>

Then you can scope the click_button() method:

When /^I press "([^\"]*)" within "([^\"]*)"$/ do |button,scope_selector|
  within(scope_selector) do      
    click_button(button)
  end
end
Synthlabs
Thanks. We ended using the id method. Thought there may have been another way.
zlog