Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Waiting for get requests to finish in selenium

For this example let's look at the site pinterest:

When i make the initial login, there is a loading of pins. In order to get more pins i need to scroll to the end of the page, after there is a request made for more pins (Lot's of sites are working like that i suppose)

So i know how to do the scroll in selenium, but how do i wait for the request to end?

I mean, it's not waiting for certain element to appear, the kind of element (The pins) is already there but i am waiting for others to appear.

If i use expected condition with wait, it good for the first batch of pins, but those that add to them, how do i wait for them, example:

When pinterest first load->

WebDriverWait driverWait = new WebDriverWait(cd, 10, 1000);

element = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("thepins")));

Which is great for the initial loading, now i scroll to the bottom of the page

((JavascriptExecutor) cd).executeScript("window.scrollTo(0, document.body.scrollHeight)");

Now depends on the page, there is a loading to more pins(And sometimes not) i want to wait for them to load before i do another scroll.

What is the best approach to this situation?

like image 669
totothegreat Avatar asked Sep 11 '18 13:09

totothegreat


People also ask

How wait till download is complete in Selenium?

There is no built-in to selenium way to wait for the download to be completed. The general idea here would be to wait until a file would appear in your "Downloads" directory.

How do I make Selenium wait 10 seconds?

We can make Selenium wait for 10 seconds. This can be done by using the Thread. sleep method. Here, the wait time (10 seconds) is passed as a parameter to the method.

What is the get () method used for in Selenium?

The get command launches a new browser and opens the given URL in your Webdriver. It simply takes the string as your specified URL and opens it for testing purposes. If you are using Selenium IDE, it is similar to open command.

How Can You Tell Selenium is waiting?

In order to declare explicit wait, one has to use “ExpectedConditions”. The following Expected Conditions can be used in Explicit Wait. To use Explicit Wait in test scripts, import the following packages into the script. Then, Initialize A Wait Object using WebDriverWait Class.


2 Answers

The way I would do it is using the number of elements on the page. So for example you could do:

int pinCount = webDriver.findElements(By.xpath("thepins")).size();

At this point run your jsExecutor for the scroll, then:

webDriverWait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath("thepins"),pinCount ));
like image 116
Jsmith2800 Avatar answered Sep 20 '22 11:09

Jsmith2800


I think the best way to handle this is by having class with all the possibilities, than you call it from where you need to wait and the code bellow will do the magic, works very well for me

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

public class Waiter {

    private static WebDriver jsWaitDriver;
    private static WebDriverWait jsWait;
    private static JavascriptExecutor jsExec;

    //Get the driver 
    public static void setDriver (WebDriver driver) {
        jsWaitDriver = driver;
        jsWait = new WebDriverWait(jsWaitDriver, 45);
        jsExec = (JavascriptExecutor) jsWaitDriver;
    }

    //Wait for JQuery Load
    public static void waitForJQueryLoad() {
        //Wait for jQuery to load
        ExpectedCondition<Boolean> jQueryLoad = driver -> ((Long) ((JavascriptExecutor) jsWaitDriver)
                .executeScript("return jQuery.active") == 0);

        //Get JQuery is Ready
        boolean jqueryReady = (Boolean) jsExec.executeScript("return jQuery.active==0");

        //Wait JQuery until it is Ready!
        if(!jqueryReady) {
            System.out.println("JQuery is NOT Ready!");
            //Wait for jQuery to load
            jsWait.until(jQueryLoad);
        } else {
            System.out.println("JQuery is Ready!");
        }
    }

    //Wait for Angular Load
    public static void waitForAngularLoad() {
        WebDriverWait wait = new WebDriverWait(jsWaitDriver,45);
        JavascriptExecutor jsExec = (JavascriptExecutor) jsWaitDriver;

        String angularReadyScript = "return angular.element(document).injector().get('$http').pendingRequests.length === 0";

        //Wait for ANGULAR to load
        ExpectedCondition<Boolean> angularLoad = driver -> Boolean.valueOf(((JavascriptExecutor) driver)
                .executeScript(angularReadyScript).toString());

        //Get Angular is Ready
        boolean angularReady = Boolean.valueOf(jsExec.executeScript(angularReadyScript).toString());

        //Wait ANGULAR until it is Ready!
        if(!angularReady) {
            System.out.println("ANGULAR is NOT Ready!");
            //Wait for Angular to load
            wait.until(angularLoad);
        } else {
            System.out.println("ANGULAR is Ready!");
        }
    }

    //Wait Until JS Ready
    public static void waitUntilJSReady() {
        WebDriverWait wait = new WebDriverWait(jsWaitDriver,45);
        JavascriptExecutor jsExec = (JavascriptExecutor) jsWaitDriver;

        //Wait for Javascript to load
        ExpectedCondition<Boolean> jsLoad = driver -> ((JavascriptExecutor) jsWaitDriver)
                .executeScript("return document.readyState").toString().equals("complete");

        //Get JS is Ready
        boolean jsReady =  (Boolean) jsExec.executeScript("return document.readyState").toString().equals("complete");

        //Wait Javascript until it is Ready!
        if(!jsReady) {
            System.out.println("JS in NOT Ready!");
            //Wait for Javascript to load
            wait.until(jsLoad);
        } else {
            System.out.println("JS is Ready!");
        }
    }

    //Wait Until JQuery and JS Ready
    public static void waitUntilJQueryReady() {
        JavascriptExecutor jsExec = (JavascriptExecutor) jsWaitDriver;

        //First check that JQuery is defined on the page. If it is, then wait AJAX
        Boolean jQueryDefined = (Boolean) jsExec.executeScript("return typeof jQuery != 'undefined'");
        if (jQueryDefined == true) {
            //Pre Wait for stability (Optional)
            sleep(30);

            //Wait JQuery Load
            waitForJQueryLoad();

            //Wait JS Load
            waitUntilJSReady();

            //Post Wait for stability (Optional)
            sleep(30);
        }  else {
            System.out.println("jQuery is not defined on this site!");
        }
    }

    //Wait Until Angular and JS Ready
    public static void waitUntilAngularReady() {
        JavascriptExecutor jsExec = (JavascriptExecutor) jsWaitDriver;

        //First check that ANGULAR is defined on the page. If it is, then wait ANGULAR
        Boolean angularUnDefined = (Boolean) jsExec.executeScript("return window.angular === undefined");
        if (!angularUnDefined) {
            Boolean angularInjectorUnDefined = (Boolean) jsExec.executeScript("return angular.element(document).injector() === undefined");
            if(!angularInjectorUnDefined) {
                //Pre Wait for stability (Optional)
                sleep(30);

                //Wait Angular Load
                waitForAngularLoad();

                //Wait JS Load
                waitUntilJSReady();

                //Post Wait for stability (Optional)
                sleep(30);
            } else {
                System.out.println("Angular injector is not defined on this site!");
            }
        }  else {
            System.out.println("Angular is not defined on this site!");
        }
    }

    //Wait Until JQuery Angular and JS is ready
    public static void waitJQueryAngular() {
        waitUntilJQueryReady();
        waitUntilAngularReady();
    }

    public static void sleep (Integer seconds) {
        long secondsLong = (long) seconds;
        try {
            Thread.sleep(secondsLong);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
like image 28
Philippe Avatar answered Sep 19 '22 11:09

Philippe