I have a Nextjs project that is using Percy (with Cypress integration) to run visual tests. My project fetches images from a CMS. How can I make sure all images on the page have loaded before (taking the snapshot) or checking elements?
I have seen an example that checks for broken images
const brokenImages = []
cy.get('img')
.each(($el, k) => {
if ($el.prop('naturalWidth') === 0) {
const id = $el.attr('id')
const alt = $el.attr('alt')
const info = `${id ? '#' + id : ''} ${alt ? alt : ''}`
brokenImages.push(info)
cy.log(`Broken image ${k + 1}: ${info}`)
}
})
.then(() => {
// report all broken images at once
// enable the condition to see the thrown error
if (false && brokenImages.length) {
throw new Error(
`Found ${
brokenImages.length
} broken images\n${brokenImages.join(', ')}`,
)
}
})
and another one that checks a single image's natural width (which doesn't work in Nextjs
cy.get('#loads')
.should('be.visible')
.and('have.prop', 'naturalWidth')
.should('be.greaterThan', 0)
Am I going to have to just wait a set number of seconds and hope they have loaded?
The property
naturalWidthis native to javascript and should not be affected by the NextJs framework,i.e any
<img>on a running web page should return a non-zero naturalWidth property.However, the images may be lazy-loaded in which case
.scrollIntoView()may fix your problem.I ran this test on a selection of Nextjs sample pages and they all passed
Have the images loaded?
According to the examples by Gleb Bahmutov Cypress examples (v13.6.5) - Image Has Loaded (the source for your first code block)
Based on Gleb's code - adding a delay to the first image we can demo with simple before/after screenshots
HTML
Test
"Before" screenshot - img1 has not yet loaded
"After" screenshot - img1 has loaded