Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test loading of image in Cypress

I want to test Cypress that an image is loaded into the page.

My source code looks like this:

import React from "react";

export default class Product extends React.Component {
  render() {
    return (
      <div className="item">
        <div className="image">
          <img src="../images/Banana-Snowboard.png" alt="Snow Board" />
        </div>
        <div className="middel aligned content">
          <div className="description">
            <a>Snow Board</a>
            <p>Cool Snow Board</p>
          </div>
          <div className="extra">
            <span>Submitted by:</span>
            <img
              className="ui avatar image"
              src="./images/avatar.png"
              alt="Avatar"
            />
          </div>
        </div>
      </div>
    );
  }
}

And my test is like this:

it("should display a image in element div with class image", () => {
  cy.get('div[class="image"]').find("img"); // some code that test that image is loaded so that it is displaye on the web page
});

it("shoul diplay a image in element div with class image inside class extra", () => {
  cy.get('div[class="extra"]').find('img[class="ui avatar image"]');
  //some code that check that image is loaded so that it is display the web page
});

How will that code look like?

like image 511
stein korsveien Avatar asked Jul 09 '18 13:07

stein korsveien


4 Answers

I have updated our recipe for static resource loading, see https://github.com/cypress-io/cypress-example-recipes/pull/363

To check if an image has finished loading, the simplest way is to check the image's naturalWidth or naturalHeight property.

// we can wait for the <img> element to appear
// but the image has not been loaded yet.
cy.get('[alt="delayed image"]')
.should('be.visible')
.and(($img) => {
  // "naturalWidth" and "naturalHeight" are set when the image loads
  expect($img[0].naturalWidth).to.be.greaterThan(0)
})

Alternatively, you can use performance entries to confirm that any static resource has finished loading, see the above pull request for the details.

like image 146
gleb bahmutov Avatar answered Sep 19 '22 11:09

gleb bahmutov


I use this chain of cypress to wait for all images that should load for the user, and not more (excluding invisble or not initialized images):

Get all images (including in shadow dom - https://docs.cypress.io/api/commands/get#Arguments)

cy.get('img', { includeShadowDom: true })

that have a src tag (css selector - https://docs.cypress.io/api/commands/filter)

.filter('[src]')

and are visible (jquery selector - https://docs.cypress.io/guides/references/assertions#Chai-jQuery)

.filter(':visible')

and are all loaded ("naturalWidth" and "naturalHeight" are set when the image loads)

.should(($imgs) => $imgs.map((i, img) => expect(img.naturalWidth).to.be.greaterThan(0)));

All in one:

cy.get('img', { includeShadowDom: true })
        .filter('[src]')
        .filter(':visible')
        .should(($imgs) => $imgs.map((i, /** @type {HTMLImageElement} */ img) => expect(img.naturalWidth).to.be.greaterThan(0)));

Thanks to others posts here and at other places.

like image 24
jehon Avatar answered Sep 16 '22 11:09

jehon


I like jehon's take. But in my case our team is not able to follow the best practice of having a dependable, static image set, so I don't want broken image urls to fail the test. This version of the code doesn't fail on missing images:

cy.get('img', { timeout: 10000, includeShadowDom: true })
  .filter(selector)
  .filter(':visible')
  .each((el) => {
    const url = el[0]?.src || el[0]?.srcset
    if (url)
      cy.request({ url: url, failOnStatusCode: false }).then((resp) => {
        if (resp.status == 200)
          cy.get(el).should((el) => {
            expect(el[0].naturalWidth).to.be.greaterThan(0)
          })
      })
  })
like image 37
MetaWhirledPeas Avatar answered Sep 20 '22 11:09

MetaWhirledPeas


What you're looking for is assertions, and in this case, should('be.visible') seems like it would fit the bill. https://docs.cypress.io/api/commands/should.html

it("should display a image in element div with class image", () => {
  cy.get('div[class="image"]').find("img").should('be.visible');
});
like image 39
sesamechicken Avatar answered Sep 17 '22 11:09

sesamechicken