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.

5
  • possible duplicate of Find Broken Images Using Selenium IDE Commented Jun 27, 2015 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. Commented Jun 27, 2015 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. Commented Jun 28, 2015 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
    Commented Jun 29, 2015 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
    Commented Jul 16, 2015 at 17:33

3 Answers 3

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.

2
  • Steve, how to achieve the second method- the md5 one? Commented Jul 13, 2015 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. Commented Jul 13, 2015 at 11:28
2

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.

Edit: It could be done very easier.

driver.get("http://demo.tanmaysarkar.com/sample_04.html")

image1 = driver.find_element_by_xpath("//img[contains(@alt,'image two')]")

width = int(image1.get_attribute("naturalWidth"))
height = int(image1.get_attribute("naturalHeight"))

if width != 0 and height != 0:
    print("Image displayed")
else:
    print("Image not displayed")
1
  • 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. Commented Jul 13, 2015 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!

1
  • 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
    Commented Oct 4, 2019 at 11:44

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