提交 d8919640 authored 作者: 黄承天's avatar 黄承天

自动测试历史判断机制更新

上级 4ce1de26
...@@ -48,12 +48,6 @@ public class SeleniumExecutor { ...@@ -48,12 +48,6 @@ public class SeleniumExecutor {
@Value("${screenshot-path}") @Value("${screenshot-path}")
private String screenshotPath; private String screenshotPath;
@Value("${selenium.executor.screenshot.url-host}")
private String screenshotPrefixHost;
@Value("${selenium.executor.screenshot.url-port}")
private String screenshotPrefixPort;
private WebDriver driver; private WebDriver driver;
private List<Input> inputs = Lists.newArrayList(); private List<Input> inputs = Lists.newArrayList();
...@@ -68,6 +62,7 @@ public class SeleniumExecutor { ...@@ -68,6 +62,7 @@ public class SeleniumExecutor {
private Queue<String> urlQueue = Queues.newLinkedBlockingDeque(); private Queue<String> urlQueue = Queues.newLinkedBlockingDeque();
Map<Attributes, WebElement> elements = Maps.newHashMap();
/** /**
* 当前进行的窗口页 * 当前进行的窗口页
*/ */
...@@ -130,8 +125,15 @@ public class SeleniumExecutor { ...@@ -130,8 +125,15 @@ public class SeleniumExecutor {
log.info("当前URL:{} 响应时间 {} ms 开始进行遍历...", currentUrl, responseTime); log.info("当前URL:{} 响应时间 {} ms 开始进行遍历...", currentUrl, responseTime);
log.info("剩余URL队列:{}", urlQueue); log.info("剩余URL队列:{}", urlQueue);
log.info("正在获取当前网页所有元素..."); log.info("正在获取当前网页所有元素...");
StringBuilder message = new StringBuilder();
String error = checkJsError();
if (nonNull(error)) {
message.append(error);
message.append(";");
}
//获取当前网页的所有元素并放入元素队列 //获取当前网页的所有元素并放入元素队列
Map<Attributes, WebElement> elements = getAllElements(driver); elements.clear();
elements = getAllElements(driver);
log.info("获取完毕...共{}个元素...", elements.size()); log.info("获取完毕...共{}个元素...", elements.size());
//当前页面的历史元素记录重置 //当前页面的历史元素记录重置
currentHistoryAttributes.clear(); currentHistoryAttributes.clear();
...@@ -149,10 +151,10 @@ public class SeleniumExecutor { ...@@ -149,10 +151,10 @@ public class SeleniumExecutor {
} }
//总合信息 //总合信息
Set<String> messages = elementDetails.stream() Set<String> messages = elementDetails.stream()
.filter(Objects::nonNull)
.map(ElementDetail::getMessage) .map(ElementDetail::getMessage)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
StringBuilder message = new StringBuilder();
for (String msg : messages) { for (String msg : messages) {
message.append(msg); message.append(msg);
message.append(";"); message.append(";");
...@@ -171,7 +173,6 @@ public class SeleniumExecutor { ...@@ -171,7 +173,6 @@ public class SeleniumExecutor {
} }
private void traversal(Map<Attributes, WebElement> elements, List<ElementDetail> elementDetails) { private void traversal(Map<Attributes, WebElement> elements, List<ElementDetail> elementDetails) {
elements = removeHistoryElements(elements);
for (Attributes attributes : elements.keySet()) { for (Attributes attributes : elements.keySet()) {
WebElement element = elements.get(attributes); WebElement element = elements.get(attributes);
if (!currentHistoryAttributes.contains(attributes) && isInputAble(element)) { if (!currentHistoryAttributes.contains(attributes) && isInputAble(element)) {
...@@ -194,8 +195,7 @@ public class SeleniumExecutor { ...@@ -194,8 +195,7 @@ public class SeleniumExecutor {
urlQueue.add(driver.getCurrentUrl()); urlQueue.add(driver.getCurrentUrl());
urlQueue = queueDuplicateRemoval(urlQueue); urlQueue = queueDuplicateRemoval(urlQueue);
} }
Map<Attributes, WebElement> reload = reload(); reload();
traversal(reload, elementDetails);
} }
if (nonNull(elementDetail)) { if (nonNull(elementDetail)) {
elementDetails.add(elementDetail); elementDetails.add(elementDetail);
...@@ -211,16 +211,17 @@ public class SeleniumExecutor { ...@@ -211,16 +211,17 @@ public class SeleniumExecutor {
boolean success = false; boolean success = false;
try { try {
if (isEnabled(element)) { if (isEnabled(element)) {
log.info("元素 ----- tag:[{}] ------ text:[{}] ---- attrs:[{}] ------ notStale:{}", element.getTagName(), element.getText(), attributes, !ExpectedConditions.stalenessOf(element).apply(driver));
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
if (Objects.equals(actType, INPUT)) { if (Objects.equals(actType, INPUT)) {
log.info("Input操作 元素 ----- tag:[{}] ------ text:[{}] ---- attrs:[{}]", element.getTagName(), element.getText(), attributes); log.info("Input操作");
if (!inputs.isEmpty()) { if (!inputs.isEmpty()) {
Input input = inputs.remove(0); Input input = inputs.remove(0);
element.sendKeys(input.getValue()); element.sendKeys(input.getValue());
} }
success = true; success = true;
} else if (Objects.equals(actType, CLICK)) { } else if (Objects.equals(actType, CLICK)) {
log.info("Click操作 元素 ----- tag:[{}] ------ text:[{}] ---- attrs:[{}]", element.getTagName(), element.getText(), attributes); log.info("Click操作");
element.click(); element.click();
sleep(); sleep();
success = true; success = true;
...@@ -249,6 +250,9 @@ public class SeleniumExecutor { ...@@ -249,6 +250,9 @@ public class SeleniumExecutor {
} catch (ElementNotInteractableException e) { } catch (ElementNotInteractableException e) {
log.error("error:可操作范围之外的元素"); log.error("error:可操作范围之外的元素");
return null; return null;
} catch (StaleElementReferenceException e) {
log.error("元素过期");
return null;
} catch (TimeoutException e) { } catch (TimeoutException e) {
message = "页面超时"; message = "页面超时";
success = false; success = false;
...@@ -313,11 +317,11 @@ public class SeleniumExecutor { ...@@ -313,11 +317,11 @@ public class SeleniumExecutor {
} }
} }
private Map<Attributes, WebElement> reload() { private void reload() {
driver.get(currentUrl); driver.get(currentUrl);
sleep(); sleep();
currentSource = driver.getPageSource(); currentSource = driver.getPageSource();
return getAllElements(driver); elements = getAllElements(driver);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
...@@ -330,6 +334,7 @@ public class SeleniumExecutor { ...@@ -330,6 +334,7 @@ public class SeleniumExecutor {
} }
private Map<Attributes, WebElement> getAllElements(WebDriver driver) { private Map<Attributes, WebElement> getAllElements(WebDriver driver) {
try {
List<WebElement> webElements = Lists.newArrayList(); List<WebElement> webElements = Lists.newArrayList();
driver.findElements(By.xpath("*")) driver.findElements(By.xpath("*"))
.forEach(element -> getSubElements(element, webElements)); .forEach(element -> getSubElements(element, webElements));
...@@ -344,18 +349,19 @@ public class SeleniumExecutor { ...@@ -344,18 +349,19 @@ public class SeleniumExecutor {
result.put(jElement.attributes(), webElement); result.put(jElement.attributes(), webElement);
} }
return result; return result;
} catch (StaleElementReferenceException e) {
log.error("获取元素过程中遇到元素过期 重新开始获取");
return getAllElements(driver);
}
} }
private void getSubElements(WebElement element, List<WebElement> elements) { private void getSubElements(WebElement element, List<WebElement> elements) {
try {
List<WebElement> results = element.findElements(By.xpath("*")); List<WebElement> results = element.findElements(By.xpath("*"));
if (results.isEmpty()) { if (results.isEmpty()) {
elements.add(element); elements.add(element);
} else { } else {
results.forEach(webElement -> getSubElements(webElement, elements)); results.forEach(webElement -> getSubElements(webElement, elements));
} }
} catch (StaleElementReferenceException ignored) {
}
} }
private Boolean isInputAble(WebElement element) { private Boolean isInputAble(WebElement element) {
...@@ -396,10 +402,11 @@ public class SeleniumExecutor { ...@@ -396,10 +402,11 @@ public class SeleniumExecutor {
private void screenshot(String name) { private void screenshot(String name) {
byte[] bytes = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES); byte[] bytes = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
String path; String path;
if (screenshotPath.endsWith("/")) { String suffix = "/";
if (screenshotPath.endsWith(suffix)) {
path = screenshotPath + name; path = screenshotPath + name;
} else { } else {
path = screenshotPath + "/" + name; path = screenshotPath + suffix + name;
} }
FileUtil.output(bytes, path); FileUtil.output(bytes, path);
} }
...@@ -423,11 +430,14 @@ public class SeleniumExecutor { ...@@ -423,11 +430,14 @@ public class SeleniumExecutor {
try { try {
Dimension size = driver.manage().window().getSize(); Dimension size = driver.manage().window().getSize();
Point elementLocation = element.getLocation(); Point elementLocation = element.getLocation();
Dimension elementSize = element.getSize(); boolean xMatch = (elementLocation.x) >= 0 && (elementLocation.x <= size.width);
boolean xMatch = (elementLocation.x) >= 0 && (elementLocation.x + elementSize.width <= size.width); boolean yMatch = (elementLocation.y) >= 0 && (elementLocation.y <= size.height);
boolean yMatch = (elementLocation.y) >= 0 && (elementLocation.y + elementSize.width <= size.height);
return xMatch && yMatch; return xMatch && yMatch;
} catch (StaleElementReferenceException e) {
log.error("判断位置布局时元素过期");
return true;
} catch (Exception e) { } catch (Exception e) {
log.error("error:" + e);
return false; return false;
} }
} }
...@@ -435,20 +445,24 @@ public class SeleniumExecutor { ...@@ -435,20 +445,24 @@ public class SeleniumExecutor {
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
private String checkJsError() { private String checkJsError() {
try { try {
return analyseLogError(driver.manage().logs().get(LogType.BROWSER).getAll().stream().findFirst().get()); return analyseLogError(driver.manage().logs().get(LogType.BROWSER).getAll().stream().findFirst().orElse(null));
} catch (Exception e) { } catch (Exception e) {
return null; return null;
} }
} }
private String analyseLogError(LogEntry logEntry) { private String analyseLogError(LogEntry logEntry) {
if (logEntry.getMessage().contains("Uncaught TypeError:")) { String typeError = "Uncaught TypeError:";
String fileNotFound = "Failed to load resource: net::ERR_FILE_NOT_FOUND";
String errorConnection = "Failed to load resource: net::ERR_CONNECTION_RESET";
String resourceFailure = "Failed to load resource: ";
if (logEntry.getMessage().contains(typeError)) {
return "JS类型错误"; return "JS类型错误";
} else if (logEntry.getMessage().contains("Failed to load resource: net::ERR_FILE_NOT_FOUND")) { } else if (logEntry.getMessage().contains(fileNotFound)) {
return "资源加载错误"; return "资源加载错误";
} else if (logEntry.getMessage().contains("Failed to load resource: net::ERR_CONNECTION_RESET")) { } else if (logEntry.getMessage().contains(errorConnection)) {
return "数据请求错误"; return "数据请求错误";
} else if (logEntry.getMessage().contains("Failed to load resource: ")) { } else if (logEntry.getMessage().contains(resourceFailure)) {
return "加载依赖错误"; return "加载依赖错误";
} }
return null; return null;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论