Some webpages implement a lazy loading design.
These kinds of pages basically load content only when the page is being scrolled to the point where the content is needed.
The Problem
To capture a full-page screenshot of a page, Eyes asks the page for its length and captures the page according to this length.
In pages that implement lazy loading, the length changes as the page is scrolled, due to more content loading.
As a result of this behavior, Eyes is capturing X pixels in length where the actual length of the page is X+Y and the resulted screenshot is shorter than it should be.
Another problem is that the screenshot is missing elements on the page in which their loading is triggered by scrolling.
The Solution
The solution is to make sure that the page is fully loaded with all of its content before taking the screenshot.
An easy way to do this is to scroll the page down to the bottom and then back up using Javascript execution.
There is more than one way to perform this and some ways work better than others.
One way to do this is to scroll the page directly to the footer by using the scrollIntoView() command.
This option does not always trigger the loading of all the content and might not be good enough.
A better solution is to scroll the page one screen at a time to make sure that all the content is being loaded.
Here is one example in C# and Python that implements this solution:
C#
public static void ScrollToTriggerLazyLoading(RemoteWebDriver driver)
{
long posA = 0;
long posB = 0;
long scrollPos = 0;
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
do
{
posA = (long)js.ExecuteScript("return window.scrollY;");
scrollPos += 300;
js.ExecuteScript("window.scrollTo(0, " + scrollPos + ");");
posB = (long)js.ExecuteScript("return window.scrollY;");
} while (posA != posB);
js.ExecuteScript("window.scrollTo(0, 0);");
Thread.Sleep(2000);
}
Python
posA = 0
posB = 1
scrollPos = 0
while posA != posB:
posA = driver.execute_script("return window.scrollY;")
scrollPos += 300
driver.execute_script("window.scrollTo(0, {});".format(scrollPos))
posB = driver.execute_script("return window.scrollY;")
driver.execute_script("window.scrollTo(0, 0);")
WDIO 5
const load_whole_page = async function(){
var previousScrollPosition = 0;
var currentScrollPosition = 0;
const scrollLength = Math.min(300,await browser.execute("return window.innerHeight;"));
var scrollPosition = 0;
do {
previousScrollPosition = currentScrollPosition;
scrollPosition = scrollPosition + scrollLength;
currentScrollPosition = await browser.execute("window.scrollTo(0, " + scrollPosition + ");");
await browser.pause(15);
currentScrollPosition = await parseInt(await browser.execute("return window.scrollY;"));
} while(previousScrollPosition!=currentScrollPosition);
};
Usage: await load_whole_page();