Over a million developers have joined DZone.

Selenium Mojo : A faster isVisible()

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

Several months ago a coworker and I were working on converting manual test cases into Selenium RC tests. We were running Selenium RC on IE 7 with singleBrowserMode set to false. In that situation Selenium uses two browsers: one that executes the JavaScript of your test and one that browsed to the website under test. The former is the parent of the later, and makes calls into its DOM to perform the steps of the tests.

As we were developing we started to realize that performance was degrading severely. Tests were hanging at certain steps for thirty to forty seconds.

After some investigation my coworker determined that the main culprit was the isVisible() method in the Selenium RC API. It was taking upwards of 4 or 5 seconds per execution.

Some online research yielded the root cause. Since Selenium is running the code of your test in a separate browser (presumably to avoid cross site scripting restrictions), each DOM operation is a round trip between the two windows. This is exceedingly slow if there is a lot of chatter between the windows.

Implementing an isVisible() method is more difficult than it looks because there is not good browser support (especially in IE) for finding the "computed style" of an element (the style of the element and all nonoverlapping styles from its entire string of ancestors.)

A quick peek into the Selenium source code showed that Selenium was using its bundled version of Prototype to traverse the DOM to find each parent of the element under consideration and examine their style attributes. All these round trips on a page with a huge DOM was causing the performance problem.

We circumvented this by implementing our own isVisible() method in native JavaScript and injecting it into the page using Selenium's setExtensionJs() method:

seleniumCustom = {};

seleniumCustom.isVisible = function(locator) {
var visible = true;

var element = selenium.browserbot.findElementOrNull(locator);
if (element == null) {
return false;

// Check if this is a hidden input element

if (element.type && element.type == "hidden") {
return false;

// Check this element and all parents for hidden style
while (element != null) {
if (element.currentStyle) {

if (element.currentStyle['display'] == 'none' ||
element.currentStyle['visibility'] == 'hidden') {
visible = false;

element = element.parentNode;

return visible;
Note: The above code is written in Groovy. Hence the multi line String.

Note: The setExtensionJs() method must be called before starting the selenium client.

Note: This version of isVisible() was written specifically for IE since that is all we are required to test against. A cross browser version would require more elaborate logic.

We had already subclassed the DefaultSelenium object in our test suite to implement several bug fixes and add some extended functionality. It was simple to then overwrite the isVisible() method with the following:
/** Overwritten with an alternate implementation to improve performance. */
public boolean isVisible(String locator) {
return getEval("selenic.isVisible(locator)").toBoolean()
This improved performance by roughly a factor of ten and reduced the test suite's run time by 20 to 30 percent.

This technique could be extended to other methods as well if you have a similar problem.

Acknowledgments: Kudos to Jesse Lentz for his detective working in figuring out that isVisible() was the problem and suggesting a solution!

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.


Published at DZone with permission of Scott Leberknight, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}