10

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 this error. I don't know of an externally visible page that will.):

Selenium browser = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com");
browser.start();
browser.open("http://www.google.com/webhp?hl=en");
browser.type("q", "hello world");

When the error occurs, the call to 'open' times out, even though you can clearly see that the page has loaded successfully before the timeout occurs. Increasing the timeout does not help. The call to 'type' never occurs, no progress is made.

How do you get selenium to recognize that the page has loaded when this error occurs?

Matthew Jaskula
  • 1,266
  • 1
  • 16
  • 16

9 Answers9

2

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);
   }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Prabu Ananthakrishnan
  • 4,139
  • 1
  • 12
  • 16
2

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.

1

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.

Jim Deville
  • 10,632
  • 1
  • 37
  • 47
1

Using 'openAndWait' in place of 'open' will do the trick.

From the website:

Many Actions can be called with the "AndWait" suffix, e.g. "clickAndWait". This suffix tells Selenium that the action will cause the browser to make a call to the server, and that Selenium should wait for a new page to load.

Lawrence
  • 537
  • 3
  • 3
  • 1
    The question is about the Selenium RC API, which doesn't support the "AndWait" part. That's in Selenium IDE only. – Ross Patterson Aug 26 '11 at 11:57
  • Agreed, this is not a useful answer. Not only are the "...AndWait" methods not available in the Java API, but the whole problem here is that Selenium is not correctly detecting when the page has finished loading. Using those methods wouldn't help anyway. http://release.seleniumhq.org/selenium-core/0.8.0/reference.html#waitForPageToLoad – Hovis Biddle May 09 '12 at 15:23
0

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.

dav
  • 8,931
  • 15
  • 76
  • 140
0

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");
}
perror
  • 7,071
  • 16
  • 58
  • 85
someman
  • 19
  • `findElement()` will throw an exception if the footer element is not found. You will not get the 60 tries you've tried to program there. – Alexander Feb 06 '14 at 10:19
0

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
}
someman
  • 19
0

Enabling the 'multiWindow' feature solved the issue, though I am not clear why.

SeleniumServer(int port, boolean slowResources, boolean multiWindow)

SeleniumServer server = new SeleniumServer(4444, false, true);

Any clarification would be helpful.

Matthew Jaskula
  • 1,266
  • 1
  • 16
  • 16
0

I've run into similar issues when using Selenium to test an application with iFrames. Basically, it seemed that once the primary page (the page containing the iframes) was loaded, Selenium was unable to determine when the iframe content had finished loading.

From looking at the source for the link you're trying to load, it looks like there's some Javascript that's creating additional page elements once the page has loaded. I can't be sure, but it's possible that this is what's causing the problem since it seems similar to the situation that I've encountered above.

Do you get the same sort of errors loading a static page? (ie, something with straight html)

If you're unable to get a better answer, try the selenium forums, they're usually quite active and the Selenium devs do respond to good questions.

http://clearspace.openqa.org/community/selenium_remote_control

Also, if you haven't already tried it, add a call to browser.WaitForPageToLoad("15000") after the call to open. I've found that doing this after every page transition makes my tests a little more solid, even though it shouldn't technically be required. (When Selenium detects that the page actually has loaded, it continues, so the actual timeout variable isn't really a concern..

Peter Bernier
  • 8,038
  • 6
  • 38
  • 53