On a rails application I was building last year, we had chosen to use prototype for some ajax features. We were using selenium to test the application. Previously it was common that any time we interacted with the page via a click, or a select, we'd follow it up with a wait_for_page_to_load command. This would ensure that selenium (or rather the driver we were using), would only send the next command to selenium once the page we were interested in was completely loaded.
On an Ajax application (or on an Ajax feature of a web site), this never happens. Small sections of the page might update. It's still necessary to wait until this process is complete before interacting with sections of the page where content or controls are yet to be rendered. A simple sleep or wait is a bad idea. These ajax calls rarely take exactly the same time to perform an operation every time. If the wait period is too short, you'll have random test failures since a control you want to interact with is missing. If the period is too long, your tests take too long since you end up waiting, very often, far longer than you need to.
The recommended approach is to use one of the selenium wait_for's. There's a wait_for_element_present I believe, which for some reason I cannot find in the rc driver at the moment. Anyway, that function waits till a particular element shows up on the page. The other option is wait_for_condition, which takes a javascript function and waits till it evaluates as true. See here.
The annoying thing about this approach though, was that there's a big advantage in having a generic "wait_for" statement that can be used anywhere, that just waits till any Ajax calls are done. You could write custom wait_fors each time that are relevant to the particular test you are writing. But I see a generic solution being useful in a variety of conditions. For example
wait_for_condition("selenium.browserbot.getCurrentWindow().Ajax.activeRequestCount == 0",timeout)
There's another solution that I know of. Twist apparently supports a proxy injection mode, where all your requests are routed through a proxy. This is interrogated by the test runner which is now always aware that whenever there is an active request, ajax or otherwise. This allows implicit waits. This is probably the cleanest solution that I know about. I've never actually used it though and so if you aren't using twist, if proxy injection mode isn't possible for some technical reason, or if this is likely to make the tests slower then the previous solution is a better idea.
In a follow up post Ill actually use an example and demonstrate how to use this wait_for_condition to write a generic ajax wait with prototype or jquery or even a custom rolled javascript framework.
On an Ajax application (or on an Ajax feature of a web site), this never happens. Small sections of the page might update. It's still necessary to wait until this process is complete before interacting with sections of the page where content or controls are yet to be rendered. A simple sleep or wait is a bad idea. These ajax calls rarely take exactly the same time to perform an operation every time. If the wait period is too short, you'll have random test failures since a control you want to interact with is missing. If the period is too long, your tests take too long since you end up waiting, very often, far longer than you need to.
The recommended approach is to use one of the selenium wait_for's. There's a wait_for_element_present I believe, which for some reason I cannot find in the rc driver at the moment. Anyway, that function waits till a particular element shows up on the page. The other option is wait_for_condition, which takes a javascript function and waits till it evaluates as true. See here.
The annoying thing about this approach though, was that there's a big advantage in having a generic "wait_for" statement that can be used anywhere, that just waits till any Ajax calls are done. You could write custom wait_fors each time that are relevant to the particular test you are writing. But I see a generic solution being useful in a variety of conditions. For example
- you have a certain element where all that changes is content. This allows you to differentiate between a failure because a call was not completed and a failure because of an actual bug.
- you have certain wizard style flows which you have to navigate through in multiple tests and you'd rather not worry about exactly what must have changed after every step.
- You fire multiple ajax calls on some interaction and you need to wait for all of them to complete ideally.
wait_for_condition("selenium.browserbot.getCurrentWindow().Ajax.activeRequestCount == 0",timeout)
There's another solution that I know of. Twist apparently supports a proxy injection mode, where all your requests are routed through a proxy. This is interrogated by the test runner which is now always aware that whenever there is an active request, ajax or otherwise. This allows implicit waits. This is probably the cleanest solution that I know about. I've never actually used it though and so if you aren't using twist, if proxy injection mode isn't possible for some technical reason, or if this is likely to make the tests slower then the previous solution is a better idea.
In a follow up post Ill actually use an example and demonstrate how to use this wait_for_condition to write a generic ajax wait with prototype or jquery or even a custom rolled javascript framework.
Thanks to Reggino, this is the required piece of code for Jquery
`selenium.browserbot.getUserWindow().$.active == 0`
making all ajax calls sync in test is another approach, an advantage of this approach is that all javascript exceptions are catchable from your testing code.
ReplyDeletehttp://www.markhneedham.com/blog/2009/05/14/selenium-waiting-for-jquery-ajax-calls/
ReplyDeleteand
http://www.luning.name/logs/39397928.html
are some similar discussions.
"wait_for_element_present" (or waitForElementPresent in Java) is, ahem, present, in the core/ide API, but not in RC's.
ReplyDeleteIn RC, the idiom is to call "is_element_present" in a loop. There's been some debate for adding "wait_for_element_present" directly in the RC API, though, for the specific reason that that the API differences cause confusion. :-)
Excellent post, and thank you for writing this up. Getting proper waits/blocking in place for ajax apps is a frequently asked question among Selenium users.
- Jason Huggins
creator: selenium
twitter: @jhuggins
thanks luning. I was planning to cover jquery too, but looks like atleast in that case the solution is known :)
ReplyDeletethanks Jason
ReplyDeleteI was wondering if it was possible for to use user extensions to actually extend the xmlhttp request object. To come up with a generic solution that works across ajax frameworks. Without using the proxy injection mode. I don't know if that makes sense just yet though =p
Thnx for the info. A small sidenote: I had to use
ReplyDeleteselenium.browserbot.getUserWindow().$.active == 0
to get stuff working for Jquery / Selenium IDE 1.0.7 Firefox plugin
I can not see the data in an unordered list. I tried using XPath expression and identifiers, but selenium can not find them. Any advice would be greatly appreciated. Thanks!
ReplyDeleteDubturbo
Vishnu,
ReplyDeleteJust a small correction. Twist includes Selenium 0.9.2 as a driver. ( We do recommend Sahi for web testing though ).
We've made enhancements to Selenium to take care of these things ( including , but not limited to , waitForPageToLoad and waitForAjaxRequest API's )
We also have implicit wait support.
Hey Manish, this thing is more than a year old =p. Btw what modifications have you made to waitForAjaxRequest? How does it work? And is it independent of any js frameworks?
ReplyDeleteI must confess that in the past all my AJAX pages have been tested with pause, not only because of the limitations of selenium, but also because it gave me a way to see what happens when time standby server.
ReplyDeleteHi,
ReplyDeleteI am struggling to fix this problem i have selenium IDE generated code
//div[@id='ext-gen25']/div[10]/table/tbody/tr/td[2]
In this ext-gen25 is dynamically changed to ext-gen29, ext-gen45 for each run. How can i use XPATH to locate this each time correctly.
Thanks,
Basham
what you need are xpath functions
ReplyDeletehttp://www.w3schools.com/xpath/xpath_functions.asp
so instead of testing id equality, test some condition on id
Well Said, you have furnished the right information that will be useful to anyone at all time. Thanks for sharing your Ideas.
ReplyDeleteSalesforce Training in Chennai | Salesforce Training Institute in Chennai
Great efforts put it to find the list of articles useful for Selenium, Definitely will share the same to other forums.
ReplyDeleteWe are also one of the best sources to learn Selnium -Selenium training in Chennai |Best Selenium training institute in Chennai
Thank you a lot for providing individuals with a very spectacular possibility to read critical reviews from this site.
ReplyDeleteselenium training in bangalore|
Great post!
ReplyDeleteThanks for sharing this list!
It helps me a lot finding a relevant blog in my niche!
Java Training in Chennai
Java Training in Coimbatore
Java Training in Bangalore
I have been reading all your blogs regularly..I admit, this is one of the best blogs I have read till date. Great going.. Waiting for the next...
ReplyDeleteSpoken English Classes in Chennai
Spoken English in Chennai
Top 10 Spoken English Classes in Chennai
Best IELTS Coaching in Chennai
IELTS Coaching Centre in Chennai
English Classes in Mumbai
English Speaking Classes in Mumbai
Best IELTS Coaching in Mumbai
IELTS Coaching in Mumbai
Spoken English Class in Anna Nagar
ReplyDeleteThis post is so interactive and informative. Thanks for sharing this great blog keep update more information
Data Science Course in Chennai
Data Science Training in Chennai
Data Science Courses in Bangalore
Data science course in coimbatore
Best data science courses in bangalore
Data science institute in bangalore
Data Science Training Institutes in Bangalore
Ethical hacking course in bangalore
Great experience for me by reading this blog. Thank you for wonderful article.
ReplyDeleteAngularjs Training in Chennai
Angularjs Training in Bangalore
angularjs training institute in bangalore
Angular 2 Training in Chennai
best angularjs training in bangalore
Angularjs course in Chennai
dot net training institutes in bangalore
php course in coimbatore
Great Article
ReplyDeleteData Mining Projects
Python Training in Chennai
Project Centers in Chennai
Python Training in Chennai
Thanks for this wonderful blog. keep update more information about this
ReplyDeleteEthical Hacking Course in Chennai
Hacking Course in Chennai
Ethical hacking course in bangalore
Ethical hacking course in coimbatore
Ethical Hacking Training in Chennai
Certified Ethical Hacking Course in Chennai
Ethical Hacking Training Institute in Chennai
Ethical hacking Training institute in bangalore
Software Testing Training in Chennai
ielts coaching centre in coimbatore
Thanks for sharing such an amazing blog! Kindly update more information
ReplyDeleteGerman Classes in Chennai
German Classes in Bangalore
German Classes in Coimbatore
German Classes in Madurai
German Language Course in Hyderabad
German language classes in bangalore
German language course in bangalore
German courses in bangalore
Selenium Training in Bangalore
Software Testing Course in Bangalore
ReplyDeletesan diego seo expert
seo company in india
Informative article on responsive website design!!! With the expansion of mobile phones, most of us access internet from our mobile and other portable gadgets. Having responsive website for your business will help you to target customers widely.
ReplyDeleteCyber Security Training Course in Chennai | Certification | Cyber Security Online Training Course | Ethical Hacking Training Course in Chennai | Certification | Ethical Hacking Online Training Course | CCNA Training Course in Chennai | Certification | CCNA Online Training Course | RPA Robotic Process Automation Training Course in Chennai | Certification | RPA Training Course Chennai | SEO Training in Chennai | Certification | SEO Online Training Course
Great information. The above content is very interesting to read. This will be loved by all age groups.
ReplyDeletedigital marketing executive interview questions and answers for freshers
50 important networking interview questions answers
As a Microsoft program, Visio not only uses the same ribbon-style layout as Word, Excel, and PowerPoint, but it’s fully integrated with these programs as well.Click Here
ReplyDeleteAnyToISO Professional 3.9.8 Crack is an ISO file format converter software. It's straightforward software, and it works very well. AnytoISO Download Full Version Free Mac
ReplyDeleteThanks for sharing this information. I really like your blog post. Enhance your English language skills with top-notch online tuition in Bahrain. Ziyyara Edutech’s experienced English language tutor in Bahrain offers the best personalized tutors.
ReplyDeleteFor more info visit English language tutor in bahrain
Awesome Blog!!! Thanks for it, it is more useful for us. Are you a Class 12 student grappling with doubts in accountancy subjects like Profit and Loss, Journal Entry, Financial Ratios and more.
ReplyDeleteBook A Free Demo Today visit Private tuition classes for class 12