在UI自动化测试中,我们经常做的是在执行脚本出错时,会在出错的时候进行截图,然后通过截图对比脚本来分析出错原因,如果点击了某个元素后,页面跳转错误,点击元素之前在截图中标记被点击的元素,就可以提高分析原因的效率,基于这样的考虑,开发了一个在截图中标记被点击元素的方法。
1、截图基本方法
使用的时候,传入的参数可以去掉,根据自己的框架设定参数。
package **.utils;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.aspectj.util.FileUtil;
import org.openqa.selenium.OutputType;
public class GetScreenShot extends IDriver {
public static String getScreenShot(String taskId, String deviceId) {
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
String date = df.format(new Date()).toString();
String fileName = date + ".png";
try {
IDriver.wait(1);
driver.getScreenshotAs(OutputType.BYTES);
File screen = driver.getScreenshotAs(OutputType.FILE);
String filePath = "/Users/autotest/mtp_workspace/business/pic/" + taskId + "/" + deviceId;
fileName = filePath + "/" + fileName;
File screenFile = new File(fileName);
FileUtil.copyFile(screen, screenFile);
} catch (IOException e) {
e.printStackTrace();
}
return fileName;
}
}
2、在截图中标记被点击的元素
传入的参数filePath是上面截图方法返回的截图路径,被点击元素的x、y坐标以及宽度和高度,这里把元素属性x、y以及宽度高度乘以3,是因为默认的截图的分辨率扩大了3倍,这个值根据自己的截图方法进行修改。
ImageIO.write(bufferedImage, “png”, new FileOutputStream(filePath));这个方法是覆盖了之前filePath的截图,如果想生成新的截图,传入新的路径即可。
package *.utils;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.log4j.Logger;
public class DealPic {
private static Logger logger = Logger.getLogger(DealPic.class);
public static void getImage(String filePath, int x, int y, int width, int height) {
File file = new File(filePath);
// 截图中点击的元素用红色框标记
try {
BufferedImage bufferedImage = ImageIO.read(file);
Graphics2D graphics2d = (Graphics2D) bufferedImage.getGraphics();
graphics2d.setColor(Color.RED);
graphics2d.setStroke(new BasicStroke(13));
graphics2d.drawRect(x * 3, y * 3, width * 3, height * 3);
ImageIO.write(bufferedImage, "png", new FileOutputStream(filePath));
} catch (IOException e) {
logger.error("Get screen shot failed!");
e.printStackTrace();
}
}
}
如何获取被点击元素的x、y、宽度和高度呢?
其实很简单,Selenium封装了这样一个方法方便获取,在RectAngle对象中
public static boolean tap(String locator) {
boolean flag = false;
try {
WebElement element = driver.findElement(By.xpath(locator));
Rectangle rectangle = element.getRect();
int x = rectangle.x;
int y = rectangle.y;
int width = rectangle.width;
int height = rectangle.height;
String picName = GetScreenShot.getScreenShot(Crawler.taskId, Crawler.deviceId);
DealPic.getImage(picName, x, y, width, height);
NodeList.picList.add(picName);
element.click();
flag = true;
} catch (Exception e) {
logger.error(locator + " not found, ignoired");
}
return flag;
}
这个方法是在点击元素之前,获取该元素的属性值,然后进行截图再标记被点击元素,当然,如果该元素找不到或者元素定位错误,这个方法是不会生效的,既然找不到该元素,也就没有截图以及标记的必要了,后面的处理也就是常规使用的@TearDown中进行当前页面截图了。