提交 a8cc7cf7 authored 作者: 孙洁清's avatar 孙洁清

Merge branch 'master' of git.yfzx.zjtys.com.cn:hct/auto-test

package com.zjty.autotest.pojo.test;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
/**
* @author C
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ElementFeature {
private Point location;
private Dimension size;
private String tag;
private String text;
}
......@@ -9,14 +9,12 @@ import com.zjty.autotest.pojo.report.ElementDetail;
import com.zjty.autotest.pojo.report.Measure;
import com.zjty.autotest.pojo.report.Report;
import com.zjty.autotest.pojo.test.ActResult;
import com.zjty.autotest.pojo.test.ElementFeature;
import com.zjty.autotest.pojo.test.Input;
import com.zjty.autotest.pojo.test.Project;
import com.zjty.autotest.util.FileUtil;
import com.zjty.autotest.util.WebDriverUtil;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.openqa.selenium.*;
import org.openqa.selenium.logging.LogEntry;
......@@ -55,15 +53,15 @@ public class SeleniumExecutor {
private Set<String> historyUrls = Sets.newHashSet();
private Set<Attributes> historyAttributes = Sets.newHashSet();
private Set<ElementFeature> historyFeatures = Sets.newHashSet();
private Set<Attributes> currentHistoryAttributes = Sets.newHashSet();
private Set<ElementFeature> currentHistoryFeatures = Sets.newHashSet();
private Queue<String> windowQueue = Queues.newLinkedBlockingDeque();
private Queue<String> urlQueue = Queues.newLinkedBlockingDeque();
private Map<Attributes, WebElement> elements = Maps.newHashMap();
private Map<ElementFeature, WebElement> elements = Maps.newHashMap();
/**
* 当前进行的窗口页
*/
......@@ -112,7 +110,8 @@ public class SeleniumExecutor {
}
private Measure testUrl(String currentUrl) {
Measure measure = null;
Measure measure = new Measure();
measure.setUrl(currentUrl);
//如果该网页是未曾进入过的网页则加入历史记录并进行遍历测试
if (!historyUrls.contains(currentUrl)) {
historyUrls.add(driver.getCurrentUrl());
......@@ -137,12 +136,17 @@ public class SeleniumExecutor {
elements = getAllElements(driver);
log.info("获取完毕...共{}个元素...", elements.size());
//当前页面的历史元素记录重置
currentHistoryAttributes.clear();
currentHistoryFeatures.clear();
//开始遍历操作元素队列中的元素 返回各个元素测试信息
List<ElementDetail> elementDetails = Lists.newArrayList();
traversal(elementDetails);
elementDetails = elementDetails.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList());
//如果全部元素通过则是通过
Boolean success = elementDetails.stream().allMatch(ElementDetail::getSuccess);
Boolean success = elementDetails.stream()
.filter(Objects::nonNull)
.allMatch(ElementDetail::getSuccess);
//如果出错 则提供截图
String screenshot = null;
if (!success) {
......@@ -174,40 +178,30 @@ public class SeleniumExecutor {
}
private void traversal(List<ElementDetail> elementDetails) {
for (Attributes attributes : elements.keySet()) {
WebElement element = elements.get(attributes);
if (ExpectedConditions.stalenessOf(element).apply(driver)) {
reload();
element = elements.get(attributes);
}
if (!currentHistoryAttributes.contains(attributes) && isInputAble(element)) {
ActResult act = act(attributes, element, INPUT);
for (ElementFeature feature : elements.keySet()) {
WebElement element = elements.get(feature);
if (!currentHistoryFeatures.contains(feature) && isInputAble(element)) {
ActResult act = act(feature, element, INPUT);
ElementDetail elementDetail = act.getElementDetail();
elementDetails.add(elementDetail);
if (act.getStaleness()) {
traversal(elementDetails);
}
}
}
for (Attributes attributes : elements.keySet()) {
WebElement element = elements.get(attributes);
if (ExpectedConditions.stalenessOf(element).apply(driver)) {
reload();
element = elements.get(attributes);
}
if (!currentHistoryAttributes.contains(attributes) && isClickAble(element)) {
ActResult act = act(attributes, element, CLICK);
for (ElementFeature feature : elements.keySet()) {
WebElement element = elements.get(feature);
if (!currentHistoryFeatures.contains(feature) && isClickAble(element)) {
ActResult act = act(feature, element, CLICK);
ElementDetail elementDetail = act.getElementDetail();
elementDetails.add(elementDetail);
if (act.getStaleness()) {
reload();
traversal(elementDetails);
return;
}
}
}
}
@SuppressWarnings("AlibabaMethodTooLong")
private ActResult act(Attributes attributes, WebElement element, String actType) {
private ActResult act(ElementFeature feature, WebElement element, String actType) {
String type = String.format("<%s>%s", element.getTagName(), element.getText());
String message = null;
long responseTime = -1L;
......@@ -215,7 +209,7 @@ public class SeleniumExecutor {
boolean staleness = false;
try {
if (isEnabled(element)) {
log.info("元素 ----- tag:[{}] ------ text:[{}] ---- attrs:[{}] ------ notStale:{}", element.getTagName(), element.getText(), attributes, !ExpectedConditions.stalenessOf(element).apply(driver));
log.info("元素 ----- tag:[{}] ------ text:[{}] ---- feature:[{}] ------ notStale:{}", element.getTagName(), element.getText(), feature, !ExpectedConditions.stalenessOf(element).apply(driver));
long startTime = System.currentTimeMillis();
if (Objects.equals(actType, INPUT)) {
log.info("Input操作");
......@@ -229,23 +223,6 @@ public class SeleniumExecutor {
element.click();
sleep();
success = true;
boolean urlChanged = checkURl();
boolean sourceChanged = checkSource();
if (urlChanged) {
boolean newPage = !historyUrls.contains(driver.getCurrentUrl())
&& !Sets.newHashSet(urlQueue).contains(driver.getCurrentUrl())
&& sourceChanged;
if (newPage) {
log.info("检测到新url:{} 加入队列 ", driver.getCurrentUrl());
urlQueue.add(driver.getCurrentUrl());
urlQueue = queueDuplicateRemoval(urlQueue);
}
reload();
}
if (ExpectedConditions.stalenessOf(element).apply(driver)) {
element = elements.get(attributes);
staleness = true;
}
}
long endTime = System.currentTimeMillis();
responseTime = endTime - startTime;
......@@ -267,13 +244,14 @@ public class SeleniumExecutor {
success = false;
log.error("error:出现js异常:{}", jsMsg);
}
staleness = checkPage();
}
} catch (ElementNotInteractableException e) {
log.error("error:可操作范围之外的元素");
return new ActResult(staleness, null);
return new ActResult(false, null);
} catch (StaleElementReferenceException e) {
log.error("元素过期");
return new ActResult(staleness, null);
return new ActResult(false, null);
} catch (TimeoutException e) {
message = "页面超时";
success = false;
......@@ -291,8 +269,8 @@ public class SeleniumExecutor {
success = false;
log.error("error:" + e);
}
historyAttributes.add(attributes);
currentHistoryAttributes.add(attributes);
historyFeatures.add(feature);
currentHistoryFeatures.add(feature);
return new ActResult(
staleness,
new ElementDetail(
......@@ -304,6 +282,25 @@ public class SeleniumExecutor {
);
}
private Boolean checkPage(){
boolean staleness = false;
boolean urlChanged = checkURl();
boolean sourceChanged = checkSource();
if (urlChanged) {
boolean newPage = !historyUrls.contains(driver.getCurrentUrl())
&& !Sets.newHashSet(urlQueue).contains(driver.getCurrentUrl())
&& sourceChanged;
if (newPage) {
log.info("检测到新url:{} 加入队列 ", driver.getCurrentUrl());
urlQueue.add(driver.getCurrentUrl());
urlQueue = queueDuplicateRemoval(urlQueue);
staleness = true;
}
reload();
}
return staleness;
}
private Boolean checkURl() {
String practiseUrl = driver.getCurrentUrl();
return !Objects.equals(currentUrl, practiseUrl);
......@@ -357,19 +354,13 @@ public class SeleniumExecutor {
}
}
private Map<Attributes, WebElement> getAllElements(WebDriver driver) {
private Map<ElementFeature, WebElement> getAllElements(WebDriver driver) {
List<WebElement> webElements = Lists.newArrayList();
driver.findElements(By.xpath("*"))
.forEach(element -> getSubElements(element, webElements));
Document document = Jsoup.parse(driver.getPageSource());
List<Element> jElements = document.getAllElements().stream()
.filter(element -> element.childrenSize() == 0)
.collect(Collectors.toList());
Map<Attributes, WebElement> result = Maps.newHashMap();
for (int i = 0; i < webElements.size(); i++) {
WebElement webElement = webElements.get(i);
Element jElement = jElements.get(i);
result.put(jElement.attributes(), webElement);
Map<ElementFeature, WebElement> result = Maps.newHashMap();
for (WebElement webElement : webElements) {
result.put(toFeature(webElement), webElement);
}
return result;
}
......@@ -384,7 +375,7 @@ public class SeleniumExecutor {
}
private Boolean isInputAble(WebElement element) {
return Objects.equals(element.getTagName(), LabelType.INPUT);
return isEnabled(element) && Objects.equals(element.getTagName(), LabelType.INPUT);
}
@SuppressWarnings("unused")
......@@ -437,11 +428,11 @@ public class SeleniumExecutor {
}
@SuppressWarnings("unused")
private Map<Attributes, WebElement> removeHistoryElements(Map<Attributes, WebElement> elements) {
Map<Attributes, WebElement> result = Maps.newHashMap(elements);
elements.forEach((attributes, element) -> {
if (historyAttributes.contains(attributes)) {
result.remove(attributes, element);
private Map<ElementFeature, WebElement> removeHistoryElements(Map<ElementFeature, WebElement> elements) {
Map<ElementFeature, WebElement> result = Maps.newHashMap(elements);
elements.forEach((feature, element) -> {
if (historyFeatures.contains(feature)) {
result.remove(feature, element);
}
});
return result;
......@@ -492,4 +483,13 @@ public class SeleniumExecutor {
return null;
}
private ElementFeature toFeature(WebElement element) {
return new ElementFeature(
element.getLocation(),
element.getSize(),
element.getTagName(),
element.getText()
);
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论