I am trying to compare two screen shots on a webpage. It is a practice page on saucelab. When you login as a standart_user and click the login button, it takes you to the products page. Then you see the pictures of products. (Backpacks, t-shirts etc.)
When you login as a problem_user, you see puppy pictures instead of products' picture. I want to screen shot the both pages and compare them. I took the shots by using WebdriverWait.
But the shots are taken before the pictures were loaded fully. What should I use to wait until the pictures on products page are fully loaded?
Below is my code.
public void waitElementVisibility(By visibleImage) {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(40));
wait.until(ExpectedConditions.visibilityOfElementLocated(visibleImage));
}
public void captureSuccesfulPageScreenShot() {
waitElementVisibility(visibleImage);
TakesScreenshot screenshot = (TakesScreenshot) driver;
File file = screenshot.getScreenshotAs(OutputType.FILE);
File path = new File("images/screenshot.png");
try {
FileUtils.copyFile(file, path);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void captureProblemUserScreenShot() {
waitElementVisibility(visibleImage);
TakesScreenshot screenshot = (TakesScreenshot) driver;
File file = screenshot.getScreenshotAs(OutputType.FILE);
File path = new File("images/problemUserScrSh.png");
try {
FileUtils.copyFile(file, path);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
I've managed to create a wait method, but it fails on fifth image. Performing the render check take some time and I'm unable to simulate slow rendering.
Code:
package tests;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import javax.imageio.ImageIO;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Saucedemo {
public static void main(String[] args) {
WebDriver driver = startChromeDriver();
driver.get("https://www.saucedemo.com/");
logIn(driver, "standard_user");
List<WebElement> inventoryContainerImages = inventoryContainerImages(driver);
waitForRenderingImages(driver, inventoryContainerImages, 4);
saveScreenShotAs(driver, "standard_user");
logOut(driver);
logIn(driver, "problem_user");
inventoryContainerImages = inventoryContainerImages(driver);
waitForRenderingImages(driver, inventoryContainerImages, 4);
saveScreenShotAs(driver, "problem_user");
logOut(driver);
driver.quit();
}
public static WebDriver startChromeDriver() {
String chromedriverPath = System.getProperty("user.dir") + "\\resources\\chromedriver.exe";
System.setProperty("webdriver.chrome.driver", chromedriverPath);
ChromeOptions options = new ChromeOptions();
options.addArguments("--ignore-certificate-errors");
options.addArguments("--start-maximized");
options.addArguments("--disable-notifications");
WebDriver driver = new ChromeDriver(options);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
return driver;
}
public static void logIn(WebDriver driver, String userName) {
System.out.println("Login as user: " + userName);
driver.findElement(By.id("user-name")).sendKeys(userName);
driver.findElement(By.id("password")).sendKeys("secret_sauce");
driver.findElement(By.id("login-button")).click();
}
public static void saveScreenShotAs(WebDriver driver, String fileName) {
TakesScreenshot screenshot = (TakesScreenshot) driver;
File file = screenshot.getScreenshotAs(OutputType.FILE);
File path = new File(fileName + ".png");
try {
FileUtils.copyFile(file, path);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void logOut(WebDriver driver) {
System.out.println("Logout");
driver.findElement(By.id("react-burger-menu-btn")).click();
driver.findElement(By.id("logout_sidebar_link")).click();
}
public static BufferedImage getBufferedImageOfElement(WebDriver driver, WebElement element) {
BufferedImage elementImage = null;
BufferedImage fullImage = null;
TakesScreenshot screenshot = (TakesScreenshot) driver;
File file = screenshot.getScreenshotAs(OutputType.FILE);
try {
fullImage = ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
}
Point point = element.getLocation();
int width = element.getSize().getWidth();
int height = element.getSize().getHeight();
elementImage = fullImage.getSubimage(point.getX(), point.getY(), width, height);
return elementImage;
}
public static BufferedImage getBufferedImageFromUrl(String imgSrc) {
BufferedImage image = null;
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) new URL(imgSrc).openConnection();
connection.connect();
image = ImageIO.read(connection.getInputStream());
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
public static Boolean imagesAreEqual(BufferedImage source, BufferedImage target) {
Boolean samePixelColors = true;
int sourceWidth = source.getWidth();
int sourceHeight = source.getHeight();
BufferedImage resizedTarget = resizeBufferedImage(source, sourceWidth, sourceHeight);
for (int x = 0; x < sourceWidth; x++) {
for (int y = 0; y < sourceHeight; y++) {
int sourceRgb = source.getRGB(x, y);
int resizedTargetRgb = resizedTarget.getRGB(x, y);
if (sourceRgb != resizedTargetRgb) {
samePixelColors = false;
break;
}
}
}
if (samePixelColors) {
return true;
}
else {
return false;
}
}
public static Boolean elementsImageEqualSrcImage(WebDriver driver, WebElement element) {
BufferedImage imageOfElement = getBufferedImageOfElement(driver, element);
String src = element.getAttribute("src");
BufferedImage imageFromUrl = getBufferedImageFromUrl(src);
return imagesAreEqual(imageFromUrl, imageOfElement);
}
public static void waitForRenderingImages(WebDriver driver, List<WebElement> images, int maxImages) {
int maxIndex = maxImages - 1;
if (maxIndex <= images.size()) {
WebDriverWait wait10s = new WebDriverWait(driver, 10);
for (int i = 0; i <= maxIndex; i++) {
WebElement image = images.get(i);
if (!elementsImageEqualSrcImage(driver, image)) {
System.out.println("Image " + (i + 1) + " of " + images.size() + " not equal with its URL source, waiting 100 ms.");
wait10s.until(new Function<WebDriver, Boolean> () {
public Boolean apply(WebDriver driver) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
return elementsImageEqualSrcImage(driver, image);
}
});
}
else {
System.out.println("Image " + (i + 1) + " of " + images.size() + " equal with its URL source, no waiting.");
}
}
}
else {
System.out.println("Error - argument maxImames is greater than images.size()");
}
}
public static List<WebElement> inventoryContainerImages(WebDriver driver) {
WebElement inventoryContainer = driver.findElement(By.id("inventory_container"));
return inventoryContainer.findElements(By.tagName("img"));
}
public static BufferedImage resizeBufferedImage(BufferedImage sourceImage, int width, int height) {
Image image = sourceImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = resizedImage.createGraphics();
g2d.drawImage(image, 0, 0, null);
g2d.dispose();
return resizedImage;
}
}
Output:
Starting ChromeDriver 104.0.5112.79 (3cf3e8c8a07d104b9e1260c910efb8f383285dc5-refs/branch-heads/5112@{#1307}) on port 22424
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully.
Srp 29, 2022 2:12:39 ODP. org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
Login as user: standard_user
Image 1 of 6 equal with its URL source, no waiting.
Image 2 of 6 equal with its URL source, no waiting.
Image 3 of 6 equal with its URL source, no waiting.
Image 4 of 6 equal with its URL source, no waiting.
Logout
Login as user: problem_user
Image 1 of 6 equal with its URL source, no waiting.
Image 2 of 6 equal with its URL source, no waiting.
Image 3 of 6 equal with its URL source, no waiting.
Image 4 of 6 equal with its URL source, no waiting.
Logout
I solved my problem by using Thread.sleep(). I also updated my methods so I don't have duplicated lines.
private void sleep(int milliSecond) {
try {
Thread.sleep(milliSecond);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.