From 3191bd8863d663f344b964221c055d246f473ac8 Mon Sep 17 00:00:00 2001
From: YeungKhaiChiu <1005935991@qq.com>
Date: Sat, 1 Jun 2024 16:47:41 +0800
Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0adb=E5=92=8Cuia?=
=?UTF-8?q?=E7=9A=84drag=20and=20drop=E6=93=8D=E4=BD=9C=EF=BC=88=E7=9C=9F-?=
=?UTF-8?q?=E6=8B=96=E6=8B=BD=E5=85=83=E7=B4=A0=E6=93=8D=E4=BD=9C=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 2 +-
.../tests/handlers/AndroidStepHandler.java | 56 +++++++++++++---
.../tests/handlers/AndroidTouchHandler.java | 64 ++++++++++++++++++-
3 files changed, 111 insertions(+), 11 deletions(-)
diff --git a/pom.xml b/pom.xml
index 24d6a54b..24222dca 100644
--- a/pom.xml
+++ b/pom.xml
@@ -78,7 +78,7 @@
io.github.soniccloudorg
sonic-driver-core
- 1.1.29
+ 1.1.30
net.coobird
diff --git a/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidStepHandler.java b/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidStepHandler.java
index 33798cb2..9bb5374b 100755
--- a/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidStepHandler.java
+++ b/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidStepHandler.java
@@ -721,8 +721,8 @@ public void swipePoint(HandleContext handleContext, String des1, String xy1, Str
double x2 = Double.parseDouble(xy2.substring(0, xy2.indexOf(",")));
double y2 = Double.parseDouble(xy2.substring(xy2.indexOf(",") + 1));
int[] point2 = computedPoint(x2, y2);
- handleContext.setStepDes("滑动拖拽" + des1 + "到" + des2);
- handleContext.setDetail("拖动坐标(" + point1[0] + "," + point1[1] + ")到(" + point2[0] + "," + point2[1] + ")");
+ handleContext.setStepDes("从" + des1 + "滑动到" + des2);
+ handleContext.setDetail("从坐标(" + point1[0] + "," + point1[1] + ")滑动到(" + point2[0] + "," + point2[1] + ")");
try {
AndroidTouchHandler.swipe(iDevice, point1[0], point1[1], point2[0], point2[1]);
} catch (Exception e) {
@@ -738,14 +738,46 @@ public void swipe(HandleContext handleContext, String des, String selector, Stri
int y1 = webElement.getRect().getY();
int x2 = webElement2.getRect().getX();
int y2 = webElement2.getRect().getY();
- handleContext.setStepDes("滑动拖拽" + des + "到" + des2);
- handleContext.setDetail("拖动坐标(" + x1 + "," + y1 + ")到(" + x2 + "," + y2 + ")");
+ handleContext.setStepDes("从" + des + "滑动到" + des2);
+ handleContext.setDetail("从坐标(" + x1 + "," + y1 + ")滑动到坐标(" + x2 + "," + y2 + ")");
AndroidTouchHandler.swipe(iDevice, x1, y1, x2, y2);
} catch (Exception e) {
handleContext.setE(e);
}
}
+ public void dragByPoint(HandleContext handleContext, String des1, String xy1, String des2, String xy2) {
+ double x1 = Double.parseDouble(xy1.substring(0, xy1.indexOf(",")));
+ double y1 = Double.parseDouble(xy1.substring(xy1.indexOf(",") + 1));
+ int[] point1 = computedPoint(x1, y1);
+ double x2 = Double.parseDouble(xy2.substring(0, xy2.indexOf(",")));
+ double y2 = Double.parseDouble(xy2.substring(xy2.indexOf(",") + 1));
+ int[] point2 = computedPoint(x2, y2);
+ handleContext.setStepDes("拖拽" + des1 + "到" + des2);
+ handleContext.setDetail("拖拽坐标(" + point1[0] + "," + point1[1] + ")到(" + point2[0] + "," + point2[1] + ")");
+ try {
+ AndroidTouchHandler.drag(iDevice, point1[0], point1[1], point2[0], point2[1]);
+ } catch (Exception e) {
+ handleContext.setE(e);
+ }
+ }
+
+ public void dragByEle(HandleContext handleContext, String des, String selector, String pathValue, String des2, String selector2, String pathValue2) {
+ try {
+ AndroidElement webElement = findEle(selector, pathValue);
+ AndroidElement webElement2 = findEle(selector2, pathValue2);
+ int x1 = webElement.getRect().getX();
+ int y1 = webElement.getRect().getY();
+ int x2 = webElement2.getRect().getX();
+ int y2 = webElement2.getRect().getY();
+ handleContext.setStepDes("拖拽" + des + "到" + des2);
+ handleContext.setDetail("拖拽坐标(" + x1 + "," + y1 + ")到(" + x2 + "," + y2 + ")");
+ AndroidTouchHandler.drag(iDevice, x1, y1, x2, y2);
+ } catch (SonicRespException e) {
+ handleContext.setE(e);
+ }
+ }
+
public void swipeByDefinedDirection(HandleContext handleContext, String slideDirection, int distance) throws Exception {
String size = AndroidDeviceBridgeTool.getScreenSize(iDevice);
String[] winSize = size.split("x");
@@ -771,7 +803,7 @@ public void swipeByDefinedDirection(HandleContext handleContext, String slideDir
} catch (Exception e) {
handleContext.setE(e);
}
- handleContext.setDetail("拖动坐标(" + centerX + "," + centerY + ")到(" + centerX + "," + targetY + ")");
+ handleContext.setDetail("从坐标(" + centerX + "," + centerY + ")滑动到坐标(" + centerX + "," + targetY + ")");
}
case "down" -> {
handleContext.setStepDes("从设备中心位置向下滑动" + distance + "像素");
@@ -785,7 +817,7 @@ public void swipeByDefinedDirection(HandleContext handleContext, String slideDir
} catch (Exception e) {
handleContext.setE(e);
}
- handleContext.setDetail("拖动坐标(" + centerX + "," + centerY + ")到(" + centerX + "," + targetY + ")");
+ handleContext.setDetail("从坐标(" + centerX + "," + centerY + ")滑动到(" + centerX + "," + targetY + ")");
}
case "left" -> {
handleContext.setStepDes("从设备中心位置向左滑动" + distance + "像素");
@@ -799,7 +831,7 @@ public void swipeByDefinedDirection(HandleContext handleContext, String slideDir
} catch (Exception e) {
handleContext.setE(e);
}
- handleContext.setDetail("拖动坐标(" + centerX + "," + centerY + ")到(" + targetX + "," + centerY + ")");
+ handleContext.setDetail("从坐标(" + centerX + "," + centerY + ")滑动到(" + targetX + "," + centerY + ")");
}
case "right" -> {
handleContext.setStepDes("从设备中心位置向右滑动" + distance + "像素");
@@ -813,7 +845,7 @@ public void swipeByDefinedDirection(HandleContext handleContext, String slideDir
} catch (Exception e) {
handleContext.setE(e);
}
- handleContext.setDetail("拖动坐标(" + centerX + "," + centerY + ")到(" + targetX + "," + centerY + ")");
+ handleContext.setDetail("从坐标(" + centerX + "," + centerY + ")滑动到(" + targetX + "," + centerY + ")");
}
default ->
throw new Exception("Sliding in this direction is not supported. Only up/down/left/right are supported!");
@@ -1767,7 +1799,7 @@ public void getPocoElementAttr(HandleContext handleContext, String des, String s
}
public void obtainPocoElementAttr(HandleContext handleContext, String des, String selector, String pathValue,
- String attr, String variable) {
+ String attr, String variable) {
handleContext.setStepDes("获取控件 " + des + " 属性到变量");
handleContext.setDetail("目标属性:" + attr + ",目标变量:" + variable);
try {
@@ -2463,6 +2495,12 @@ public void runStep(JSONObject stepJSON, HandleContext handleContext) throws Thr
case "swipe2" ->
swipe(handleContext, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleType"), eleList.getJSONObject(0).getString("eleValue")
, eleList.getJSONObject(1).getString("eleName"), eleList.getJSONObject(1).getString("eleType"), eleList.getJSONObject(1).getString("eleValue"));
+ case "drag" ->
+ dragByPoint(handleContext, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleValue")
+ , eleList.getJSONObject(1).getString("eleName"), eleList.getJSONObject(1).getString("eleValue"));
+ case "drag2" ->
+ dragByEle(handleContext, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleType"), eleList.getJSONObject(0).getString("eleValue")
+ , eleList.getJSONObject(1).getString("eleName"), eleList.getJSONObject(1).getString("eleType"), eleList.getJSONObject(1).getString("eleValue"));
case "tap" ->
tap(handleContext, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleValue"));
case "longPressPoint" ->
diff --git a/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidTouchHandler.java b/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidTouchHandler.java
index c67297c2..a771525c 100755
--- a/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidTouchHandler.java
+++ b/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidTouchHandler.java
@@ -118,7 +118,7 @@ public static void swipe(IDevice iDevice, int x1, int y1, int x2, int y2, int sw
int[] re2 = transferWithRotation(iDevice, x2, y2);
writeToOutputStream(iDevice, String.format("down %d %d\n", re1[0], re1[1]));
try {
- Thread.sleep(300);
+ Thread.sleep(5); // 滑动效果不需要长按300ms
} catch (InterruptedException e) {
e.printStackTrace();
}
@@ -167,6 +167,68 @@ public static void swipe(IDevice iDevice, int x1, int y1, int x2, int y2, int sw
}
}
+ public static void drag(IDevice iDevice, int x1, int y1, int x2, int y2) throws SonicRespException {
+ drag(iDevice, x1, y1, x2, y2, DEFAULT_SWIPE_DURATION);
+ }
+
+ public static void drag(IDevice iDevice, int x1, int y1, int x2, int y2, int swipeDuration) throws SonicRespException {
+ switch (getTouchMode(iDevice)) {
+ case ADB ->
+ AndroidDeviceBridgeTool.executeCommand(iDevice, String.format("input draganddrop %d %d %d %d %d", x1, y1, x2, y2, swipeDuration));
+ case APPIUM_UIAUTOMATOR2_SERVER -> {
+ AndroidStepHandler curStepHandler = HandlerMap.getAndroidMap().get(iDevice.getSerialNumber());
+ if (curStepHandler != null && curStepHandler.getAndroidDriver() != null) {
+ curStepHandler.getAndroidDriver().drag(x1, y1, x2, y2, swipeDuration, null, null);
+ }
+ }
+ case SONIC_APK -> {
+ // 原本这段代码是在`swipe(IDevice iDevice, int x1, int y1, int x2, int y2, int swipeDuration)`中的
+ // 但是swipe的效果应该是在屏幕滑动,而不是在第一个坐标按下时存在延迟,所以放在drag方法里面更加符合
+ int[] re1 = transferWithRotation(iDevice, x1, y1);
+ int[] re2 = transferWithRotation(iDevice, x2, y2);
+ writeToOutputStream(iDevice, String.format("down %d %d\n", re1[0], re1[1]));
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ long startTime = System.currentTimeMillis();
+ while (true) {
+ // 当前时间
+ long currentTime = System.currentTimeMillis();
+ // 计算时间进度
+ float timeProgress = (currentTime - startTime) / (float) swipeDuration;
+ if (timeProgress >= 1.0f) {
+ // 已经过渡到结束值,停止过渡
+ writeToOutputStream(iDevice, String.format("move %d %d\n", re2[0], re2[1]));
+ break;
+ }
+ BiFunction transitionX = (start, end) ->
+ (int) (start + (end - start) * timeProgress);
+ BiFunction transitionY = (start, end) ->
+ (int) (start + (end - start) * timeProgress);
+
+ int currentX = transitionX.apply(re1[0], re2[0]);
+ int currentY = transitionY.apply(re1[1], re2[1]);
+ // 使用当前坐标进行操作
+ writeToOutputStream(iDevice, String.format("move %d %d\n", currentX, currentY));
+ try {
+ Thread.sleep(5);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ writeToOutputStream(iDevice, "up\n");
+ }
+
+ }
+ }
+
private static int[] transferWithRotation(IDevice iDevice, int x, int y) {
Integer directionStatus = AndroidDeviceManagerMap.getRotationMap().get(iDevice.getSerialNumber());
if (directionStatus == null) {
From 6eed398567ceb9406be8e4e123c52ad18927ba72 Mon Sep 17 00:00:00 2001
From: YeungHoiChiu <1005935991@qq.com>
Date: Mon, 3 Jun 2024 17:51:00 +0800
Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E5=AE=89=E5=8D=93=E5=A2=9E?=
=?UTF-8?q?=E5=8A=A0=E8=A7=A6=E6=8E=A7=E6=89=8B=E5=8A=BF=E5=8A=A8=E4=BD=9C?=
=?UTF-8?q?=E7=8B=AC=E7=AB=8B=E4=BA=8B=E4=BB=B6=EF=BC=88adb=20motionevent?=
=?UTF-8?q?=20down=E6=8C=89=E4=B8=8B=E4=B8=8D=E6=9D=BE=E6=89=8B=E3=80=81up?=
=?UTF-8?q?=E6=9D=BE=E6=89=8B=E4=BB=A5=E5=8F=8Amove=E7=A7=BB=E5=8A=A8?=
=?UTF-8?q?=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../tests/handlers/AndroidStepHandler.java | 59 +++++++++++++++----
.../tests/handlers/AndroidTouchHandler.java | 17 ++++++
2 files changed, 63 insertions(+), 13 deletions(-)
diff --git a/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidStepHandler.java b/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidStepHandler.java
index 9bb5374b..17a71eae 100755
--- a/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidStepHandler.java
+++ b/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidStepHandler.java
@@ -70,6 +70,7 @@
import org.springframework.util.CollectionUtils;
import javax.imageio.stream.FileImageOutputStream;
+import java.awt.desktop.AboutHandler;
import java.io.File;
import java.util.*;
import java.util.concurrent.Future;
@@ -427,7 +428,7 @@ public void appAutoGrantPermissions(HandleContext handleContext, String packageN
String getDetailCommandResult = AndroidDeviceBridgeTool.executeCommand(iDevice, dumpsysCommandStr);
List allPermissionItems =
AndroidPermissionExtractor.extractPermissions(getDetailCommandResult,
- Arrays.asList("install", "runtime"), true);
+ Arrays.asList("install", "runtime"), true);
allPermissionItems.stream().filter(permissionItem -> !permissionItem.isGranted())
.forEach(permissionItem -> {
String curPermission = permissionItem.getPermission();
@@ -778,6 +779,32 @@ public void dragByEle(HandleContext handleContext, String des, String selector,
}
}
+ public void motionEventByPoint(HandleContext handleContext, String des, String xy, String motionEventType) throws SonicRespException {
+ double x = Double.parseDouble(xy.substring(0, xy.indexOf(",")));
+ double y = Double.parseDouble(xy.substring(xy.indexOf(",") + 1));
+ int[] point = computedPoint(x, y);
+ handleContext.setStepDes("通过坐标" + des + "触发" + motionEventType + "-Motion事件");
+ handleContext.setDetail("对坐标" + point[0] + "," + point[1] + String.format("执行Motion事件(%s)", motionEventType));
+ try {
+ AndroidTouchHandler.motionEvent(iDevice, motionEventType, point[0], point[1]);
+ } catch (SonicRespException e) {
+ handleContext.setE(e);
+ }
+ }
+
+ public void motionEventByEle(HandleContext handleContext, String des, String selector, String pathValue, String motionEventType) throws SonicRespException {
+ try {
+ AndroidElement webElement = findEle(selector, pathValue);
+ int x = webElement.getRect().getX();
+ int y = webElement.getRect().getY();
+ handleContext.setStepDes("通过" + des + "触发" + motionEventType + "-Motion事件");
+ handleContext.setDetail("对坐标" + x + "," + y + String.format("执行Motion事件(%s)", motionEventType));
+ AndroidTouchHandler.motionEvent(iDevice, motionEventType, x, y);
+ } catch (SonicRespException e) {
+ handleContext.setE(e);
+ }
+ }
+
public void swipeByDefinedDirection(HandleContext handleContext, String slideDirection, int distance) throws Exception {
String size = AndroidDeviceBridgeTool.getScreenSize(iDevice);
String[] winSize = size.split("x");
@@ -2061,10 +2088,12 @@ public AndroidElement findEle(String selector, String pathValue, Integer retryTi
switch (selector) {
case "androidIterator" -> we = androidDriver.findElement(pathValue);
case "id" -> we = androidDriver.findElement(AndroidSelector.Id, pathValue, retryTime);
- case "accessibilityId" -> we = androidDriver.findElement(AndroidSelector.ACCESSIBILITY_ID, pathValue, retryTime);
+ case "accessibilityId" ->
+ we = androidDriver.findElement(AndroidSelector.ACCESSIBILITY_ID, pathValue, retryTime);
case "xpath" -> we = androidDriver.findElement(AndroidSelector.XPATH, pathValue, retryTime);
case "className" -> we = androidDriver.findElement(AndroidSelector.CLASS_NAME, pathValue, retryTime);
- case "androidUIAutomator" -> we = androidDriver.findElement(AndroidSelector.UIAUTOMATOR, pathValue, retryTime);
+ case "androidUIAutomator" ->
+ we = androidDriver.findElement(AndroidSelector.UIAUTOMATOR, pathValue, retryTime);
default ->
log.sendStepLog(StepType.ERROR, "查找控件元素失败", "这个控件元素类型: " + selector + " 不存在!!!");
}
@@ -2456,10 +2485,9 @@ public void runStep(JSONObject stepJSON, HandleContext handleContext) throws Thr
case "getElementAttr" ->
getElementAttr(handleContext, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleType")
, eleList.getJSONObject(0).getString("eleValue"), step.getString("text"), step.getString("content"));
- case "obtainElementAttr" ->
- obtainElementAttr(handleContext, eleList.getJSONObject(0).getString("eleName"),
- eleList.getJSONObject(0).getString("eleType"), eleList.getJSONObject(0).getString("eleValue"),
- step.getString("text"), step.getString("content"));
+ case "obtainElementAttr" -> obtainElementAttr(handleContext, eleList.getJSONObject(0).getString("eleName"),
+ eleList.getJSONObject(0).getString("eleType"), eleList.getJSONObject(0).getString("eleValue"),
+ step.getString("text"), step.getString("content"));
case "logElementAttr" ->
logElementAttr(handleContext, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleType")
, eleList.getJSONObject(0).getString("eleValue"), step.getString("text"));
@@ -2472,12 +2500,11 @@ public void runStep(JSONObject stepJSON, HandleContext handleContext) throws Thr
case "isExistEle" ->
isExistEle(handleContext, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleType")
, eleList.getJSONObject(0).getString("eleValue"), step.getBoolean("content"));
- case "scrollToEle" ->
- scrollToEle(handleContext, eleList.getJSONObject(0).getString("eleName"),
- eleList.getJSONObject(0).getString("eleType"),
- eleList.getJSONObject(0).getString("eleValue"),
- step.getInteger("content"),
- step.getString("text"));
+ case "scrollToEle" -> scrollToEle(handleContext, eleList.getJSONObject(0).getString("eleName"),
+ eleList.getJSONObject(0).getString("eleType"),
+ eleList.getJSONObject(0).getString("eleValue"),
+ step.getInteger("content"),
+ step.getString("text"));
case "isExistEleNum" -> isExistEleNum(handleContext, eleList.getJSONObject(0).getString("eleName"),
eleList.getJSONObject(0).getString("eleType"),
eleList.getJSONObject(0).getString("eleValue"),
@@ -2501,6 +2528,12 @@ public void runStep(JSONObject stepJSON, HandleContext handleContext) throws Thr
case "drag2" ->
dragByEle(handleContext, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleType"), eleList.getJSONObject(0).getString("eleValue")
, eleList.getJSONObject(1).getString("eleName"), eleList.getJSONObject(1).getString("eleType"), eleList.getJSONObject(1).getString("eleValue"));
+ case "motionEvent" -> motionEventByEle(handleContext, eleList.getJSONObject(0).getString("eleName"),
+ eleList.getJSONObject(0).getString("eleType"), eleList.getJSONObject(0).getString("eleValue"), eleList.getJSONObject(0).getString("text"));
+ case "motionEventByPoint" ->
+ motionEventByPoint(handleContext, eleList.getJSONObject(0).getString("eleName"),
+ eleList.getJSONObject(0).getString("eleValue"),
+ eleList.getJSONObject(0).getString("text"));
case "tap" ->
tap(handleContext, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleValue"));
case "longPressPoint" ->
diff --git a/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidTouchHandler.java b/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidTouchHandler.java
index a771525c..296d1c77 100755
--- a/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidTouchHandler.java
+++ b/src/main/java/org/cloud/sonic/agent/tests/handlers/AndroidTouchHandler.java
@@ -229,6 +229,23 @@ public static void drag(IDevice iDevice, int x1, int y1, int x2, int y2, int swi
}
}
+ public static void motionEvent(IDevice iDevice, String motionEventType, int x1, int y1) throws SonicRespException {
+ switch (getTouchMode(iDevice)) {
+ case ADB ->
+ AndroidDeviceBridgeTool.executeCommand(iDevice, String.format("input motionevent %s %d %d", motionEventType, x1, y1));
+ case SONIC_APK -> {
+ int[] re1 = transferWithRotation(iDevice, x1, y1);
+ writeToOutputStream(iDevice, String.format("%s %d %d\n", motionEventType.toLowerCase(), re1[0], re1[1]));
+ }
+ case APPIUM_UIAUTOMATOR2_SERVER -> {
+ AndroidStepHandler curStepHandler = HandlerMap.getAndroidMap().get(iDevice.getSerialNumber());
+ if (curStepHandler != null && curStepHandler.getAndroidDriver() != null) {
+ curStepHandler.getAndroidDriver().touchAction(motionEventType.toLowerCase(), x1, y1);
+ }
+ }
+ }
+ }
+
private static int[] transferWithRotation(IDevice iDevice, int x, int y) {
Integer directionStatus = AndroidDeviceManagerMap.getRotationMap().get(iDevice.getSerialNumber());
if (directionStatus == null) {