BackstopJS icon indicating copy to clipboard operation
BackstopJS copied to clipboard

Unable to capture screenshot of the page with all the images

Open mkarthik87 opened this issue 4 years ago • 5 comments

hi,

I tried to use img in the readySelector. But even though the images are not loaded the screenshots are taken.

How to wait until the whole page is loaded along with images and text.

2021-05-25_06-42-57-c9c5beed9d7cd096fc4802c9321953e3

Below is the backstop.json file { "id": "MAGNUM", "viewports": [ { "label": "tablet", "width": 1024, "height": 768 } ], "onBeforeScript": "puppet/onBefore.js", "onReadyScript": "puppet/onReady.js", "scenarios": [ {"label":"magnum-uk-home","url":"https://www.magnumicecream.com/uk/home.html","referenceUrl":"https://www.magnumicecream.com/uk/home.html", "delay": 10000, "expect": 0, "requireSameDimensions": true,"readySelector": "img", "clickSelector": ["button[class='o-btn--close js-btn-close js-content-panel-close']","#onetrust-reject-all-handler"] , "selectorExpansion": true, "readySelector": "", "readyEvent": "", "misMatchThreshold" : 0.1}], "paths": { "bitmaps_reference": "backstop_data/bitmaps_reference", "bitmaps_test": "backstop_data/bitmaps_test", "engine_scripts": "backstop_data/engine_scripts", "html_report": "backstop_data/html_report", "ci_report": "backstop_data/ci_report" }, "report": ["browser"], "engine": "puppeteer", "engineOptions": { "args": ["--no-sandbox"] }, "asyncCaptureLimit": 5, "asyncCompareLimit": 50, "debug": false, "debugWindow": false }

I have tried:

  1. adding delay
  2. using readySelector with img tag
  3. scrolling till bottom of the page

Note: https://www.magnumicecream.com/uk/home.html is the sample page.

mkarthik87 avatar Jun 07 '21 05:06 mkarthik87

Backstop already waits for images in static markup to be loaded. Maybe there is JavaScript on your page dynamically loading images?

garris avatar Jun 07 '21 15:06 garris

Yes. There are sections of the page which uses api to load Images or icons or data from other system. Is there a way this can be handled? I added delay property in json to 10 seconds or more but still the images were not captured correctly.

mkarthik87 avatar Jun 07 '21 16:06 mkarthik87

If your script is in charge of loading the images then your script can send an event to signal backstop that the page is ready for screenshot testing. That would be the best way to resolve this.

garris avatar Jun 08 '21 03:06 garris

This is image lazy loading related issue. Since your viewport height is 768px images bellow this point will not load because they are not in the view. As we see here with dimensions 768X1024 only first two images are in the view so the reason only they loaded. small

For website to request other images user has to scroll them into the view. requests

Probably there are better ways how to solve this, but this is how I went about it so far. I set viewport heigh to something really big so all images are in the view. Screenshot 2021-08-01 at 16 21 02

large

Then I use some inner wrapper selector like #wrapper to only capture the app portion of the view to exclude white space left at the bottom. Since all images are in the view during the test they all loaded as you can see in the test screenshot I made. Screenshot 2021-08-01 at 13 05 06

edvardsniedre avatar Aug 01 '21 12:08 edvardsniedre

This worked for me in Playwright:

engine_scripts/playwright/onReadyCustom.js

module.exports = async (
  page,
  scenario,
  viewport,
  isReference,
  browserContext
) => {
  console.log('SCENARIO > ' + scenario.label);
  await require('./clickAndHoverHelper')(page, scenario);
  await page.evaluate((scenario) => {
    /** force load lazy images */
    const lazyImages = document.querySelectorAll('img[loading="lazy"');
    lazyImages.forEach((i) => {
      i.removeAttribute('loading');
    });
  }, scenario);
};

dgrebb avatar Oct 27 '23 03:10 dgrebb