I’m using watir-webdriver to interact with radio buttons in Firefox that are styled as a jQuery buttonset.
<label for="radioButtonSet">Radio Buttons</label>
<div id="radioButtonSet">
<input type="radio" id="radio1" name="radio"/><label for="radio1">Choice 1</label>
<input type="radio" id="radio2" name="radio"/><label for="radio2">Choice 2</label>
<input type="radio" id="radio3" name="radio"/><label for="radio3">Choice 3</label>
</div>
The relevant js:
$(function() {
$( "#radioButtonSet" ).buttonset();
});
Now, what this turns into is actually a hidden set of radio buttons, each with a <label> that’s got listeners on it to interact with the corresponding radio button. Hacky but ehh. Anyway, I want to make my Cucumber step definitions to appear ‘agnostic’ with regards to whether we’re dealing with a basic (unstyled) set of radio buttons, or a jQuery buttonset. The step of interest is as follows:
When /^I click on the (.+ button)$/ do |button|
get_on_page(@current_page,button).click
end
I’m using page object models, so get_on_page is defined as…
def get_on_page (page_object, element_on_page)
page_object.send(element_on_page.downcase.gsub(" ","_"))
end
In the interest of full disclosure, because I wanted steps like “and the middle radio button is selected” to likewise be jQuery agnostic, I’ve extended Watir::Label so that I can use it to check if whatever button it’s for happens to be checked.
class Watir::Label
attr_accessor :for, :browser
#For cases where the label is a "skin" over a checkbox or radio button.
#Finds the checkbox or radio button that this Label is for and interrogates it.
#Requires that @browser is set to the current active browser instance
def checked?
@input = @browser.checkbox(:id => self.for)
if (not @input.exists?) then
@input = @browser.radio(:id => self.for)
end
@input.checked?
end
end
Anyway, in irb (command line) everything works as expected. See here:
irb(main):370:0> @middle_radio_button = @browser.label(:for => "radio2")
=> #<Watir::Label:0x5b6635c2 located=false selector={:for=>"radio2", :tag_name=>"label"}>
irb(main):371:0> @middle_radio_button.browser = @browser
=> #<Watir::Browser:0x..fb560d81a url="file:///C:/Users/dsharkov/git/html-template/ShowCase.html" title="Showcase">
irb(main):372:0> @middle_radio_button.for = "radio2"
=> "radio2"
irb(main):373:0> @middle_radio_button.click
=> []
irb(main):374:0> @middle_radio_button.checked?
=> true
I can click the <label> and then see whether its radio button is checked. And yes I’ve visually confirmed on the active browser window that the label gets clicked and all that fun stuff.
So, here’s the problem. I CAN NOT get this to work as expected when I am running my Cucumber features! Here’s the scenario:
Scenario: radio buttons styled as jQuery toggle buttons
Given I am on the Showcase page
And I click on the middle radio button
Then the middle radio button is selected
And the left radio button is not selected
The other step definition of interest is the “is selected” one, I guess, so here’s that:
Then /^the (.+) is (not )?(?:checked|selected)$/ do |checkbox_or_radio,not_checked|
@checkbox = get_on_page(@current_page,checkbox_or_radio)
if (not_checked == "not ") then
@checkbox.checked?.should_not be_true
else
@checkbox.checked?.should be_true
end
end
Here’s what I get:
Scenario: radio buttons styled as jQuery toggle buttons # features\accessing_common_elements.feature:54
Given I am on the Showcase page # features/step_definitions/common_steps.rb:3
And I click on the middle radio button # features/step_definitions/common_steps.rb:19
Then the middle radio button is selected # features/step_definitions/common_steps.rb:85
expected false to be true (RSpec::Expectations::ExpectationNotMetError)
./features/step_definitions/common_steps.rb:90:in `/^the (.+) is (not )?(?:checked|selected)$/'
features\accessing_common_elements.feature:57:in `Then the middle radio button is selected'
And the left radio button is not selected # features/step_definitions/common_steps.rb:85
This makes me sad. I have visually confirmed that all that happens to the buttonset is the button I’m interested in clicking simply gets highlighted as if it’s being hovered over, which looks different.
And here’s what makes me even more sad — when I change my step definition to this:
When /^I click on the (.+ button)$/ do |button|
get_on_page(@current_page,button).click
get_on_page(@current_page,button).click
end
Everything is happy and green. That is not cool! Clicking twice is not the same as clicking once, nor is it the same as doubleclicking, so I am really confused about this. What may be the underlying issue here? This would be a little easier to comprehend if I weren’t seeing it work “correctly” through irb. I also don’t think it’s a race condition because I’ve added a Watir::Wait.until{...} after the single click and that merely timed out.
Any insight would be appreciated.
The “solution” to this ended up being changing the step definition that was used for clicking on a button.
Original:
New and improved:
As Chuck mentions above in the comments, a
.clickwill result in multiple events firing, but what’s of interest in this case is really what happens in response to an “onclick” event, so this rewrite is sufficient. At least for the purposes of this situation.