How do you test the Ajax app with Selenium and keep it stable?

Our team tested our application with Selenium, as it was heavily dependent on JavaScript, and we always had testing problems that sometimes did not work. As the number of tests increased, the likelihood that at least one of the two tests would fail in a full run became a confidence.

What we recently found out is that we probably have a race condition in which selenium will click links before initializing JavaScript to have the ability to attach event handlers to the element that is clicked. Of course, at this moment the effects that we are looking for do not happen, and we get a failed test.

Currently, we have added a slight delay before clicks to give the initialization time of the JavaScript code to complete, this is obviously a bit hacky, it adds time to the overall test execution and does not guarantee that the tests will not fail yet, so we are looking for the best solution.

The best idea we have come up with so far is to insert a hidden element in the DOM that Selenium can wait for before it fires a click event to know that it is ready. This will be a lot of additional overhead in terms of development time when we work on our asynchronous events by deleting and adding this element. He also adds additional materials to our pages, which are really not needed for the application.

Does anyone have any better strategies? What have you done to effectively solve this problem?

+4
source share
5 answers

I did exactly the same as you: add some delay and wait for some elements to appear on the page. And I am in perfect order. Maybe switching to Webdriver / selenium 2.0 will help. Test execution can be shortened if you work with a database in memory or share a single selenium / selenium server between tests or even with parallelization (for example, using TestNG).

+2
source

We switched to Selenium 2 (WebDriver) and use the Page Object Image using PageFactory / AjaxElementLocatorFactory - an example of this is here

+3
source

Have you tried the waitForElementPresent command and then click the button?

+1
source

To eliminate race conditions, use Selenium runScript(String initCondition) in combination with waitForCondition(String jsConditional, String timeout) methods.

For example, if the AJAX function you want to test causes the addition of a new element to dom, you can use something like the following.

 String jsPoll = ""; jsPoll += "selenium.browserbot.getCurrentWindow()"; jsPoll += ".document.getElementById('DOMID')"; selenium.waitForCondition(jsPoll, "30000"); 

The condition will evaluate to true when the item is added and the method continues. If your AJAX function changes elements (that is: one div for another similarly identified div), you can initialize your conditional code like this.

 String jsInit = ""; jsInit += "!selenium.browserbot.getCurrentWindow()"; jsInit += ".document.getElementById('DOMID').setAttribute('SELENIUMTEST','1')"; String jsPoll = ""; selenium.runScript(jsInit); jsPoll += "selenium.browserbot.getCurrentWindow()"; jsPoll += ".document.getElementById('DOMID').getAttribute('SELENIUMTEST') != 1"; selenium.waitForCondition(jsPoll, "30000"); 

The condition evaluates to true when the item is unloaded by the AJAX function.

+1
source

IMHO delays are not a good solution (only a workaround).

We use the iMacros image recognition feature to test complex AJAX (and Flash). For selenium, maybe you can combine it with AutoHotKey (which contains basic image search and is popular as a tool for testing desktop applications)? http://www.autohotkey.com/docs/commands/ImageSearch.htm

+1
source

All Articles