In certain unknown situations selenium does not detect that a page has loaded when using the open method. I am using the Java API. For example (This code will not produce th
I faced this problem quite recently.
All JS-based solutions didn't quite fit ICEFaces 2.x + Selenium 2.x/Webdriver combination I have.
What I did and what worked for me is the following:
In the corner of the screen, there's connection activity indicator.
<ice:outputConnectionStatus id="connectStat"
showPopupOnDisconnect="true"/>
In my Java unit test, I wait until its 'idle' image comes back again:
private void waitForAjax() throws InterruptedException {
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try {
if ("visibility: visible;".equals(
selenium.getAttribute("top_right_form:connectStat:connection-idle@style"))) {
break;
}
} catch (Exception e) {
}
Thread.sleep(1000);
}
}
You can disable rendering of this indicator in production build, if showing it at the page is unnecessary, or use empty 1x1 gifs as its images.
Works 100% (with popups, pushed messages etc.) and relieves you from the hell of specifying waitForElement(...) for each element separately.
Hope this helps someone.
another idea is to modify AJAX API (to add some text after AJAX actions). After ajax action was finished, before return, set invisible field to TRUE, selenium will find it and read as green-light
in html:
<input type='hidden' id="greenlight">
in selenium
if(driver.findElement(By.id("greenlight")).getAttr("value").equals("TRUE")){
// do something after page loading
}
When I do Selenium testing, I wait to see if a certain element is visible (waitForVisible), then I do my action. I usually try to use an element after the one I'm typing in.
Not a perfect solution, but I am using this method
$t1 = time(); // current timestamp
$this->selenium->waitForPageToLoad(30);
$t2 = time();
if ($t2 - $t1 >= 28) {
// page was not loaded
}
So, it is kind of checking if the page was not loaded during the specified time, so it is not loaded.
If you page has no AJAX, try to seek footer of page (I also use Junit fail("")
, you may use System.err.println()
instead):
element.click();
int timeout =120;
// one loop = 0.5 sec, co it will be one minute
WebElement myFooter = null;
for(int i=0; i<timeout; i++){
myFooter = driver.findElement(By.id("footer"));
if(myFooter!= null){
break;
}
else{
timeout--;
}
}
if(timeout==0 && myFooter == null){
fail("ERROR! PAGE TIMEOUT");
}
Maybe this will help you....
Consider the following method is in page called Functions.java
public static void waitForPageLoaded(WebDriver driver) {
ExpectedCondition<Boolean> expectation = new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
}
};
WebDriverWait wait = new WebDriverWait(driver,30);
try {
wait.until(expectation);
} catch(Throwable error) {
Assert.assertFalse(true, "Timeout waiting for Page Load Request to complete.");
}
}
And you can call this method into your function. Since it is a static method, you can directly call with the class name.
public class Test(){
WebDriver driver;
@Test
public void testing(){
driver = new FirefoxDriver();
driver.get("http://www.gmail.com");
Functions.waitForPageLoaded(driver);
}
}