You have not described clearly what your website is meant to be doing. It’s possible to infer what it might be doing from some of what you said, but I would be as likely to hinder you as help you. Please, write out a clear paragraph describing how the site is meant to behave.
With that said, I’m guessing you don’t need the loop. Clicking TO_2 causes a page (or section of a page) to load wherein TO_1 resides. Once TO_1 is present then your test (not shown) is meant to proceed - correct?
Statements:
FailureHandling works.
waitFor* APIs work.
Your logic though is still under question.
Follow the advice I gave here, then perhaps we can help you:
Hi Russ,
My script previously is simple search which gives me list of the results (10 records per 1 page). There are 2 kind of results - highlighted in green and red, I need to search for first red record and click it to open details.
My loop firstly is checking first if red record is displayed on the list of results(TestObject_1’), if not it’s clicking next page button (TestObject_2) and it works if I use delay command. I would like to use wait command to check if TestObject_2 is displayed on the page (it’s displaying when new page finished loading) to save time of execution because sometimes red record is presenting on 10th page and loading each page with results takes from 10 to even 40 seconds.
I hope it’s more clear now.
Hi Robert,
I tried to reproduce your case. As far a I can see with your loading scenario, you can optimize your loop, because if your result is on the first page, you wait only 5 seconds, which might not be enought. And later, when you wait until your page is fully loaded, you again wait 5 seconds. Please see the following :
// wait for the first result page to be fully loaded
WebUI.waitForElementVisible(findTestObject(‘next’), 40, FailureHandling.OPTIONAL)
// search for your element with shorter failed timeout (as we already ensure page is loaded)
while (WebUI.verifyElementPresent(findTestObject(‘objetRecherche’), 1, FailureHandling.OPTIONAL) != true) {
// if not, click next
WebUI.click(findTestObject(‘next’))
// wait for the page to be fully loaded
WebUI.waitForElementVisible(findTestObject(‘next’), 40, FailureHandling.OPTIONAL)
// add this extra comment so your logs will look nicer (for the next check loop result)
WebUI.comment(‘next while’)
}
WebUI.click(findTestObject(‘objetRecherche’))
Also, please pay intention to the extra comment at the end of the while loop : this will help you debug your script.
Hi @Robert_C,
Try seting Default timeout in Project Setting to 40 seconds.
If you set 5 seconds in waitElementPresent() but 40 seconds for default timeout then it will be waited up to 5 seconds. However, if 5 seconds is set in waitElementPresent() but 1 second set for default timeout setting, it will be waited 1 second maximum
Sounds like you have a working solution, but just wanted to toss an idea to solve this more generically, as I’ve grappled with similar challenges. What it sounds like is happening is that most or all of your page has loaded, but there’s some AJAX going on in the background, and thus your web developer puts up a ‘spinner’ to prevent user interaction with the page until it’s complete.
This would explain why your wait conditions end after ~5 seconds, even though there’s a spinner. As far as the DOM is concerned, your elements are available and ready to be interacted with.
First, check if your page is jQuery enabled by executing the following in the browser console:
!!window.jQuery
If you get ‘true’, try using a custom wait condition like the following one:
I have quick doubt, Hope you don’t mind my ignorance …
a. How is it different from built in keyword WebUI.waitForJQueryLoad(10)
b. what does 300, 100 mean in new WebDriverWait(DriverFactory.getWebDriver(), 300, 100).
The jQuery.active property is a counter. Each time jQuery starts an asynchronous process, it increments the counter. Each time a process completes (regardless of a success status) it decrements the counter. The code is waiting for the the counter to reach zero, meaning, “it’s finished and ready”.
I don’t know the detail behind waitForJQueryLoad but it certainly doesn’t do what Brandon has given you.
So the 300 is the timeout in seconds (5 minutes) and the 100 is the polling frequency (aka the sleep time between checking the active jQuery count) in milliseconds.
Run up the website in a browser (by hand) and open the devtools console. Type:
jQuery.active
Type it again and again and again…
If the value displayed is always greater than 0, there is a bug in the application page. Tell the devlopers you found a bug making the page untestable.
If it does reach zero, then you used Brandon’s code incorrectly. It’s hard to say what you did wrong from here.
For a non-jQuery application, this will always return false. Thus if you call this for a non-jQuery application, it will wait all the way up to the given timeout.
You can remove the “!!window.jQuery” argument if you want, but if you then run this on a non-jQuery app, instead of waiting the full duration of the timeout, you will get an error:
org.openqa.selenium.WebDriverException: unknown error: Cannot read property 'active' of undefined