fix:移动端通用组件库

1.增加点击后截图的加点的操作
2.添加StaleElement异常的处理
master
李杰应 2024-08-19 14:17:21 +08:00
parent 6ef190c7d7
commit 5f3a467afd
4 changed files with 64 additions and 42 deletions

View File

@ -65,7 +65,11 @@ public class ClickElementThread implements Callable<Boolean> {
isDebug = (boolean) isDebugObj; isDebug = (boolean) isDebugObj;
} }
if (!isDebug) { if (!isDebug) {
try {
CommonUtils.screenShot(context,driver); CommonUtils.screenShot(context,driver);
} catch (Exception e) {
logger.error("步骤截图异常", e);
}
} }
if (point == null) { if (point == null) {
logger.error("查找不到控件"); logger.error("查找不到控件");

View File

@ -6,6 +6,7 @@ import io.appium.java_client.ios.IOSDriver;
import net.northking.cctp.element.core.IExecuteContext; import net.northking.cctp.element.core.IExecuteContext;
import net.northking.cctp.element.core.exception.ExecuteException; import net.northking.cctp.element.core.exception.ExecuteException;
import net.northking.cctp.element.mobile.constants.ConfigPath; import net.northking.cctp.element.mobile.constants.ConfigPath;
import net.northking.cctp.element.mobile.entity.PointMessage;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -56,6 +57,10 @@ public class CommonUtils {
} }
public static void screenShot(IExecuteContext context, AppiumDriver<WebElement> driver) { public static void screenShot(IExecuteContext context, AppiumDriver<WebElement> driver) {
screenShot(context, driver, null);
}
public static void screenShot(IExecuteContext context, AppiumDriver<WebElement> driver, PointMessage point) {
String screenShotAddress = context.getProperty(ConfigPath.UPLOAD_MOBILE_SCREEN_SHOT_ADDRESS_KEY); //截全屏地址 String screenShotAddress = context.getProperty(ConfigPath.UPLOAD_MOBILE_SCREEN_SHOT_ADDRESS_KEY); //截全屏地址
Map<String, Object> deviceInfo = context.getDeviceInfo(); Map<String, Object> deviceInfo = context.getDeviceInfo();
String host = driver.getRemoteAddress().getHost(); //上位机地址 String host = driver.getRemoteAddress().getHost(); //上位机地址
@ -74,8 +79,12 @@ public class CommonUtils {
}else if(driver instanceof IOSDriver) { }else if(driver instanceof IOSDriver) {
screenParam.put("platform","1"); screenParam.put("platform","1");
} }
if (null != point) {
screenParam.put("x", String.valueOf(point.getX()));
screenParam.put("y", String.valueOf(point.getY()));
}
HttpEntity<Map> screenEntity = new HttpEntity<>(screenParam, null); HttpEntity<Map> screenEntity = new HttpEntity<>(screenParam, null);
String picAddress = HttpUtils.doPost(shotAllScreenAddress, screenEntity, String.class); String picAddress = HttpUtils.doPost(shotAllScreenAddress, screenEntity, String.class, 20 * 1000);
logger.debug("截图地址:{}", picAddress); logger.debug("截图地址:{}", picAddress);
if (!StringUtils.hasText(picAddress)) { if (!StringUtils.hasText(picAddress)) {
logger.warn("设备【{}】截图失败", deviceId); logger.warn("设备【{}】截图失败", deviceId);

View File

@ -59,6 +59,24 @@ public class HttpUtils<T> {
} }
return response.getBody(); return response.getBody();
} }
public static <T> T doPost(String uri, HttpEntity<?> httpEntity,Class<T> responseType, int timeout){
ResponseEntity<T> response = null;
try {
RestTemplate template = createRestTemplate(timeout);
response = template.exchange(uri, HttpMethod.POST, httpEntity, responseType);
} catch (Exception e) {
logger.error("请求出错,地址:{},原因:{}",uri,e);
throw new ExecuteException(String.format("http请求【%s】出错", uri));
}
return response.getBody();
}
private static RestTemplate createRestTemplate(int timeout) {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(5000);
factory.setReadTimeout(timeout);
return new RestTemplate(factory);
}
public static <T> T doGet(URI uri, Class<T> responseType){ public static <T> T doGet(URI uri, Class<T> responseType){
ResponseEntity<T> response = null; ResponseEntity<T> response = null;

View File

@ -21,6 +21,7 @@ import net.northking.cctp.element.mobile.constants.ConfigPath;
import net.northking.cctp.element.mobile.constants.HzBankOcrCode; import net.northking.cctp.element.mobile.constants.HzBankOcrCode;
import net.northking.cctp.element.mobile.constants.UsingType; import net.northking.cctp.element.mobile.constants.UsingType;
import net.northking.cctp.element.mobile.entity.PointMessage; import net.northking.cctp.element.mobile.entity.PointMessage;
import net.northking.cctp.element.mobile.utils.CommonUtils;
import net.northking.cctp.element.mobile.utils.HttpUtils; import net.northking.cctp.element.mobile.utils.HttpUtils;
import net.northking.cctp.element.mobile.utils.RandomUtil; import net.northking.cctp.element.mobile.utils.RandomUtil;
import net.northking.cctp.element.mobile.utils.hzBank.HzBankOcrUtils; import net.northking.cctp.element.mobile.utils.hzBank.HzBankOcrUtils;
@ -1323,24 +1324,6 @@ public class ElementUtil {
throw e; throw e;
} }
WebElement webElement = getWebElement(driver, swipe, xpath, swipeNum); WebElement webElement = getWebElement(driver, swipe, xpath, swipeNum);
/*SessionId sessionId = driver.getSessionId();
logger.debug("当前driver的sessionId为{}", sessionId);
try {
webElement = submit.get(waitTimeout, TimeUnit.SECONDS);
logger.info("拿到元素:{}", webElement);
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof NoSuchSessionException) {
logger.warn("driver失效了。。。。");
NoSuchSessionException nsse = (NoSuchSessionException) cause;
throw nsse;
}
} catch (Exception e) {
logger.error("xpath找元素出错", e);
xpathThread.kill();
}*/
Rectangle rect = null; Rectangle rect = null;
try { try {
rect = webElement.getRect(); rect = webElement.getRect();
@ -1703,7 +1686,7 @@ public class ElementUtil {
stopWatch.start(); stopWatch.start();
switch (target.getUsing()) { switch (target.getUsing()) {
case UsingType.SELECTOR: case UsingType.SELECTOR:
exist = xpathFindElementExist(driver, target, timeOut, swipe, swipeCount); point = xpathFindElementExist(driver, target, timeOut, swipe, swipeCount);
break; break;
case UsingType.OCR: case UsingType.OCR:
point = ocrFind(target, driver, context, timeOut); point = ocrFind(target, driver, context, timeOut);
@ -1724,7 +1707,12 @@ public class ElementUtil {
stopWatch.stop(); stopWatch.stop();
logger.info("{}找了{}s", target.getUsing(), stopWatch.getTotalTimeSeconds()); logger.info("{}找了{}s", target.getUsing(), stopWatch.getTotalTimeSeconds());
if (point != null) { if (point != null) {
return true; exist = true;
Object debugFlag = context.getContextVariable("__isDebug");
if (debugFlag != null && !(boolean)debugFlag ) {
// 用于添加截图红点
CommonUtils.screenShot(context, driver, point);
}
} }
} }
} }
@ -2069,13 +2057,14 @@ public class ElementUtil {
return point; return point;
} }
private static boolean xpathFindElementExist(AppiumDriver<WebElement> driver, IStepTarget target, int timeOut, String swipe, Integer swipeCount) { private static PointMessage xpathFindElementExist(AppiumDriver<WebElement> driver, IStepTarget target, int timeOut, String swipe, Integer swipeCount) {
PointMessage point = null;
JSONObject object = JSON.parseObject(target.getValue(), JSONObject.class); JSONObject object = JSON.parseObject(target.getValue(), JSONObject.class);
String xpath = object.getString(UsingType.Key.SELECTOR_KEY); String xpath = object.getString(UsingType.Key.SELECTOR_KEY);
logger.info("拿到的xpath:{}", xpath); logger.info("拿到的xpath:{}", xpath);
Integer perPageTimeout = timeOut; Integer perPageTimeout = timeOut;
Integer swipeNum = swipeCount; Integer swipeNum = swipeCount;
if ((swipeCount <= 0 && swipeCount > 5)/*限定滑屏查找不超过5次*/ || "0".equals(swipe) /*不滑屏*/) { if ((swipeCount <= 0 || swipeCount > 5)/*限定滑屏查找不超过5次*/ || "0".equals(swipe) /*不滑屏*/) {
swipeNum = 0; swipeNum = 0;
} }
if (swipeNum > 0) { if (swipeNum > 0) {
@ -2086,29 +2075,31 @@ public class ElementUtil {
} catch (NoSuchSessionException e) { } catch (NoSuchSessionException e) {
throw e; throw e;
} }
WebElement webElement = null; WebElement webElement = getWebElement(driver, swipe, xpath, swipeNum);
while (swipeNum >= 0) { Rectangle rect = null;
List<WebElement> elements = null;
try { try {
elements = driver.findElements(By.xpath(xpath)); rect = webElement.getRect();
} catch (WebDriverException e) { } catch (StaleElementReferenceException e) {
logger.error("driver查找控件异常", e); logger.warn("页面发生变化,重新查找元素", e);
throw new ExecuteException("设备自动化驱动连接异常,查找控件失败"); try {
Thread.sleep(2000L);
} catch (InterruptedException ex) {
logger.error("在查找元素等待时被打断", ex);
} }
logger.info("找到元素{}个", elements.size()); logger.info("再次查找当前页面的元素");
if (!CollectionUtils.isEmpty(elements)) { //xpath找到了 WebElement we = getWebElement(driver, swipe, xpath, swipeNum);
webElement = elements.get(0); if (null != we) {
} else { //xpath没找到 rect = we.getRect();
if (swipeNum > 0) {
ScreenUtil.standardSwipe(swipe, 2000, driver);
} }
} }
swipeNum--; if (null != rect) {
int x = rect.getX();
int y = rect.getY();
int width = rect.getWidth();
int height = rect.getHeight();
point = new PointMessage(x + width / 2, y + height / 2, false);
} }
if (null != webElement) { return point;
return true;
}
return false;
} }
public static PointMessage findTextByOcr(IExecuteContext context, AppiumDriver<WebElement> driver, String value, Integer index) { public static PointMessage findTextByOcr(IExecuteContext context, AppiumDriver<WebElement> driver, String value, Integer index) {