Hello Readers, Welcome Back !!

As the first part of this Selenium Tips series, this article intends to summarize the different ways to interact with dynamic sites that refresh content asynchronously wherein the script will have to wait for certain elements to appear or disappear before proceeding further. As you are already aware of, Selenium has several ‘waitFor’ commands that fulfill this purpose. waitForCondition is one among them. ‘waitForCondition’ basically takes in two arguments, a JavaScript snippet and a timeout period in milliseconds. The snippet is executed either until it returns true or until the timeout period, after which the command will return an error. Now enough of theory and let’s get into action.

Example:
Variation 1:
Consider the following example where there are two drop-downs, one for the states and the other for counties.
The county drop-down is populated based on the state selection.
(Example courtesy of bitrepository.com)

You can see in the site above, when the state is selected, a spinner shows up for a few seconds before the county drop-down is populated. Using waitForCondition and some JavaScript, we wait until display style attribute changes to ‘none’ in the snippet below.

selenium.open(“http://www.bitrepository.com/apps/viewDemo/?originalPost=http://www.bitrepository.com/dynamic-dependant-dropdown-list-us-states-counties.html&demoPage=http://www.bitrepository.com/demo/dynamic-dependent-dropdown-list/”);
selenium.selectFrame(“mainFrame”);
selenium.select(“state”, “label=California”);
selenium.waitForCondition(“var value = selenium.browserbot.findElementOrNull(‘loading_county_drop_down’); value.style.display == ‘none’”, “10000″);
selenium.select(“county”, “label=Amador County”);

Variation 2:
You may also use logical operators to add additional logic.

selenium.waitForCondition(“var value = selenium.browserbot.findElementOrNull(‘loading_county_drop_down’); value.style.display == ‘none’ || selenium.browserbot.getUserWindow().document.form.county.options[0].text == ‘Select a county of California’;”, “10000″);

Variation 3:
The same can also be accomplished by simply using waitForNotVisible and/or waitForSelectOptions.

selenium.waitForNotVisible(“loading_county_drop_down”);
selenium.waitForSelectOptions(“county”,”regexpi:Amador County”);

You may wonder why you need to go into the trouble of using complex JavaScript with waitForCondition while you can accomplish the same with one of the other selenium waitFor commands. The additional advantage of using waitForCondition is that you are able to declare a timeout value explicitly whereas the other waitFor commands simply honor the default selenium timeout value.

Other useful variations:
You may have seen many AJAX intensive sites displaying a ‘Loading..’ or ‘Saving..’ or ‘Processing…’ message when a button or a link is clicked. In such cases you may find this to be helpful to wait for the status text to change or disappear.

Assuming that a ‘Saving’ message is displayed within a div tag when a fictional ‘Save’ button is clicked in the snippet below:

selenium.waitForCondition(“var value = selenium.getText(”//div[@class='save-text']”);value != ”Saving””, “20000″);

In general, .Net sites that use the web form controls, panel controls etc, trigger an asynchronous postback everytime a form control is filled or a .Net tab or panel control is clicked etc. In such cases, I’ve found the following to be very helpful in waiting for the postback to complete.

selenium.waitForCondition(“selenium.browserbot.getUserWindow().Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack() == false;”, “10000″);

Now for the killer part, for sites that use jQuery, if all you need is to confirm there aren’t any active asynchronous requests, then the following does the trick:

selenium.waitForCondition(“selenium.browserbot.getUserWindow().$.active == 0″, “10000″);

As you can see, there are several possible variations to a single command. The possibilities are endless with Selenium.

Happy Testing !!