Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find out which resources are not loaded successfully with Selenium

I have to test an application with Selenium. The application contains external content like ads. In my test I have several times a wait till the document is loaded. This looks like this:

private static final String DOCUMENT_READY_STATE_COMPLETE = "complete";

protected void waitUntilDocumentLoaded() {
    wait.until(input -> getDocumentReadyState().equals(DOCUMENT_READY_STATE_COMPLETE));
}

private String getDocumentReadyState() {
    return ((JavascriptExecutor) driver).executeScript("return document.readyState").toString();
}

It happens sometimes, that the browser is still loading some resource. As far as I understand I could sometimes accept if the readyState is interactive instead of complete. For example if some ads are not loaded in time, for my test is completely not interesting.

Is it possible somehow to get a list of resources with URLs which have not been loaded yet? Then I could build in an assertion, that checks which resources are mandatory for the test, and which are not.

I use Selenium Java WebDriver 2.53.1 with Firefox 46 under Linux.

like image 213
Gábor Lipták Avatar asked Jul 20 '16 09:07

Gábor Lipták


People also ask

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.

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.


3 Answers

So this is what I have made up myself. This can detect the images, which are not loaded. I used the really cool web services http://www.deelay.me and https://placekitten.com. So at least for images I have something.

<html>
<body>
<img src="http://deelay.me/1000/https://placekitten.com/g/500/500"/>
<img src="http://deelay.me/10000/https://placekitten.com/g/500/501"/>
<script>
function isImageOk(img) {
    //Function taken from http://stackoverflow.com/a/1977898/337621

    // During the onload event, IE correctly identifies any images that
    // weren’t downloaded as not complete. Others should too. Gecko-based
    // browsers act like NS4 in that they report this incorrectly.
    if (!img.complete) {
        return false;
    }

    // However, they do have two very useful properties: naturalWidth and
    // naturalHeight. These give the true size of the image. If it failed
    // to load, either of these should be zero.

    if (typeof img.naturalWidth !== "undefined" && img.naturalWidth === 0) {
        return false;
    }

    // No other way of checking: assume it’s ok.
    return true;
}


function checkState(){
    var documentState = document.readyState;
    if ( documentState != "complete") {
        console.log("Document is still having readystate " + documentState + ". Pending images: " );
        var images = document.getElementsByTagName("img");
        for(i = 0;i < images.length; i++)
        {
            if ( !isImageOk( images[i] ) ) {
                console.log("Image URL: " + images[i].src );
            }
        }
        setTimeout(checkState,500);
    }
    else {
        console.log("Document is loaded successfully.");
    }
}

checkState();

</script>
</body>
</html>

Console output:

Document is still having readystate loading. Pending images: 
Image URL: http://deelay.me/1000/https://placekitten.com/g/500/500
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/1000/https://placekitten.com/g/500/500
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/1000/https://placekitten.com/g/500/500
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/1000/https://placekitten.com/g/500/500
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/1000/https://placekitten.com/g/500/500
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/1000/https://placekitten.com/g/500/500
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is still having readystate interactive. Pending images: 
Image URL: http://deelay.me/10000/https://placekitten.com/g/500/501
Document is loaded successfully.
like image 105
Gábor Lipták Avatar answered Oct 25 '22 12:10

Gábor Lipták


I can share 3 approaches which can check the element is present or not. Hope by using this methods, you can get quell.

Approach#1:

/**
 * Checks if is element present or not.
 * 
 * @param element
 * @return true, if is element present, otherwise return false.
 * @throws Exception
 */
public boolean isElementPresent(WebElement element) throws Exception {
    try {
        waitForElement(element, Integer.valueOf(PropertyLoader
                .loadProperty("implicit_timeout_second")));
        return true;
    } catch (NoSuchElementException e) {
        return false;
    }
}

Approach#2:

/**
 * waits for element to be present.
 * 
 * @param element
 * @param timeOut
 *            The timeout in seconds when an expectation is called
 * @return
 */
public WebElement waitForElement(WebElement element, int timeOut) {
    WebDriverWait wait = new WebDriverWait(driverW, timeOut);
    wait.until(ExpectedConditions.elementToBeClickable(element));
    return element;
}

Approach#3:

/**
 * Waits for the element to be present BY.
 * 
 * @param dinamic
 *            element
 * @return true, if is element present, otherwise return false.
 * @throws Exception
 */
protected boolean waitForDynamicElementPresent(By by) throws IOException {
    try {
        WebDriverWait wait = new WebDriverWait(driverW,
                Integer.valueOf(PropertyLoader
                        .loadProperty("implicit_call_timeout_second")));
        wait.until(ExpectedConditions.elementToBeClickable(by));
        return true;
    } catch (NoSuchElementException e) {
        return false;
    }
}
like image 2
SkyWalker Avatar answered Oct 25 '22 10:10

SkyWalker


  1. Wait for specific elements to be present
  2. Sort of workaround is to use browsermob proxy or smthn similar, in case of browsermob there is a method that allows you to wait for network traffic to stop and wait for a certain amount of time to make sure that browser is not making any additional calls.
like image 1
Mikhail Avatar answered Oct 25 '22 11:10

Mikhail