[英]Selenium Java image comparison
I am trying to compare two screen shots on a webpage.我正在尝试比较网页上的两个屏幕截图。 It is a practice page on saucelab.这是一个关于 saucelab 的练习页面。 When you login as a standart_user and click the login button, it takes you to the products page.当您以standart_user 身份登录并单击登录按钮时,它会将您带到产品页面。 Then you see the pictures of products.然后你会看到产品的图片。 (Backpacks, t-shirts etc.) (背包、T恤等)
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.我使用 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: 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().我通过使用 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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.