Q: When is a button not a button?
A: When it is a YUI button
Selenium, at its core, deals with HTML things stored in the DOM. And does a pretty good job at it. But things start to get confusing when the people creating the page start to get fancy and use third-party widgets like those provided by YUI. This post is about how to fake your way through Se automation when you encounter YUI controls, specifically a YUI Button.
The big thing to understand is that YUI buttons are not buttons (to the browser), they are in fact just blobs of JS that happen to look like a button. When you ‘click’ on one, a callback is fired to execute another bit of JS to make it look like you click did something. Ahhh, AJAXy goodness.
But because there is nothing happening at the DOM level, we need to simulate both the ‘click’ and the subsequent action. For example, here is a helper function I wrote to deal with a ‘checkbox’ type YUI button for a client.
def enable_bubbles(se): if se.is_element_present("//span[@id='PinBalloonSelector']"): se.get_eval("window.ShowBalloonButton.set('checked', true)") se.get_eval("window.PersistBalloonPinMode()") se.wait_for_condition("selenium.isElementPresent(\"//div[@id='balloonContentDiv']/div\")", "60000")
Important things to note:
- YUI buttons are children of the window object so start your hunt there
- To ‘click’ the box on you set the attribute ‘checked’ to true. Setting to false ‘unclicks’ it
- After the click you need to call the JS function that would normally be triggered as we’re sneaking operations in under-the-hood
- Because all of this is happening in JS, you need to use the get_eval variant that your binding provides
That took me well over a day to figure out, so I figure someone else has likely run into issues where Se-IDE has recorded a button interaction one way but on playback or export it didn’t work because the button isn’t an HTML button, it is a YUI button.
So who wants to write a plugin for Se-IDE that deals with YUI controls properly? :)