karthick kumar
karthick kumar

Reputation: 3031

Wait for page load in Selenium

How do you make Selenium 2.0 wait for the page to load?

Upvotes: 302

Views: 636951

Answers (30)

pAulseperformance
pAulseperformance

Reputation: 389

Man all these answers require too much code. This should be a simple thing as its pretty common.

Why not just inject some simple Javascript with the webdriver and check. This is the method I use in my webscraper class. The Javascript is pretty basic even if you don't know it.

def js_get_page_state(self):
"""
Javascript for getting document.readyState
:return: Pages state. See doc link below.
"""
ready_state = self.driver.execute_script('return document.readyState')
if ready_state == 'loading':
    self.logger.info("Loading Page...")
elif ready_state == 'interactive':
    self.logger.info("Page is interactive")
elif ready_state == 'complete':
    self.logger.info("The page is fully loaded!")
return ready_state

More Info in "Document.readyState" of MDN Web Docs: https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState

Upvotes: 10

Artem
Artem

Reputation: 2421

Use class WebDriverWait

Also see here

You can expect to show some element. something like in C#:

WebDriver _driver = new WebDriver();
WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 1, 0));

_wait.Until(d => d.FindElement(By.Id("Id_Your_UIElement")));

Upvotes: 102

BelovedFool
BelovedFool

Reputation: 445

Here is a Java 8 version of the currently most upvoted answer:

WebDriverWait wait = new WebDriverWait(myDriver, Duration.ofSeconds(15));
wait.until(webDriver -> "complete".equals(((JavascriptExecutor) webDriver)
    .executeScript("return document.readyState")));
    

Where myDriver is a WebDriver object (declared earlier).

Note: Be aware that this method (document.readyState) only checks the DOM.

Upvotes: 17

anirus
anirus

Reputation: 1657

You can explicitly wait for an element to show up on the webpage before you can take any action (like element.click()):

driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
    .until(new ExpectedCondition<WebElement>() {
        @Override
        public WebElement apply(WebDriver d) {
            return d.findElement(By.id("myDynamicElement"));
        }
    }
);

This is what I used for a similar scenario and it works fine.

Upvotes: 3

Arpan Saini
Arpan Saini

Reputation: 5247

You can use the below existing method to set the pageLoadTimeout. In below example if the page is taking more than 20 seconds to load, then it will throw an exception of page reload:

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS);

Upvotes: 4

sidanmor
sidanmor

Reputation: 5189

NodeJS Solution:

In Nodejs you can get it via promises...

If you write this code, you can be sure that the page is fully loaded when you get to the then...

driver.get('www.sidanmor.com').then(()=> {
    // here the page is fully loaded!!!
    // do your stuff...
}).catch(console.log.bind(console));

If you write this code, you will navigate, and selenium will wait 3 seconds...

driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...

From Selenium Documentation (Nodejs):

this.get( url ) → Thenable<undefined>

Schedules a command to navigate to the given URL.

Returns a promise that will be resolved when the document has finished loading.

Upvotes: 4

MTK
MTK

Reputation: 81

For Programmers using java 8 onward can use below code to wait for page load using explicit wait.

JavascriptExecutor js = (JavascriptExecutor) driver;  
new WebDriverWait(driver, 10).until(webDriver ->
(js).executeScript("return document.readyState;").equals("complete"));

Note: In my above code Lambda Expression is used, which is only available in java 8 onward version.

For Programmers using lower version of Java i.e. below Java 8 can use:

ExpectedCondition<Boolean> cond = new ExpectedCondition<Boolean>() {
    @Override
    public Boolean apply(WebDriver input) {
        JavascriptExecutor js = (JavascriptExecutor) driver; 
        return js.executeScript("return document.readyState;").equals("complete");
            }
        };
         
    new WebDriverWait(driver, 100).until(cond);

Upvotes: 1

Shubham Jain
Shubham Jain

Reputation: 17593

Call below Function in your script , this will wait till page is not loaded using javascript

public static boolean isloadComplete(WebDriver driver)
{
    return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
            || ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}

Upvotes: 4

Praveen
Praveen

Reputation: 41

In my case , I used the following to know the page load status. In our application loading gif(s) are present and, I listen to them as follows to eliminate unwanted wait time in the script.

public static void processing(){ 
    WebDriverWait wait = new WebDriverWait(driver, 30);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
    wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
}

Where the xpath locates the gif in the HTML DOM. After this, You may also implement your action methods Click.

public static void click(WebElement elementToBeClicked){
    WebDriverWait wait = new WebDriverWait(driver, 45);
    wait.until(ExpectedConditions.visibilityOf(element));
    wait.until(ExpectedConditions.elementToBeClickable(element)); 
    wait.ignoring(NoSuchElementException.class).ignoring(StaleElementReferenceException.class); elementToBeClicked.click(); 
 }

Upvotes: 2

Salman Arshad
Salman Arshad

Reputation: 59

For implicit wait you can use something like following:

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS)

In order for webpage to wait for a specific object to be visible or cerntain condition to be true. You can use wait feather of web driver.

//120 is maximum number of seconds to wait.
WebDriverWait wait = new WebDriverWait(driver,120);  
wait.until(ExpectedConditions.elementToBeClickable("CONDITITON"));

In Java, another option is to sleep the thread for specific time.

Thread.sleep(numberOfSeconds*1000); 
//This line will cause thread to sleep for seconds as variable

I created a method to simplify thread.sleep method

public static void wait_time(int seconds){
    try {
        Thread.sleep(seconds*1000);
        }catch (InterruptedException e) {
        // TODO Auto-generated catch block
            e.printStackTrace();
        }
}

Use the method as wait_time(10); The thread will sleep for 10 seconds.

Upvotes: 0

Anuj Teotia
Anuj Teotia

Reputation: 1323

Explicitly wait or conditional wait in this wait until given this condition.

WebDriverWait wait = new WebDriverWait(wb, 60);
wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));

This will wait for every web element for 60 seconds.

Use implicitly wait for wait of every element on page till that given time.

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

This will wait for every web element for 60 seconds.

Upvotes: 8

Prasobh.Kollattu
Prasobh.Kollattu

Reputation: 1701

private static void checkPageIsReady(WebDriver driver) {
    JavascriptExecutor js = (JavascriptExecutor) driver;

    // Initially bellow given if condition will check ready state of page.
    if (js.executeScript("return document.readyState").toString().equals("complete")) {
        System.out.println("Page Is loaded.");
        return;
    }

    // This loop will rotate for 25 times to check If page Is ready after
    // every 1 second.
    // You can replace your value with 25 If you wants to Increase or
    // decrease wait time.
    for (int i = 0; i < 25; i++) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        // To check page ready state.
        if (js.executeScript("return document.readyState").toString().equals("complete")) {
            break;
        }
    }
}

Upvotes: 0

Neel Gurbani
Neel Gurbani

Reputation: 13

use following code it's very easy and simple for page load.

public void PageLoad(IWebDriver driver, By by)
{
    try
    {
        Console.WriteLine("PageLoad" + by);
        WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
        wait.Until(ExpectedConditions.ElementIsVisible(by));
        wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30)); // 30 seconds wait until element not found. 
        wait.Until(ExpectedConditions.ElementToBeClickable(by));


    }
    catch (Exception ex)
    {

        Console.WriteLine(ex.Message);
        Assert.Fail("Element not found!")
    }
}

i hope this helps you.

Upvotes: 0

IKo
IKo

Reputation: 5816

If someone uses selenide:

public static final Long SHORT_WAIT = 5000L; // 5 seconds
$("some_css_selector").waitUntil(Condition.appear, SHORT_WAIT);

More Conditions can be found here: http://selenide.org/javadoc/3.0/com/codeborne/selenide/Condition.html

Upvotes: 2

iamsankalp89
iamsankalp89

Reputation: 4749

You can use wait. there are basically 2 types of wait in selenium

  • Implicit wait
  • Explicit wait

- Implicit wait

This is very simple please see syntax below:

driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

- Explicit wait

Explicitly wait or conditional wait in this wait until given condition is occurred.

WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

You can use other properties like visblityOf(), visblityOfElement()

Upvotes: 2

yuwanlin
yuwanlin

Reputation: 65

I use node + selenium-webdriver(which version is 3.5.0 now). what I do for this is:

var webdriver = require('selenium-webdriver'),
    driver = new webdriver.Builder().forBrowser('chrome').build();
;
driver.wait(driver.executeScript("return document.readyState").then(state => {
  return state === 'complete';
}))

Upvotes: 2

Ak8511
Ak8511

Reputation: 1

In python, you can simply use:

driver.implicitly_wait(30)

Upvotes: -4

rahul yadav
rahul yadav

Reputation: 1

This code will wait until all the elements on the page are loaded in the DOM.

WebDriver driver = new WebDriver();
WebDriverWait wait = new WebDriverWait(driver, timeout);

wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*")));

Upvotes: -4

Firas Al-Barghouthi
Firas Al-Barghouthi

Reputation: 21

public static int counter = 0;

public void stepGeneralWait() {

    boolean breakIt = true;

    while (true) {
        breakIt = true;
        try {

            do{
                // here put e.g. your spinner ID
                Controller.driver.findElement(By.xpath("//*[@id='static']/div[8]/img")).click();
                Thread.sleep(10000);

                counter++;

                if (counter > 3){
                    breakIt = false;

                }
            }
            while (breakIt);



        } catch (Exception e) {
            if (e.getMessage().contains("element is not attached")) {
                breakIt = false;
            }
        }
        if (breakIt) {
            break;
        }

    }

    try {
        Thread.sleep(12000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

Upvotes: 0

forresthopkinsa
forresthopkinsa

Reputation: 1467

The best way I've seen is to utilize the stalenessOf ExpectedCondition, to wait for the old page to become stale.

Example:

WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);

WebElement oldHtml = driver.findElement(By.tagName("html"));
wait.until(ExpectedConditions.stalenessOf(oldHtml));

It'll wait for ten seconds for the old HTML tag to become stale, and then throw an exception if it doesn't happen.

Upvotes: 2

Mohsin Awan
Mohsin Awan

Reputation: 1172

You can use this snippet of code for the page to load:

    IWait wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver,TimeSpan.FromSeconds(30.00));
    wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));

Or you can use waiter for any element to be loaded and become visible/clickable on that page, most probably which is going to be load at the end of loading like:

    Wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath(xpathOfElement));
    var element = GlobalDriver.FindElement(By.XPath(xpathOfElement));
    var isSucceededed = element != null;

Upvotes: 2

ANarula
ANarula

Reputation: 11

You can try this code to let the page load completely until element is found.

public void waitForBrowserToLoadCompletely() {
    String state = null;
    String oldstate = null;
    try {
        System.out.print("Waiting for browser loading to complete");

        int i = 0;
        while (i < 5) {
            Thread.sleep(1000);
            state = ((JavascriptExecutor) driver).executeScript("return document.readyState;").toString();
            System.out.print("." + Character.toUpperCase(state.charAt(0)) + ".");
            if (state.equals("interactive") || state.equals("loading"))
                break;
            /*
             * If browser in 'complete' state since last X seconds. Return.
             */

            if (i == 1 && state.equals("complete")) {
                System.out.println();
                return;
            }
            i++;
        }
        i = 0;
        oldstate = null;
        Thread.sleep(2000);

        /*
         * Now wait for state to become complete
         */
        while (true) {
            state = ((JavascriptExecutor) driver).executeScript("return document.readyState;").toString();
            System.out.print("." + state.charAt(0) + ".");
            if (state.equals("complete"))
                break;

            if (state.equals(oldstate))
                i++;
            else
                i = 0;
            /*
             * If browser state is same (loading/interactive) since last 60
             * secs. Refresh the page.
             */
            if (i == 15 && state.equals("loading")) {
                System.out.println("\nBrowser in " + state + " state since last 60 secs. So refreshing browser.");
                driver.navigate().refresh();
                System.out.print("Waiting for browser loading to complete");
                i = 0;
            } else if (i == 6 && state.equals("interactive")) {
                System.out.println(
                        "\nBrowser in " + state + " state since last 30 secs. So starting with execution.");
                return;
            }

            Thread.sleep(4000);
            oldstate = state;

        }
        System.out.println();

    } catch (InterruptedException ie) {
        ie.printStackTrace();
    }
}

Upvotes: 1

Gulraiz Aslam
Gulraiz Aslam

Reputation: 1

There are 2 types of waits available in Webdriver/Selenium 2 software testing tool. One of them is Implicit wait and another one is explicit wait. Both (Implicit wait and explicit wait) are useful for waiting in WebDriver. Using waits, we are telling WebDriver to wait for a certain amount of time before going to next step.You can use implicit wait for page load waiting.

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

Upvotes: -2

iam_muqshid
iam_muqshid

Reputation: 37

use a if condition and for any of the element present

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Upvotes: -1

Vinod Kumar K V
Vinod Kumar K V

Reputation: 121

  1. WebDriver driver = new ff / chrome / anyDriverYouWish(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); Waits maximum of 10 Seconds.

  2. WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.visibilityOf(WebElement element));

  3. FluentWait<Driver> fluentWait; fluentWait = new FluentWait<>(driver).withTimeout(30, TimeUnit.SECONDS) .pollingEvery(200, TimeUnit.MILLISECONDS) .ignoring(NoSuchElementException.class);

The advantage of the last option is that you can include exception to be expected, so that your execution continues.

Upvotes: 0

Kuldeep Yadav
Kuldeep Yadav

Reputation: 107

Use implicitly wait for wait of every element on page till given time.

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

this wait for every element on page for 30 sec.

Another wait is Explicitly wait or conditional wait in this wait until given condition.

WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

In id give static element id which is diffidently display on the page, as soon as page is load.

Upvotes: 5

sonhu
sonhu

Reputation: 961

The best way to wait for page loads when using the Java bindings for WebDriver is to use the Page Object design pattern with PageFactory. This allows you to utilize the AjaxElementLocatorFactory which to put it simply acts as a global wait for all of your elements. It has limitations on elements such as drop-boxes or complex javascript transitions but it will drastically reduce the amount of code needed and speed up test times. A good example can be found in this blogpost. Basic understanding of Core Java is assumed.

http://startingwithseleniumwebdriver.blogspot.ro/2015/02/wait-in-page-factory.html

Upvotes: 4

Manavendher
Manavendher

Reputation: 395

Use this function

public void waitForPageLoad(ChromeDriver d){
        String s="";
        while(!s.equals("complete")){
        s=(String) d.executeScript("return document.readyState");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }

    }

Upvotes: -1

Vaibhav
Vaibhav

Reputation: 2556

Implicit and explicit wait is better.

But if you are handling an exception in Java, then you can use this for waiting for a page to reload:

Thead.sleep(1000);

Upvotes: -6

Fin
Fin

Reputation: 183

Imran's answer rehashed for Java 7:

    WebDriverWait wait = new WebDriverWait(driver, 30);

    wait.until(new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver wdriver) {
            return ((JavascriptExecutor) driver).executeScript(
                "return document.readyState"
            ).equals("complete");
        }
    });

Upvotes: 12

Related Questions