harmony滑动解锁、滑动查找组件、识别验证码、if存在控件执行点击、点击返回键、点击多任务键、if存在控件执行输入、击指定文字指定方向第几个指定内容的文本
parent
a3330deff9
commit
394185218f
|
@ -48,6 +48,10 @@ public interface AutomationRequestCmd {
|
|||
|
||||
String PRESS_HOME_KEY = "press_home_key"; //点击home键
|
||||
|
||||
String PRESS_BACK_KEY = "press_back_key"; //点击返回键
|
||||
|
||||
String PRESS_APP_SWITCH_KEY = "press_app_switch_key"; //点击多任务键
|
||||
|
||||
String INPUT_PASSWORD_BY_OCR = "input_password_by_ocr"; //输入密码(ocr)
|
||||
|
||||
String GET_ELEMENT_MONEY_TEXT = "get_element_money_text"; //识别金额
|
||||
|
|
|
@ -48,6 +48,10 @@ public interface AutomationRequestCmd {
|
|||
|
||||
String PRESS_HOME_KEY = "press_home_key"; //点击home键
|
||||
|
||||
String PRESS_BACK_KEY = "press_back_key"; //点击返回键
|
||||
|
||||
String PRESS_APP_SWITCH_KEY = "press_app_switch_key"; //点击多任务键
|
||||
|
||||
String INPUT_PASSWORD_BY_OCR = "input_password_by_ocr"; //输入密码(ocr)
|
||||
|
||||
String GET_ELEMENT_MONEY_TEXT = "get_element_money_text"; //识别金额
|
||||
|
|
|
@ -2,6 +2,7 @@ package net.northking.cctp.upperComputer.automation.handler;
|
|||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import net.northking.cctp.upperComputer.automation.constants.AutomationRequestCmd;
|
||||
import net.northking.cctp.upperComputer.automation.constants.UpperParamKey;
|
||||
|
@ -22,6 +23,7 @@ import net.northking.cctp.upperComputer.utils.deviceHepler.DeviceHelper;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.websocket.Session;
|
||||
|
@ -104,6 +106,10 @@ public abstract class AbstractAutomationHandler implements AutomationMessageHand
|
|||
handleApp(request);
|
||||
} else if (AutomationRequestCmd.PRESS_HOME_KEY.equals(cmd)) {
|
||||
pressHomeKey(request);
|
||||
} else if (AutomationRequestCmd.PRESS_BACK_KEY.equals(cmd)){
|
||||
pressBack(request);
|
||||
}else if (AutomationRequestCmd.PRESS_APP_SWITCH_KEY.equals(cmd)){
|
||||
pressAppSwitch(request);
|
||||
} else if (AutomationRequestCmd.INPUT_PASSWORD_BY_OCR.equals(cmd)) {
|
||||
inputPasswordByOcr(request);
|
||||
} else if (AutomationRequestCmd.GET_ELEMENT_MONEY_TEXT.equals(cmd)) {
|
||||
|
@ -486,4 +492,94 @@ public abstract class AbstractAutomationHandler implements AutomationMessageHand
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTextDirectionText(CmdAutomationRequest request) {
|
||||
CmdAutomationResponse response = CmdAutomationResponse.builderFailure(request, "获取指定文字指定方向的内容失败");
|
||||
String value = "";
|
||||
try {
|
||||
Map<String, Object> data = request.getData();
|
||||
String text = (String) data.get(UpperParamKey.INPUT_TEXT);
|
||||
Integer index = (Integer) data.get(UpperParamKey.INDEX);
|
||||
String direction = (String) data.get(UpperParamKey.DIRECTION);
|
||||
String imgBase64 = getClickTextOcrAreaToBase64(request);
|
||||
if (StringUtils.isBlank(imgBase64)) {
|
||||
response = CmdAutomationResponse.builderFailure(request, "未获取到ocr区域");
|
||||
}
|
||||
JSONObject ocrResultMap = ocrHelper.getTextDirectionText(imgBase64, text, direction, index);
|
||||
if (null != ocrResultMap) {
|
||||
JSONObject target_boxes = ocrResultMap.getJSONObject("target_boxes");
|
||||
logger.info("target_boxes为:{}", JSON.toJSONString(target_boxes));
|
||||
if ("右".equals(direction) || "左".equals(direction)) {
|
||||
if (null != target_boxes) {
|
||||
String targetText = (String) target_boxes.get("text");
|
||||
if (StringUtils.isNotBlank(targetText)) {
|
||||
int targetIndex = targetText.indexOf(text);
|
||||
if ("右".equals(direction) && targetIndex < (targetText.length() - text.length())) {
|
||||
value = targetText.substring(targetIndex + text.length());
|
||||
} else if ("左".equals(direction) && targetIndex > 0) {
|
||||
value = targetText.substring(0, targetIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(value)) {
|
||||
try {
|
||||
JSONObject neighbor_boxes = ocrResultMap.getJSONObject("neighbor_boxes");
|
||||
logger.info("neighbor_boxes为:{}", JSON.toJSONString(neighbor_boxes));
|
||||
if (null != neighbor_boxes) {
|
||||
String neighborText = (String) neighbor_boxes.get("text");
|
||||
value = neighborText;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
JSONArray neighbor_boxes = ocrResultMap.getJSONArray("neighbor_boxes");
|
||||
if (!CollectionUtils.isEmpty(neighbor_boxes)) {
|
||||
value = (String) ((Map<String, Object>) neighbor_boxes.get(0)).get("text");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info("获取指定文字指定方向的内容为:{}", value);
|
||||
response = CmdAutomationResponse.builderSuccess(request, "获取指定文字指定方向的内容成功").withData(value);
|
||||
} catch (Exception e) {
|
||||
logger.error("识别失败,原因:", e);
|
||||
response = CmdAutomationResponse.builderFailure(request, e.getMessage());
|
||||
} finally {
|
||||
sendResultToEngine(response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getVerificationCodeByOcr(CmdAutomationRequest request) {
|
||||
CmdAutomationResponse response = CmdAutomationResponse.builderSuccess(request, "根据ocr获取验证码失败").withData(null);
|
||||
try {
|
||||
String value = null;
|
||||
Map<String, Object> requestData = request.getData();
|
||||
String targetBase64 = "";
|
||||
if (requestData.get(UpperParamKey.X) != null) {
|
||||
targetBase64 = getOcrAreaToBase64(request);
|
||||
} else {
|
||||
targetBase64 = getClickTextOcrAreaToBase64(request);
|
||||
}
|
||||
if (StringUtils.isBlank(targetBase64)) {
|
||||
response = CmdAutomationResponse.builderSuccess(request, "未获取到ocr区域").withData(null);
|
||||
return;
|
||||
}
|
||||
Map<String, Object> data = request.getData();
|
||||
Integer codeType = (Integer) data.get(UpperParamKey.CODE_TYPE);
|
||||
value = ocrHelper.getVerificationCodeByBase64(targetBase64, codeType);
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
response = CmdAutomationResponse.builderSuccess(request, "根据ocr获取控件值成功").withData(value);
|
||||
} else {
|
||||
response = CmdAutomationResponse.builderSuccess(request, "根据ocr获取控件值失败").withData(null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("根据ocr获取验证码失败,原因:", e);
|
||||
response = CmdAutomationResponse.builderSuccess(request, e.getMessage()).withData(null);
|
||||
} finally {
|
||||
sendResultToEngine(response);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -111,11 +111,6 @@ public class AndroidAutomationHandler extends AbstractAutomationHandler{
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getVerificationCodeByOcr(CmdAutomationRequest request) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void longPress(CmdAutomationRequest request) {
|
||||
|
||||
|
@ -202,7 +197,12 @@ public class AndroidAutomationHandler extends AbstractAutomationHandler{
|
|||
}
|
||||
|
||||
@Override
|
||||
public void getTextDirectionText(CmdAutomationRequest request) {
|
||||
public void pressBack(CmdAutomationRequest request) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pressAppSwitch(CmdAutomationRequest request) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,10 @@ public interface AutomationMessageHandler {
|
|||
|
||||
void pressHomeKey(CmdAutomationRequest request); //点击home键
|
||||
|
||||
void pressBack(CmdAutomationRequest request); //点击home键
|
||||
|
||||
void pressAppSwitch(CmdAutomationRequest request); //点击home键
|
||||
|
||||
void inputPasswordByOcr(CmdAutomationRequest request); //密码输入(ocr)
|
||||
|
||||
void getElementMoneyText(CmdAutomationRequest request); //识别金额
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package net.northking.cctp.upperComputer.automation.handler;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import net.northking.cctp.upperComputer.automation.constants.Command;
|
||||
import net.northking.cctp.upperComputer.automation.constants.UpperParamKey;
|
||||
import net.northking.cctp.upperComputer.automation.entity.CmdAutomationRequest;
|
||||
|
@ -20,6 +23,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
@ -30,6 +34,7 @@ import javax.xml.parsers.DocumentBuilder;
|
|||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.xpath.*;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -381,12 +386,41 @@ public class HarmonyAutomationHandler extends AbstractAutomationHandler {
|
|||
|
||||
@Override
|
||||
public void getVerificationCodeByNode(CmdAutomationRequest request) {
|
||||
|
||||
CmdAutomationResponse response = CmdAutomationResponse.builderSuccess(request, "根据ui节点获取验证码失败").withData(null);
|
||||
try {
|
||||
String value = null;
|
||||
String targetBase64 = "";
|
||||
NodeList nodeList = findElementByXml(request);
|
||||
if (null == nodeList || nodeList.getLength() <= 0 ) {
|
||||
response = CmdAutomationResponse.builderSuccess(request, "验证码元素不存在").withData(null);
|
||||
} else {
|
||||
Element item = (Element) nodeList.item(0);
|
||||
Integer width = Integer.parseInt(item.getAttribute("width"));
|
||||
Integer height = Integer.parseInt(item.getAttribute("height"));
|
||||
Integer realityX = Integer.parseInt(item.getAttribute("x"));
|
||||
Integer realityY = Integer.parseInt(item.getAttribute("y"));
|
||||
logger.debug("设备:{},步骤:{}找到验证码元素->x:{},y:{},width:{},height:{}",this.serial,request.getStepToken(),realityX,realityY,width,height);
|
||||
File screenShotFile = deviceHandleHelper.getScreenShotFile(this.serial, realityX, realityY, width, height);
|
||||
targetBase64 = Base64.encode(screenShotFile);
|
||||
}
|
||||
if (StringUtils.isBlank(targetBase64)) {
|
||||
response = CmdAutomationResponse.builderSuccess(request, "未获取到ocr区域").withData(null);
|
||||
return;
|
||||
}
|
||||
Map<String, Object> data = request.getData();
|
||||
Integer codeType = (Integer) data.get(UpperParamKey.CODE_TYPE);
|
||||
value = ocrHelper.getVerificationCodeByBase64(targetBase64, codeType);
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
response = CmdAutomationResponse.builderSuccess(request, "根据ocr获取控件值成功").withData(value);
|
||||
} else {
|
||||
response = CmdAutomationResponse.builderSuccess(request, "根据ocr获取控件值失败").withData(null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("根据ocr获取验证码失败,原因:", e);
|
||||
response = CmdAutomationResponse.builderSuccess(request, e.getMessage()).withData(null);
|
||||
} finally {
|
||||
sendResultToEngine(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getVerificationCodeByOcr(CmdAutomationRequest request) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -674,6 +708,10 @@ public class HarmonyAutomationHandler extends AbstractAutomationHandler {
|
|||
CmdAutomationResponse response = CmdAutomationResponse.builderFailure(request, "点击home键失败").withData(false);
|
||||
try {
|
||||
HarmonyProvider harmonyProvider = getHarmonyProvider();
|
||||
if (null == harmonyProvider) {
|
||||
response = CmdAutomationResponse.builderFailure(request, "设备与上位机连接断开");
|
||||
return;
|
||||
}
|
||||
boolean success = harmonyProvider.pressHome();
|
||||
if (success) {
|
||||
response = CmdAutomationResponse.builderSuccess(request, "点击home键成功").withData(true);
|
||||
|
@ -688,18 +726,184 @@ public class HarmonyAutomationHandler extends AbstractAutomationHandler {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pressBack(CmdAutomationRequest request) {
|
||||
CmdAutomationResponse response = CmdAutomationResponse.builderFailure(request, "点击返回键失败").withData(false);
|
||||
try {
|
||||
HarmonyProvider harmonyProvider = getHarmonyProvider();
|
||||
if (null == harmonyProvider) {
|
||||
response = CmdAutomationResponse.builderFailure(request, "设备与上位机连接断开");
|
||||
return;
|
||||
}
|
||||
boolean success = harmonyProvider.pressBack();
|
||||
if (success) {
|
||||
response = CmdAutomationResponse.builderSuccess(request, "点击返回键成功").withData(true);
|
||||
} else {
|
||||
response = CmdAutomationResponse.builderFailure(request, "点击返回键失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("点击返回键失败,原因:", e);
|
||||
response = CmdAutomationResponse.builderFailure(request, e.getMessage());
|
||||
} finally {
|
||||
sendResultToEngine(response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pressAppSwitch(CmdAutomationRequest request) {
|
||||
CmdAutomationResponse response = CmdAutomationResponse.builderFailure(request, "点击多任务键失败").withData(false);
|
||||
try {
|
||||
HarmonyProvider harmonyProvider = getHarmonyProvider();
|
||||
if (null == harmonyProvider) {
|
||||
response = CmdAutomationResponse.builderFailure(request, "设备与上位机连接断开");
|
||||
return;
|
||||
}
|
||||
int height = this.screenInfo.getHeight();
|
||||
harmonyProvider.touchDown(200, height-10);
|
||||
Thread.sleep(200);
|
||||
for (float i = 0.01f; i <= 1; i +=0.01) {
|
||||
Float y = height - 10 - i * 300;
|
||||
harmonyProvider.touchMove(200, y.intValue());
|
||||
Thread.sleep(5);
|
||||
}
|
||||
Thread.sleep(200);
|
||||
boolean success = harmonyProvider.touchUp(200, height - 10 - 300);
|
||||
if (success) {
|
||||
response = CmdAutomationResponse.builderSuccess(request, "点击多任务键成功").withData(true);
|
||||
} else {
|
||||
response = CmdAutomationResponse.builderFailure(request, "点击多任务键失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("点击多任务键失败,原因:", e);
|
||||
response = CmdAutomationResponse.builderFailure(request, e.getMessage());
|
||||
} finally {
|
||||
sendResultToEngine(response);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void pressAndSwipe(CmdAutomationRequest request) {
|
||||
|
||||
CmdAutomationResponse response = CmdAutomationResponse.builderFailure(request, "滑动解锁失败").withData(false);
|
||||
boolean success = false;
|
||||
Map<String, Object> data = request.getData();
|
||||
try {
|
||||
String[] pointXpath = new String[3];
|
||||
JSONObject xpathObject = JSON.parseObject((String) data.get(UpperParamKey.FIRST_POINT), JSONObject.class);
|
||||
pointXpath[0] = xpathObject.getString("selector");
|
||||
xpathObject = JSON.parseObject((String) data.get(UpperParamKey.SECOND_POINT), JSONObject.class);
|
||||
pointXpath[1] = xpathObject.getString("selector");
|
||||
xpathObject = JSON.parseObject((String) data.get(UpperParamKey.THIRD_POINT), JSONObject.class);
|
||||
pointXpath[2] = xpathObject.getString("selector");
|
||||
Integer num = (Integer) data.get(UpperParamKey.POINT_NUM);
|
||||
List<Integer> passPoint = (List<Integer>) data.get(UpperParamKey.SWIPE_POINT);
|
||||
Integer waitTimeOut = (Integer) data.get(UpperParamKey.WAIT_TIMEOUT);
|
||||
logger.debug("拿到的左上角的点:{}", pointXpath[0]);
|
||||
logger.debug("拿到的左上角的右边点:{}", pointXpath[1]);
|
||||
logger.debug("拿到的左上角的下边点:{}", pointXpath[2]);
|
||||
logger.debug("拿到的每行每列的点数:{}", num);
|
||||
logger.debug("拿到的经过的点:{}", JSON.toJSONString(passPoint));
|
||||
long startTime = System.currentTimeMillis();
|
||||
long endTime = startTime;
|
||||
logger.debug("步骤:{}开始查找控件,超时时间:{}", request.getStepToken(), waitTimeOut);
|
||||
Map<String, Integer>[] point = new Map[3];
|
||||
int index = 0;
|
||||
int findIndex = 1;
|
||||
HarmonyProvider harmonyProvider = getHarmonyProvider();
|
||||
if (null == harmonyProvider) {
|
||||
response = CmdAutomationResponse.builderFailure(request, "设备与上位机连接断开");
|
||||
return;
|
||||
}
|
||||
NodeList nodeList = null;
|
||||
do {
|
||||
UiComponent uiComponent = harmonyProvider.captureLayout();
|
||||
Document document = builder.newDocument();
|
||||
Node xmlElement = uiComponent.createXMLElement(document);
|
||||
document.appendChild(xmlElement);
|
||||
try {
|
||||
nodeList = findNode(pointXpath[index], document);
|
||||
} catch (XPathExpressionException e) {
|
||||
logger.error("步骤:{},xpath格式不对:{}",request.getStepToken(),pointXpath[index]);
|
||||
}
|
||||
logger.debug("步骤:{},第{}次开始查找第{}个元素", request.getStepToken(), findIndex, index + 1);
|
||||
endTime = System.currentTimeMillis();
|
||||
findIndex++;
|
||||
if (null != nodeList) {
|
||||
Element node = (Element) nodeList.item(0);
|
||||
logger.debug("步骤:{},第{}次开始查找第{}个元素已经找到", request.getStepToken(), findIndex, index + 1);
|
||||
int x = Integer.parseInt(node.getAttribute("x"));
|
||||
int y = Integer.parseInt(node.getAttribute("y"));
|
||||
Integer width = Integer.parseInt(node.getAttribute("width"));
|
||||
Integer height = Integer.parseInt(node.getAttribute("height"));
|
||||
Map<String, Integer> perPoint = new HashMap<>();
|
||||
perPoint.put("x", x + width / 2);
|
||||
perPoint.put("y", y + height / 2);
|
||||
point[index] = perPoint;
|
||||
index++;
|
||||
findIndex = 1;
|
||||
}
|
||||
} while ((endTime - startTime) < waitTimeOut * 1000 && index < 3);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (point[i] == null) {
|
||||
response = CmdAutomationResponse.builderFailure(request, "定位解锁区域的点不全").withData(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//计算每个点的坐标
|
||||
int perWidth = point[1].get("x") - point[0].get("x");
|
||||
int perHeight = point[2].get("y") - point[0].get("y");
|
||||
List<Map<String, Integer>> pointList = new ArrayList<>();
|
||||
int n = 1;
|
||||
for (int i = 0; i < num; i++) {
|
||||
int pointY = point[0].get("y") + i * perHeight; //每一行的y坐标
|
||||
for (int j = 0; j < num; j++) {
|
||||
int pointX = point[0].get("x") + j * perWidth;
|
||||
logger.info("第{}个点的坐标x:{},y:{}", n, pointX, pointY);
|
||||
Map<String, Integer> perPoint = new HashMap<>();
|
||||
perPoint.put("x", pointX);
|
||||
perPoint.put("y", pointY);
|
||||
pointList.add(n - 1, perPoint);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
logger.info("token:{},滑动解锁的所有坐标集合:{}", request.getStepToken(), JSON.toJSONString(pointList));
|
||||
//开始滑动
|
||||
if (!CollectionUtils.isEmpty(passPoint)) {
|
||||
Integer startIndex = passPoint.get(0);
|
||||
Map<String, Integer> startPoint = pointList.get(startIndex - 1);
|
||||
harmonyProvider.touchDown(startPoint.get("x"), startPoint.get("y"));
|
||||
for (int i = 1; i < passPoint.size(); i++) {
|
||||
try {
|
||||
Thread.sleep(200);
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
}
|
||||
Integer passIndex = passPoint.get(i);
|
||||
Map<String, Integer> pointMessage = pointList.get(passIndex - 1);
|
||||
harmonyProvider.touchMove(pointMessage.get("x"), pointMessage.get("y"));
|
||||
}
|
||||
try {
|
||||
Thread.sleep(200);
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
}
|
||||
Integer endIndex = passPoint.get(passPoint.size() - 1);
|
||||
Map<String, Integer> endPoint = pointList.get(endIndex - 1);
|
||||
success = harmonyProvider.touchUp(endPoint.get("x"), endPoint.get("y"));
|
||||
} else {
|
||||
logger.warn("token:{},没有滑动通过的坐标", request.getStepToken());
|
||||
}
|
||||
logger.info("token:{},滑动解锁的结果:{}", request.getStepToken(), success);
|
||||
if (success) {
|
||||
response = CmdAutomationResponse.builderSuccess(request, "滑动解锁成功").withData(success);
|
||||
} else {
|
||||
response = CmdAutomationResponse.builderFailure(request, "滑动解锁失败").withData(success);
|
||||
}
|
||||
} finally {
|
||||
sendResultToEngine(response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTextDirectionText(CmdAutomationRequest request) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inputPasswordByOcr(CmdAutomationRequest request) {
|
||||
|
@ -821,9 +1025,6 @@ public class HarmonyAutomationHandler extends AbstractAutomationHandler {
|
|||
|
||||
private HarmonyProvider getHarmonyProvider() {
|
||||
HarmonyProvider provider = HarmonyDeviceManager.getInstance().getCurrentDeviceProvider(this.serial);
|
||||
if (null == provider) {
|
||||
throw new ExecuteException("当前设备已经掉线,请检查设备");
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
|
@ -902,11 +1103,14 @@ public class HarmonyAutomationHandler extends AbstractAutomationHandler {
|
|||
boolean alreadyFind = false;
|
||||
int screenIndex = 1;
|
||||
NodeList nodeList = null;
|
||||
HarmonyProvider harmonyProvider = getHarmonyProvider();
|
||||
if (null == harmonyProvider) {
|
||||
return null;
|
||||
}
|
||||
while (!alreadyFind) {
|
||||
int findIndex = 1;
|
||||
do {
|
||||
logger.debug("步骤:{},第{}屏,第{}次开始查找元素", request.getStepToken(), screenIndex, findIndex);
|
||||
HarmonyProvider harmonyProvider = getHarmonyProvider();
|
||||
UiComponent uiComponent = harmonyProvider.captureLayout();
|
||||
Document document = builder.newDocument();
|
||||
Node xmlElement = uiComponent.createXMLElement(document);
|
||||
|
|
|
@ -1699,6 +1699,16 @@ public class IosAutomationHandler extends AbstractAutomationHandler {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pressBack(CmdAutomationRequest request) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pressAppSwitch(CmdAutomationRequest request) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inputPasswordByOcr(CmdAutomationRequest request) {
|
||||
CmdAutomationResponse response = CmdAutomationResponse.builderFailure(request, "密码输入(ocr)失败").withData(false);
|
||||
|
|
|
@ -243,7 +243,7 @@ public class HarmonyMessageHandlerThread extends AbstractMessageHandler{
|
|||
success = harmonyProvider.pressHome();
|
||||
break;
|
||||
case "appSwitch":
|
||||
success = harmonyProvider.pressRecentApp();
|
||||
success = pressRecentApp(harmonyProvider);
|
||||
break;
|
||||
case "back":
|
||||
success = harmonyProvider.pressBack();
|
||||
|
@ -267,6 +267,24 @@ public class HarmonyMessageHandlerThread extends AbstractMessageHandler{
|
|||
logger.warn("设备【{}】热键【{}】操控失败............................",this.serial,key);
|
||||
}
|
||||
}
|
||||
private boolean pressRecentApp(HarmonyProvider harmonyProvider) {
|
||||
boolean success = false;
|
||||
int height = catchParam.getRealHeight();
|
||||
try {
|
||||
harmonyProvider.touchDown(200, height-10);
|
||||
Thread.sleep(200);
|
||||
for (float i = 0.01f; i <= 1; i +=0.01) {
|
||||
Float y = height - 10 - i * 300;
|
||||
harmonyProvider.touchMove(200, y.intValue());
|
||||
Thread.sleep(5);
|
||||
}
|
||||
Thread.sleep(200);
|
||||
success = harmonyProvider.touchUp(200, height - 10 - 300);
|
||||
} catch (InterruptedException e) {
|
||||
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inputType(CmdRequest request) {
|
||||
|
|
|
@ -601,5 +601,392 @@ public class HnosTools {
|
|||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>if存在控件执行点击</p>
|
||||
*
|
||||
* @param deviceDriver 设备驱动链接
|
||||
* @param targets 定位控件的信息
|
||||
* @param waitTimeout 默认超时时间
|
||||
* @param waitStatusStr 是否等待界面稳定
|
||||
* @param swipe 滑动方向
|
||||
* @param swipeCount 滑动次数
|
||||
* @param preExecuteWait 执行前等待
|
||||
* @param sufExecuteWait 执行后等待
|
||||
* @return
|
||||
*/
|
||||
@Keyword(alias = "if存在控件执行点击", category = "0", attributes = "7", commonlyUse = true)
|
||||
@Return(name = "result", comment = "点击结果", type = DataType.BOOLEAN)
|
||||
public boolean clickIfExistElement(IExecuteContext context,
|
||||
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
|
||||
@Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
|
||||
@Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
|
||||
@Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
|
||||
@Argument(name = "swipe", scope = ParamScope.ARGS, comment = "滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, required = false, defaultValue = "0", inputType = InputType.select, defaultDisplay = false) String swipe,
|
||||
@Argument(name = "swipeCount", scope = ParamScope.ARGS, comment = "滑动次数", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer swipeCount,
|
||||
// @Argument(name = "xMove", scope = ParamScope.ARGS, comment = "水平偏移量", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer xMove,
|
||||
// @Argument(name = "yMove", scope = ParamScope.ARGS, comment = "垂直偏移量", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer yMove,
|
||||
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float preExecuteWait,
|
||||
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float sufExecuteWait,
|
||||
@Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "", required = false) String value
|
||||
) {
|
||||
// 前端如果不选择元素,抛出异常
|
||||
if (CollectionUtils.isEmpty(targets)) {
|
||||
throw new ExecuteException("元素属性值为空!");
|
||||
}
|
||||
Boolean success = false;
|
||||
try {
|
||||
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
|
||||
boolean waitStatus = "1".equals(waitStatusStr); //是否等待界面稳定
|
||||
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
|
||||
.useContext(context)
|
||||
.withTargets(targets)
|
||||
.waitTimeout(waitTimeout)
|
||||
.searchSwipeDirection(swipe)
|
||||
.withSwipeCount(swipeCount)
|
||||
.waitStatus(waitStatus);
|
||||
success = AutomationHandleUtil.clickElement(param);
|
||||
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
|
||||
} catch (InterruptedException ie) {
|
||||
logger.warn("用户取消查询元素");
|
||||
throw new ExecuteException("取消操作");
|
||||
} catch (Exception e) {
|
||||
logger.error("出现了其他的问题。。。。", e);
|
||||
}
|
||||
if (success != null && !StringUtils.isEmpty(value)) {
|
||||
CommonUtils.setParamValue(context,value,success.toString());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>if存在控件执行输入文本</p>
|
||||
*
|
||||
* @param text 输入的文本
|
||||
* @param cleanStr 是否清空文本框0-否,1-是
|
||||
* @param deviceDriver 设备连接驱动
|
||||
* @param targets 定位控件参数
|
||||
* @param waitTimeout 超时时间
|
||||
* @param waitStatusStr 是否等待屏幕稳定
|
||||
* @param swipe 是否滑屏查找控件0-否,up-上滑,down-下滑,left-左滑,right-右滑
|
||||
* @param swipeCount 滑屏次数
|
||||
* @param preExecuteWait 执行前等待
|
||||
* @param sufExecuteWait 执行后等待
|
||||
* @return
|
||||
*/
|
||||
@Keyword(alias = "if存在控件执行输入文本", category = "0", attributes = "7", commonlyUse = true)
|
||||
@Return(name = "result", comment = "输入的结果", type = DataType.BOOLEAN)
|
||||
public boolean inputIfExistElement(IExecuteContext context,
|
||||
@Argument(name = "text", scope = ParamScope.VARIABLES, comment = "输入的文本", type = DataType.STRING) String text,
|
||||
@Argument(name = "clean", scope = ParamScope.ARGS, comment = "是否清空输入框", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String cleanStr,
|
||||
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
|
||||
@Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
|
||||
@Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
|
||||
@Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
|
||||
@Argument(name = "swipe", scope = ParamScope.ARGS, comment = "滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, inputType = InputType.select, defaultValue = "0", required = false, defaultDisplay = false) String swipe,
|
||||
@Argument(name = "swipeCount", scope = ParamScope.ARGS, comment = "滑动次数", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer swipeCount,
|
||||
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
|
||||
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait,
|
||||
@Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "", required = false) String value
|
||||
) {
|
||||
// 前端如果不选择元素,抛出异常
|
||||
if (CollectionUtils.isEmpty(targets)) {
|
||||
throw new ExecuteException("元素属性值为空!");
|
||||
}
|
||||
Boolean success = false;
|
||||
try {
|
||||
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
|
||||
boolean waitStatus = "1".equals(waitStatusStr); //是否等待界面稳定
|
||||
boolean clear = "1".equals(cleanStr); //是否清除文本框
|
||||
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
|
||||
.useContext(context)
|
||||
.withTargets(targets)
|
||||
.waitTimeout(waitTimeout)
|
||||
.searchSwipeDirection(swipe)
|
||||
.withSwipeCount(swipeCount)
|
||||
.clear(clear)
|
||||
.withInputTextValue(text)
|
||||
.waitStatus(waitStatus);
|
||||
success = AutomationHandleUtil.elementInput(param);
|
||||
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
|
||||
} catch (InterruptedException ie) {
|
||||
logger.warn("用户取消查询元素");
|
||||
throw new ExecuteException("取消操作");
|
||||
} catch (Exception e) {
|
||||
logger.error("出现了其他的问题。。。。", e);
|
||||
}
|
||||
if (success != null && !StringUtils.isEmpty(value)) {
|
||||
CommonUtils.setParamValue(context,value,success.toString());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* 滑动查找控件
|
||||
* @param context
|
||||
* @param direction
|
||||
* @param deviceDriver
|
||||
* @param targets
|
||||
* @param referencesStr
|
||||
* @param waitTimeout
|
||||
* @param index
|
||||
* @param waitStatusStr
|
||||
* @param value
|
||||
* @param preExecuteWait
|
||||
* @param sufExecuteWait
|
||||
* @return
|
||||
*/
|
||||
@Keyword(alias = "滑动查找控件", category = "0", attributes = "7",commonlyUse = true)
|
||||
@Return(name = "result", comment = "滑动的结果", type = DataType.OBJECT)
|
||||
public boolean swipeAndFindTargetElement(IExecuteContext context,
|
||||
@Argument(name = "direction", scope = ParamScope.ARGS, comment = "控件滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, inputType = InputType.select, defaultValue = "up") String direction,
|
||||
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
|
||||
@Argument(name = "targets", scope = ParamScope.STEP, comment = "目标元素", type = DataType.LIST, defaultDisplay = false,inputType = InputType.element) List<IStepTarget> targets,
|
||||
@Argument(name = "references", scope = ParamScope.ARGS, comment = "滑动元素", type = DataType.LIST, defaultDisplay = false, required = false,inputType = InputType.element) String referencesStr,
|
||||
@Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
|
||||
@Argument(name = "index", scope = ParamScope.ARGS, comment = "多个时定位第几个", type = DataType.INTEGER, defaultValue = "1",defaultDisplay = false) Integer index,
|
||||
@Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
|
||||
@Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值",required = false, type = DataType.STRING, defaultValue = "") String value,
|
||||
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
|
||||
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait) {
|
||||
logger.debug("拿到的reference为:{}",referencesStr);
|
||||
Boolean result = null;
|
||||
try {
|
||||
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
|
||||
boolean waitStatus = "1".equals(waitStatusStr); //是否等待界面稳定
|
||||
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
|
||||
.useContext(context)
|
||||
.withTargets(targets)
|
||||
.waitTimeout(waitTimeout)
|
||||
.searchSwipeDirection("0") //不滑动
|
||||
.withSwipeCount(1)
|
||||
.waitStatus(waitStatus)
|
||||
.swipeDirection(direction)
|
||||
.withIndex(index)
|
||||
.withReferences(referencesStr);
|
||||
result = AutomationHandleUtil.swipeAndFindTargetElement(param);
|
||||
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
|
||||
if (result != null && !StringUtils.isEmpty(value)) {
|
||||
CommonUtils.setParamValue(context,value,result.toString());
|
||||
}
|
||||
} catch (InterruptedException ie) {
|
||||
logger.warn("用户取消查询元素");
|
||||
throw new ExecuteException("取消操作");
|
||||
} catch (Exception e) {
|
||||
logger.error("出现了其他的问题。。。。", e);
|
||||
throw new ExecuteException(e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>滑动解锁</p>
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param deviceDriver 设备连接
|
||||
* @param firstPointStr 左上角点
|
||||
* @param secondPointStr 左上角右边的点
|
||||
* @param thirdPointStr 左上角下面的点
|
||||
* @param pointNum 每一行、列的点数
|
||||
* @param passingPoints 经过的点,填[1,3,5,6]数组的形式
|
||||
* @param waitTime 等待时间
|
||||
* @param preExecuteWait 执行前等待
|
||||
* @param sufExecuteWait 执行后等待
|
||||
* @return
|
||||
*/
|
||||
@Keyword(alias = "滑动解锁", category = "0", attributes = "7", commonlyUse = true)
|
||||
@Return(name = "result", comment = "是否滑动成功", type = DataType.BOOLEAN)
|
||||
public Boolean pressAndSwipe(
|
||||
IExecuteContext context,
|
||||
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
|
||||
@Argument(name = "firstPoint", scope = ParamScope.ARGS, comment = "第一排第一个点", type = DataType.LIST, defaultDisplay = true,inputType = InputType.element) String firstPointStr,
|
||||
@Argument(name = "secondPoint", scope = ParamScope.ARGS, comment = "第一排第二个点", type = DataType.LIST, defaultDisplay = true,inputType = InputType.element) String secondPointStr,
|
||||
@Argument(name = "thirdPoint", scope = ParamScope.ARGS, comment = "第二排第一个点", type = DataType.LIST, defaultDisplay = true,inputType = InputType.element) String thirdPointStr,
|
||||
@Argument(name = "pointNum", scope = ParamScope.ARGS, comment = "每一行、列的点数", type = DataType.INTEGER, defaultDisplay = false,defaultValue = "3") Integer pointNum,
|
||||
@Argument(name = "passingPoints", scope = ParamScope.ARGS, comment = "经过的点", type = DataType.LIST, defaultDisplay = true) List<Integer> passingPoints,
|
||||
@Argument(name = "waitTime", scope = ParamScope.ARGS, comment = "等待时间(单位s)", type = DataType.INTEGER, defaultValue = "30") Integer waitTime,
|
||||
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
|
||||
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait
|
||||
|
||||
) {
|
||||
Boolean result = false;
|
||||
try {
|
||||
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
|
||||
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
|
||||
.useContext(context)
|
||||
.waitTimeout(waitTime)
|
||||
.withPassingPoints(passingPoints)
|
||||
.withPointData(firstPointStr, secondPointStr, thirdPointStr)
|
||||
.withPointNum(pointNum);
|
||||
result = AutomationHandleUtil.pressAndSwipe(param);
|
||||
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
|
||||
} catch (InterruptedException ie) {
|
||||
logger.warn("用户取消查询元素");
|
||||
throw new ExecuteException("取消操作");
|
||||
} catch (Exception e) {
|
||||
logger.error("出现了其他的问题。。。。", e);
|
||||
throw new ExecuteException(e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>获取指定文字指定方向的内容</p>
|
||||
*
|
||||
* @param direction 滑动方向
|
||||
* @param deviceDriver 设备驱动
|
||||
* @param waitTimeout 默认超时时间
|
||||
* @param text 指定文本
|
||||
* @param direction 指定方向
|
||||
* @param preExecuteWait 执行前等待
|
||||
* @param sufExecuteWait 执行后等待
|
||||
* @return
|
||||
*/
|
||||
@Keyword(alias = "获取指定文字指定方向的内容", category = "0", attributes = "7")
|
||||
@Return(name = "result", comment = "返回的结果", type = DataType.BOOLEAN)
|
||||
public String getTextDirectionText(IExecuteContext context,
|
||||
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
|
||||
@Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
|
||||
@Argument(name = "index", scope = ParamScope.ARGS, comment = "第几个", type = DataType.INTEGER, defaultValue = "1") Integer index,
|
||||
@Argument(name = "text", comment = "指定文本", scope = ParamScope.ARGS, type = DataType.STRING) String text,
|
||||
@Argument(name = "direction", scope = ParamScope.ARGS, comment = "指定方向", type = DataType.ENUM, enumValues = TextDirection.class, inputType = InputType.select, defaultValue = "右") String direction,
|
||||
@Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "") String value,
|
||||
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
|
||||
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait) {
|
||||
String result = "";
|
||||
try {
|
||||
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
|
||||
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
|
||||
.useContext(context)
|
||||
.withText(text)
|
||||
.withIndex(index)
|
||||
.waitTimeout(waitTimeout)
|
||||
.withDirection(direction);
|
||||
result = AutomationHandleUtil.getTextDirectionText(param);
|
||||
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
|
||||
CommonUtils.setParamValue(context, value, result);
|
||||
} catch (InterruptedException ie) {
|
||||
logger.warn("用户取消查询元素");
|
||||
throw new ExecuteException("取消操作");
|
||||
} catch (Exception e) {
|
||||
logger.error("出现了其他的问题。。。。", e);
|
||||
throw new ExecuteException(e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>识别验证码</p>
|
||||
*
|
||||
* @param deviceDriver 设备连接驱动
|
||||
* @param targets 定位元素参数
|
||||
* @param waitTimeout 等待超时时间
|
||||
* @param value 赋值变量
|
||||
* @param preExecuteWait 执行前等待
|
||||
* @param sufExecuteWait 执行后等待
|
||||
* @return
|
||||
*/
|
||||
@Keyword(alias = "识别验证码", category = "0", attributes = "7")
|
||||
@Return(name = "result", comment = "验证码识别", type = DataType.STRING)
|
||||
public String getCodeByOcr(
|
||||
IExecuteContext context,
|
||||
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
|
||||
@Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
|
||||
@Argument(name = "codeType", scope = ParamScope.ARGS, comment = "验证码类型", type = DataType.INTEGER, required = false, defaultValue = "1", defaultDisplay = false) Integer codeType,
|
||||
@Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
|
||||
@Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "") String value,
|
||||
@Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
|
||||
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
|
||||
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait
|
||||
|
||||
) {
|
||||
String result = "";
|
||||
try {
|
||||
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
|
||||
boolean waitStatus = "1".equals(waitStatusStr); //是否等待界面稳定
|
||||
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
|
||||
.useContext(context)
|
||||
.withTargets(targets)
|
||||
.waitTimeout(waitTimeout)
|
||||
.codeType(codeType)
|
||||
.searchSwipeDirection("0") //不滑动
|
||||
.withSwipeCount(1)
|
||||
.waitStatus(waitStatus);
|
||||
result = AutomationHandleUtil.getVerificationCode(param);
|
||||
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
|
||||
CommonUtils.setParamValue(context, value, result);
|
||||
} catch (InterruptedException ie) {
|
||||
logger.warn("用户取消查询元素");
|
||||
throw new ExecuteException("取消操作");
|
||||
} catch (Exception e) {
|
||||
logger.error("出现了其他的问题。。。。", e);
|
||||
throw new ExecuteException(e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>点击返回键</p>
|
||||
*
|
||||
* @param deviceDriver 设备连接驱动
|
||||
* @param preExecuteWait 执行前等待
|
||||
* @param sufExecuteWait 执行后等待
|
||||
* @return
|
||||
*/
|
||||
@Keyword(alias = "点击返回键", category = "0", attributes = "7", commonlyUse = true)
|
||||
@Return(name = "result", comment = "点击返回键", type = DataType.BOOLEAN)
|
||||
public boolean pressKeyBack(IExecuteContext context,
|
||||
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
|
||||
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float preExecuteWait,
|
||||
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float sufExecuteWait) {
|
||||
boolean success = false;
|
||||
try {
|
||||
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
|
||||
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
|
||||
.useContext(context)
|
||||
.waitTimeout(30);
|
||||
success = AutomationHandleUtil.pressBack(param);
|
||||
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
|
||||
} catch (InterruptedException ie) {
|
||||
logger.warn("用户取消查询元素");
|
||||
throw new ExecuteException("取消操作");
|
||||
} catch (Exception e) {
|
||||
logger.error("出现了其他的问题。。。。", e);
|
||||
throw new ExecuteException(e.getMessage());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>点击返回键</p>
|
||||
*
|
||||
* @param deviceDriver 设备连接驱动
|
||||
* @param preExecuteWait 执行前等待
|
||||
* @param sufExecuteWait 执行后等待
|
||||
* @return
|
||||
*/
|
||||
@Keyword(alias = "点击多任务", category = "0", attributes = "7", commonlyUse = true)
|
||||
@Return(name = "result", comment = "点击多任务", type = DataType.BOOLEAN)
|
||||
public boolean pressKeyMenu(IExecuteContext context,
|
||||
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
|
||||
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float preExecuteWait,
|
||||
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float sufExecuteWait) {
|
||||
boolean success = false;
|
||||
try {
|
||||
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
|
||||
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
|
||||
.useContext(context)
|
||||
.waitTimeout(30);
|
||||
success = AutomationHandleUtil.pressAppSwitch(param);
|
||||
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
|
||||
} catch (InterruptedException ie) {
|
||||
logger.warn("用户取消查询元素");
|
||||
throw new ExecuteException("取消操作");
|
||||
} catch (Exception e) {
|
||||
logger.error("出现了其他的问题。。。。", e);
|
||||
throw new ExecuteException(e.getMessage());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -428,6 +428,10 @@ public class AutomationHandleUtil {
|
|||
logger.warn("不支持的查找元素方式:{}", target.getUsing());
|
||||
break;
|
||||
}
|
||||
if (null != point) {
|
||||
logger.debug("使用【{}】方式找到了控件",target.getUsing());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
@ -799,6 +803,30 @@ public class AutomationHandleUtil {
|
|||
return success;
|
||||
}
|
||||
|
||||
public static boolean pressBack(ElementHandleParam param) throws Exception {
|
||||
Boolean success = false;
|
||||
String token = UUID.randomUUID().toString();
|
||||
CmdAutomationRequest builder = CmdAutomationRequest.builder(AutomationRequestCmd.PRESS_BACK_KEY, token, new HashMap<>());
|
||||
Object o = sendUpperMessageAndWaitReturn(param.getDeviceDriver(), builder, token, param.getWaitTimeout());
|
||||
logger.debug("点击返回键的结果:{}",o);
|
||||
if (null != o) {
|
||||
success = JSONObject.parseObject(JSONObject.toJSONString(o), Boolean.class);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
public static boolean pressAppSwitch(ElementHandleParam param) throws Exception {
|
||||
Boolean success = false;
|
||||
String token = UUID.randomUUID().toString();
|
||||
CmdAutomationRequest builder = CmdAutomationRequest.builder(AutomationRequestCmd.PRESS_APP_SWITCH_KEY, token, new HashMap<>());
|
||||
Object o = sendUpperMessageAndWaitReturn(param.getDeviceDriver(), builder, token, param.getWaitTimeout());
|
||||
logger.debug("点击多任务键的结果:{}",o);
|
||||
if (null != o) {
|
||||
success = JSONObject.parseObject(JSONObject.toJSONString(o), Boolean.class);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
private static boolean longPressElementByPoint(DeviceDriver deviceDriver, PointMessage point, Integer waitTimeout) throws Exception{
|
||||
Boolean success = false;
|
||||
String token = UUID.randomUUID().toString();
|
||||
|
@ -1165,7 +1193,7 @@ public class AutomationHandleUtil {
|
|||
if (null == waitTimeout || waitTimeout <= 0) {
|
||||
param.setWaitTimeout(30);
|
||||
}
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
String referenceStr = param.getReferences();
|
||||
logger.debug("执行滑动查找控件的操作,滑动控件:{}", referenceStr);
|
||||
PointMessage point = null;
|
||||
|
@ -1182,22 +1210,28 @@ public class AutomationHandleUtil {
|
|||
}
|
||||
}
|
||||
logger.debug("找到要滑动的控件位置:{}",JSON.toJSONString(point));
|
||||
PointMessage targetPoint = swipeToFindTargetElement(point, param.getContext(), param.getDeviceDriver(), param.getTargets(), param.getWaitTimeout(),
|
||||
long endTime = System.currentTimeMillis();
|
||||
long remainingTime = param.getWaitTimeout() * 1000 - (endTime - startTime);
|
||||
PointMessage targetPoint = swipeToFindTargetElement(point, param.getContext(), param.getDeviceDriver(), param.getTargets(), remainingTime,
|
||||
param.getSwipeDirection(), param);
|
||||
getRedDotScreenShotWithPoint(param, point);
|
||||
return targetPoint != null;
|
||||
}
|
||||
|
||||
private static PointMessage swipeToFindTargetElement(PointMessage swipePoint, IExecuteContext context, DeviceDriver driver, List<IStepTarget> targets, Integer waitTimeout, String direction, ElementHandleParam param) throws Exception{
|
||||
private static PointMessage swipeToFindTargetElement(PointMessage swipePoint, IExecuteContext context, DeviceDriver driver, List<IStepTarget> targets, Long waitTimeout, String direction, ElementHandleParam param) throws Exception{
|
||||
logger.debug("执行滑动查找控件的操作,目标控件:{}", JSON.toJSONString(targets));
|
||||
long startTime = System.currentTimeMillis();
|
||||
long endTime = System.currentTimeMillis();
|
||||
PointMessage targetPoint = null;
|
||||
Double perWaiTimeOut = waitTimeout.doubleValue() / 1000 / 5;
|
||||
if (perWaiTimeOut < 3) {
|
||||
perWaiTimeOut = 3.0;
|
||||
}
|
||||
int num = 1;
|
||||
do {
|
||||
logger.debug("开始第{}次查找", num);
|
||||
try {
|
||||
targetPoint = findElementByTargetsForSwipe(param.getDeviceDriver(), param.getTargets(), 30, param.getSwipe(), param.getSwipeCount(), 1);
|
||||
targetPoint = findElementByTargetsForSwipe(param.getDeviceDriver(), param.getTargets(), perWaiTimeOut.intValue(), param.getSwipe(), param.getSwipeCount(), 1);
|
||||
} catch (Exception ignore) {
|
||||
logger.error(ignore.getMessage());
|
||||
}
|
||||
|
@ -1208,7 +1242,7 @@ public class AutomationHandleUtil {
|
|||
}
|
||||
num++;
|
||||
endTime = System.currentTimeMillis();
|
||||
} while (targetPoint == null && endTime - startTime < waitTimeout * 1000);
|
||||
} while (targetPoint == null && endTime - startTime < waitTimeout);
|
||||
logger.debug("在规定的时间内查找的结果:{}", JSON.toJSONString(targetPoint));
|
||||
return targetPoint;
|
||||
}
|
||||
|
@ -1227,8 +1261,8 @@ public class AutomationHandleUtil {
|
|||
String token = UUID.randomUUID().toString();
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
if (swipePoint != null) {
|
||||
Integer x = swipePoint.getXOriginal();
|
||||
Integer y = swipePoint.getYOriginal();
|
||||
Integer x = swipePoint.getX();
|
||||
Integer y = swipePoint.getY();
|
||||
paramMap.put(UpperParamKey.X, x);
|
||||
paramMap.put(UpperParamKey.Y, y);
|
||||
paramMap.put(UpperParamKey.SWIPE_DIRECTION, direction);
|
||||
|
|
Loading…
Reference in New Issue