garris / BackstopJS

Catch CSS curve balls.
http://backstopjs.org
MIT License
6.79k stars 604 forks source link

Unable to capture screenshot of the page with all the images #1330

Open mkarthik87 opened 3 years ago

mkarthik87 commented 3 years ago

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.

garris commented 3 years ago

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

mkarthik87 commented 3 years ago

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.

garris commented 3 years ago

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.

edvardsniedre commented 3 years ago

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
dgrebb commented 1 year ago

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);
};