views:

1118

answers:

4

Has anyone been able to get the jQuery UI Dialog buttons to respond to click_button or selenium.click? I can't seem to be able to get this to work.

Basically, I'm trying to test a form in a jQuery UI Dialog in a Rails app using Cucumber/Webrat/Selenium.

I have a page with many table rows, and each row on click fires off a dialog box with a form. Each form element has a unique id so the markup is valid.

Since the buttons can be created dynamically by the Dialog plugin, I initialize the dialog to add a 'Save' and 'Cancel' button. Interestingly, the plugin inserts a button tag, not an input tag. I also add ids on open as shown below, so the buttons can be targeted by the testing framework.

$('.inventory_dialog').dialog({
  autoOpen: false,
  modal: true,
  buttons: {
    'Save': function() {
      // ajax submit stuff
    },
    Cancel: function() {
      // cancel stuff
    }
  },
  open: function() {
    // add ids to buttons for selenium
    var inventory_id = $(this).attr('id').split('_').pop();
    $('.ui-dialog-buttonpane')
      .find('button:contains("Save")').attr('id', 'inventory_'+inventory_id+'_save_button')
      .end()
      .find('button:contains("Cancel")').attr('id', 'inventory_'+inventory_id+'_cancel_button');
  }
});

The markup looks like:

<div id="inventory_dialog_392827" class="inventory_dialog">
  <form action="/suppliers/22/listings/27738/inventory/392827" class="edit_inventory" id="edit_inventory_392827" method="post"><div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /></div>
    <div class="input_block">
      <label for="inventory_392827_new_quantity">Quantity</label>
      <input id="inventory_392827_new_quantity" name="inventory[new_quantity]" type="text" value="10" />
    </div>
    <div class="input_block">
      <label for="inventory_392827_claim_quantities">Groups of</label>
      <input id="inventory_392827_claim_quantities" name="inventory[claim_quantities]" type="text" value="6-8" />
    </div>
  </form>
</div>

My Cucumber step (presently) looks like:

When /^I click the "(.+)" button in the inventory dialog$/ do |button_name|
  debugger
  selenium.click "//button[@id='inventory_#{@current_offer.id}_#{button_name.downcase}_button']"
  selenium_wait
end

When I run Cucumber and it hits 'debugger', I am able to manually 'selenium.click' in the input fields.

selenium.click "//input[@id='inventory_392827_new_quantity']"

This successfully puts a cursor in that field. However, clicking the button does not work:

selenium.click "//button[@id='inventory_392827_save_button']"

When I type that in the command line debugger, it returns nil (which I believe is success, since there is no exception), but Firefox doesn't do anything. The dialog box stays open in the browser. When I output response.body, that button is present.

I also tried

click_button "inventory_392827_save_button"

but the 'selenium_wait' command times out which means it doesn't see that element.

I'm stuck...

A: 

Does the problem go away if you change it to "fireEvent ... click" or to clickAt?

Patrick Lightbody
I haven't tried that yet (sorry), but it appears my problem is related to response.body spitting out multiple buttons with the same id, although in browser the ids are unique. I'm perplexed.
cotopaxi
A: 

It might be better to locate your button by another location strategy such as XPath or CSS. If you add the HTML of the button(s) then I'll try to give some suggestions.

If your target button has a class of 'submit' for example you could use:

css=input.submit

If the target button has a value of 'Click Me' you could use:

//input[@value='Click Me']

Another suggestion would be to use the id attribute without the unique number, so the following may work for you:

//input[substring(@id, string-length(@id) -11, 12) = '_save_button']
Dave Hunt
A: 

Did you find any solution for closing the jQuery dialog in Selenium?

Ola
Sorry for the super late response. I used a CSS selector based on a parent div's id to target the button. I never figured out why the selenium markup was generating the same ids for all the buttons.
cotopaxi
A: 

I had a similar problem, and here's how i got it done (using Capybara/Selenium/Factory_Girl).

The jQuery UI Dialog buttons generates this HTML, in my case with two buttons Add and Cancel:

<div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix">
 <button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" role="button" aria-disabled="false">
   <span class="ui-button-text">Add</span>
 </button>

 <button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" role="button" aria-disabled="false">
   <span class="ui-button-text">Cancel</span>
 </button>
</div>

But the click_button method doesn't work because the actual button name is a span nested inside the button tag, as you can see above.

So i wrote in the .feature step:

When I press the jquery dialog "Add" button

And i added this to my 'base.rb':

# jQuery Dialog buttons
When /^I press the jquery dialog "([^\"]*)" button$/ do |button_text|
  page.find("div.ui-dialog-buttonpane").find('span', :text => button_text).click
end
iuri