How do I click on a specific button using cucumber/webrat when the name of the button starts with the same word?

zlog picture zlog · Jan 8, 2010 · Viewed 13k times · Source

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"?

Answer

Synthlabs picture Synthlabs · Jan 11, 2010

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