2

I have read that there is no "sure shot" way of knowing that an image is loaded or displayed on a webpage using Selenium. I want to know the reason behind it, as to why this is completely not possible.

I tried three different kinds of checks and I see they all return the incorrect result, i.e. even if the image is broken, the result returns true.

  • Using JavaScript Executor

    driver.get('http://demo.tanmaysarkar.com/sample_04.html')
    
    image1 = driver.find_element_by_xpath("//img[contains(@alt,'image two')]")
    
    bool(driver.execute_script("return arguments[0].complete && typeof arguments[0].naturalWidth != \"undefined\" && arguments[0].naturalWidth > 0", image1))
    
    if not bool:
        print('d')
    
    else:
        print('c')
    

This returns 'c' for image two on the given webpage, which should not be the case.

  • Using size attribute

    if image1.size != 0 :
        print("good")
    else:
        print('food')
    

Again returns 'good', which I'm not expecting it to do. And finally, being captain obvious:

  • Using is_displayed( ) method

    if image1.is_displayed():
        print('foo')
    
    else:
        print('fii')
    

prints 'foo', which again is not expected.

I'm curious to know what else I can to do a sort of assert truly if the image is shown or not.

Can checking for a 404 error code help here? I am taking this from this example that I came upon - Broken Images check

Any help/suggestion/explanation would be appreciated.

  • possible duplicate of Find Broken Images Using Selenium IDE – Niels van Reijmersdal Jun 27 '15 at 19:29
  • Duplicate of sqa.stackexchange.com/questions/11876/… , broken images are still images you need to get the src of the image and check the HttpResponse statuscode value to see if the image is valid. – Niels van Reijmersdal Jun 27 '15 at 19:30
  • I haven't tried the httpresponse suggestion mentioned but the getatrribute thing only works for firefox i think. for example the image in question here had the same 350×350 pix resolution returned in Chrome while the same test yielded a different result in firefox. – demouser123 Jun 28 '15 at 15:26
  • its difficult to suggest without seeing the page you are looking at but maybe its easier to perform an AssertFalse (with JUnit or TestNG) on the image failing to display correctly. Often the failure is easier to define than the success. – ECiurleo Jun 29 '15 at 15:51
  • We tend not to close good questions as duplicates of closed questions. That being said, I'm not sure the proposed duplicate is actually deserving of being closed. Have to review that. @NielsvanReijmersdal – corsiKa Jul 16 '15 at 17:33
2

If you are testing for a specific image at a specific resolution then you could either compare the image with the reference image or quicker calculate the MD5 of the image and compare it with the expected.

Be sure and wait for the page to be loaded, including images, before validation.

  • Steve, how to achieve the second method- the md5 one? – demouser123 Jul 13 '15 at 8:19
  • @geeko_zac - I personally would use the python hashlib library to calculate the respective MD5s, but there are libraries for just about any language, store the expected MD5 as part of my test data and calculate the downloaded image MD5 to do a simple check it is equal to the expected. – Steve Barnes Jul 13 '15 at 11:28
1

I hope below given points may help you strong to see how this can be done:

Find a web page which contains a broken image. Or you can create in your local system. Open your class file and write a code to locate an image such as below.
You can use different image attributes(Eg. alt, name etc.) to locate image using XPath.

 WebElement ImageFile = driver.findElement(By.xpath("//img[contains(@id,'Test Image')]"));

Write a JavaScript executor code to verify if image is present in page. It can be done as shown in below code.

 Boolean ImagePresent = (Boolean) ((JavascriptExecutor)driver).executeScript("return arguments[0].complete && typeof arguments[0].naturalWidth != \"undefined\" && arguments[0].naturalWidth > 0", ImageFile);

Write a code to print desired output as per image presence state.

if (!imageLoaded1) {
System.out.println("Image not displayed.");
} 

else {
System.out.println("Image displayed.");

}

Done. Your method should look like below after performing above steps.

@Test
public void CheckImage() throws Exception {
driver.get(baseUrl);
WebElement ImageFile = driver.findElement(By.xpath("//img[contains(@id,'Test Image')]"));

    Boolean ImagePresent = (Boolean) ((JavascriptExecutor)driver).executeScript("return arguments[0].complete && typeof arguments[0].naturalWidth != \"undefined\" && arguments[0].naturalWidth > 0", ImageFile);
    if (!ImagePresent)
    {
         System.out.println("Image not displayed.");
    }
    else
    {
        System.out.println("Image displayed.");
    }
}

Run your test. It should identify if image is displayed in web page and will print appropriate result in console.

  • I have mentioned this that this method is not working. If you try this for Chrome, this test fails many time, because though the image is not getting displayed, the image looks like to be taking that specified image on the browser screen. – demouser123 Jul 13 '15 at 8:18
0

Just in case the earlier solution using the JavascriptExecutor does not work, use;

        try {
            boolean imagePresent = (Boolean) ((JavascriptExecutor) driver).executeScript("return (typeof arguments[0].naturalWidth !=\"undefined\" && arguments[0].naturalWidth > 0);", Source);

            if (!imagePresent) {
                System.out.println("Image is NOT Displayed");
            }
            else {
                System.out.println("Image is Displayed");
            }
        }
        catch (Exception ex) {
            System.out.println("Unable to locate Element " + Arrays.toString(ex.getStackTrace()));
        }

Hope this was helpful. Up-vote if this works out fine!

  • You could make this answer much better by explaining how it would improve the other solutions to the question - if you edit your answer to say what difference typeof makes and why you'd wrap the call in a try/catch block that would help - without that, your answer looks so much like the other JavascriptExecutor answer code that people may mistake it for the same code. – Kate Paulk Oct 4 at 11:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.