From a622682f34da7d0d7c9829aeedad51389b8644d0 Mon Sep 17 00:00:00 2001 From: ZhouYixun <291028775@qq.com> Date: Sun, 30 Oct 2022 16:37:52 +0800 Subject: [PATCH 01/12] feat: add sib proxy tool and ios poco support --- .../agent/automation/AndroidStepHandler.java | 1 + .../agent/automation/IOSStepHandler.java | 235 +++++++++++++++++- .../cloud/sonic/agent/bridge/ios/SibTool.java | 85 +++++++ .../sonic/agent/websockets/IOSWSServer.java | 17 ++ 4 files changed, 331 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java b/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java index 8435eb73..02b37524 100644 --- a/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java +++ b/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java @@ -152,6 +152,7 @@ public void closeAndroidDriver() { } if (pocoDriver != null) { pocoDriver.closeDriver(); + AndroidDeviceBridgeTool.removeForward(iDevice, pocoPort, targetPort); pocoDriver = null; } if (androidDriver != null) { diff --git a/src/main/java/org/cloud/sonic/agent/automation/IOSStepHandler.java b/src/main/java/org/cloud/sonic/agent/automation/IOSStepHandler.java index ff7d74ca..c3246cb3 100644 --- a/src/main/java/org/cloud/sonic/agent/automation/IOSStepHandler.java +++ b/src/main/java/org/cloud/sonic/agent/automation/IOSStepHandler.java @@ -32,6 +32,7 @@ import org.cloud.sonic.agent.tests.handlers.StepHandlers; import org.cloud.sonic.agent.tests.script.GroovyScript; import org.cloud.sonic.agent.tests.script.GroovyScriptImpl; +import org.cloud.sonic.agent.tools.PortTool; import org.cloud.sonic.agent.tools.ProcessCommandTool; import org.cloud.sonic.agent.tools.SpringTool; import org.cloud.sonic.agent.tools.file.DownloadTool; @@ -43,6 +44,10 @@ import org.cloud.sonic.driver.ios.enums.IOSSelector; import org.cloud.sonic.driver.ios.enums.SystemButton; import org.cloud.sonic.driver.ios.service.IOSElement; +import org.cloud.sonic.driver.poco.PocoDriver; +import org.cloud.sonic.driver.poco.enums.PocoEngine; +import org.cloud.sonic.driver.poco.enums.PocoSelector; +import org.cloud.sonic.driver.poco.models.PocoElement; import org.cloud.sonic.vision.cv.AKAZEFinder; import org.cloud.sonic.vision.cv.SIFTFinder; import org.cloud.sonic.vision.cv.SimilarityChecker; @@ -70,10 +75,13 @@ public class IOSStepHandler { public LogUtil log = new LogUtil(); private IOSDriver iosDriver; + private PocoDriver pocoDriver = null; private JSONObject globalParams = new JSONObject(); private String udId = ""; - private int status = ResultDetailStatus.PASS; + private int[] screenWindowPosition = {0, 0, 0, 0}; + private int pocoPort = 0; + private int targetPort = 0; public LogUtil getLog() { return log; @@ -115,6 +123,11 @@ public void closeIOSDriver() { iosDriver.closeDriver(); log.sendStepLog(StepType.PASS, "退出连接设备", ""); } + if (pocoDriver != null) { + pocoDriver.closeDriver(); + SibTool.stopProxy(udId, targetPort); + pocoDriver = null; + } } catch (Exception e) { log.sendStepLog(StepType.WARN, "测试终止异常!请检查设备连接状态", ""); //测试异常 @@ -746,6 +759,188 @@ public void publicStep(HandleDes handleDes, String name, JSONArray stepArray) { log.sendStepLog(StepType.WARN, "公共步骤「" + name + "」执行完毕", ""); } + public void startPocoDriver(HandleDes handleDes, String engine, int port) { + handleDes.setStepDes("启动PocoDriver"); + handleDes.setDetail(""); + if (pocoPort == 0) { + pocoPort = PortTool.getPort(); + } + targetPort = port; + SibTool.proxy(udId, pocoPort, targetPort); + pocoDriver = new PocoDriver(PocoEngine.valueOf(engine), pocoPort); + } + + public PocoElement findPocoEle(String selector, String pathValue) throws Throwable { + PocoElement pocoElement = null; + pathValue = TextHandler.replaceTrans(pathValue, globalParams); + pocoDriver.getPageSourceForXmlElement(); + try { + switch (selector) { + case "poco": + pocoElement = pocoDriver.findElement(PocoSelector.POCO, pathValue); + break; + case "xpath": + pocoElement = pocoDriver.findElement(PocoSelector.XPATH, pathValue); + break; + case "cssSelector": + pocoElement = pocoDriver.findElement(PocoSelector.CSS_SELECTOR, pathValue); + break; + default: + log.sendStepLog(StepType.ERROR, "查找控件元素失败", "这个控件元素类型: " + selector + " 不存在!!!"); + break; + } + } catch (Throwable e) { + throw e; + } + return pocoElement; + } + + public void isExistPocoEle(HandleDes handleDes, String des, String selector, String value, boolean expect) { + handleDes.setStepDes("判断控件 " + des + " 是否存在"); + handleDes.setDetail("期望值:" + (expect ? "存在" : "不存在")); + boolean hasEle = false; + try { + PocoElement w = findPocoEle(selector, value); + if (w != null) { + hasEle = true; + } + } catch (Throwable e) { + } + try { + assertEquals(hasEle, expect); + } catch (AssertionError e) { + handleDes.setE(e); + } + } + + public void pocoClick(HandleDes handleDes, String des, String selector, String value) { + handleDes.setStepDes("点击" + des); + handleDes.setDetail("点击 " + value); + try { + PocoElement w = findPocoEle(selector, value); + if (w != null) { + List pos = w.getPayload().getPos(); + int[] realCoordinates = getTheRealCoordinatesOfPoco(pos.get(0), pos.get(1)); + iosDriver.tap(realCoordinates[0], realCoordinates[1]); + } else { + throw new SonicRespException(value + " not found!"); + } + } catch (Throwable e) { + handleDes.setE(e); + } + } + + public void pocoLongPress(HandleDes handleDes, String des, String selector, String value, int time) { + handleDes.setStepDes("长按" + des); + handleDes.setDetail("长按 " + value); + try { + PocoElement w = findPocoEle(selector, value); + if (w != null) { + List pos = w.getPayload().getPos(); + int[] realCoordinates = getTheRealCoordinatesOfPoco(pos.get(0), pos.get(1)); + iosDriver.longPress(realCoordinates[0], realCoordinates[1], time); + } else { + throw new SonicRespException(value + " not found!"); + } + } catch (Throwable e) { + handleDes.setE(e); + } + } + + public void pocoSwipe(HandleDes handleDes, String des, String selector, String value, String des2, String selector2, String value2) { + handleDes.setStepDes("滑动拖拽" + des + "到" + des2); + handleDes.setDetail("拖拽 " + value + " 到 " + value2); + try { + PocoElement w1 = findPocoEle(selector, value); + PocoElement w2 = findPocoEle(selector2, value2); + if (w1 != null && w2 != null) { + List pos1 = w1.getPayload().getPos(); + int[] realCoordinates1 = getTheRealCoordinatesOfPoco(pos1.get(0), pos1.get(1)); + + List pos2 = w2.getPayload().getPos(); + int[] realCoordinate2 = getTheRealCoordinatesOfPoco(pos2.get(0), pos2.get(1)); + + iosDriver.swipe(realCoordinates1[0], realCoordinates1[1], realCoordinate2[0], realCoordinate2[1]); + } else { + throw new SonicRespException(value + " or " + value2 + " not found!"); + } + } catch (Throwable e) { + handleDes.setE(e); + } + } + + public void setTheRealPositionOfTheWindow(HandleDes handleDes, String text) { + JSONObject offsetValue = JSONObject.parseObject(text); + handleDes.setStepDes("设置偏移量"); + handleDes.setDetail(String.format("offsetWidth: %d, offsetHeight: %d, windowWidth: %d, windowHeight: %d", + offsetValue.getInteger("offsetWidth"), + offsetValue.getInteger("offsetHeight"), + offsetValue.getInteger("windowWidth"), + offsetValue.getInteger("windowHeight") + )); + this.screenWindowPosition[0] = offsetValue.getInteger("offsetWidth"); + this.screenWindowPosition[1] = offsetValue.getInteger("offsetHeight"); + this.screenWindowPosition[2] = offsetValue.getInteger("windowWidth"); + this.screenWindowPosition[3] = offsetValue.getInteger("windowHeight"); + } + + public int[] getTheRealCoordinatesOfPoco(double pocoX, double pocoY) { + int[] pos = new int[2]; + int screenOrientation = SibTool.getOrientation(udId); + + int width = screenWindowPosition[2], height = screenWindowPosition[3]; + + if (width == 0 || height == 0) { + WindowSize windowSize = null; + try { + windowSize = iosDriver.getWindowSize(); + } catch (SonicRespException e) { + e.printStackTrace(); + } + width = windowSize.getWidth(); + height = windowSize.getHeight(); + } + + if (screenOrientation == 1 || screenOrientation == 3) { + // x + pos[0] = this.screenWindowPosition[1] + (int) (height * pocoX); + // y + pos[1] = this.screenWindowPosition[0] + (int) (width * pocoY); + } else { + // x = offsetX + width*pocoPosX + pos[0] = this.screenWindowPosition[0] + (int) (width * pocoX); + // y = offsetY + height*pocoPosY + pos[1] = this.screenWindowPosition[1] + (int) (height * pocoY); + } + return pos; + } + + public void freezeSource(HandleDes handleDes) { + handleDes.setStepDes("冻结控件树"); + handleDes.setDetail(""); + pocoDriver.freezeSource(); + } + + public void thawSource(HandleDes handleDes) { + handleDes.setStepDes("解冻控件树"); + handleDes.setDetail(""); + pocoDriver.thawSource(); + } + + public void closePocoDriver(HandleDes handleDes) { + handleDes.setStepDes("关闭PocoDriver"); + handleDes.setDetail(""); + if (pocoDriver != null) { + pocoDriver.closeDriver(); + SibTool.stopProxy(udId, targetPort); + pocoDriver = null; + } + } + + public PocoDriver getPocoDriver() { + return pocoDriver; + } + public IOSElement findEle(String selector, String pathValue) throws SonicRespException { IOSElement we = null; pathValue = TextHandler.replaceTrans(pathValue, globalParams); @@ -984,12 +1179,6 @@ public void runStep(JSONObject stepJSON, HandleDes handleDes) throws Throwable { case "sendKeyForce": sendKeyForce(handleDes, step.getString("content")); break; -// case "hideKey": -// hideKey(handleDes); -// break; -// case "monkey": -// runMonkey(handleDes, step.getJSONObject("content"), step.getJSONArray("text").toJavaList(JSONObject.class)); -// break; case "publicStep": publicStep(handleDes, step.getString("content"), stepJSON.getJSONArray("pubSteps")); return; @@ -1005,6 +1194,38 @@ public void runStep(JSONObject stepJSON, HandleDes handleDes) throws Throwable { case "runScript": runScript(handleDes, step.getString("content"), step.getString("text")); break; + case "startPocoDriver": + startPocoDriver(handleDes, step.getString("content"), step.getInteger("text")); + break; + case "isExistPocoEle": + isExistPocoEle(handleDes, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleType") + , eleList.getJSONObject(0).getString("eleValue"), step.getBoolean("content")); + break; + case "pocoClick": + pocoClick(handleDes, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleType") + , eleList.getJSONObject(0).getString("eleValue")); + break; + case "pocoLongPress": + pocoLongPress(handleDes, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleType") + , eleList.getJSONObject(0).getString("eleValue") + , Integer.parseInt(step.getString("content"))); + break; + case "pocoSwipe": + pocoSwipe(handleDes, 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")); + break; + case "setTheRealPositionOfTheWindow": + setTheRealPositionOfTheWindow(handleDes, step.getString("content")); + break; + case "freezeSource": + freezeSource(handleDes); + break; + case "thawSource": + thawSource(handleDes); + break; + case "closePocoDriver": + closePocoDriver(handleDes); + break; } switchType(step, handleDes); } diff --git a/src/main/java/org/cloud/sonic/agent/bridge/ios/SibTool.java b/src/main/java/org/cloud/sonic/agent/bridge/ios/SibTool.java index 6c5894b1..ce25104c 100644 --- a/src/main/java/org/cloud/sonic/agent/bridge/ios/SibTool.java +++ b/src/main/java/org/cloud/sonic/agent/bridge/ios/SibTool.java @@ -592,6 +592,91 @@ public static int startWebInspector(String udId) { return 0; } + public static void stopProxy(String udId, int target) { + String processName = String.format("process-%s-proxy-%d", udId, target); + if (GlobalProcessMap.getMap().get(processName) != null) { + Process ps = GlobalProcessMap.getMap().get(processName); + ps.children().forEach(ProcessHandle::destroy); + ps.destroy(); + } + } + + public static void proxy(String udId, int local, int target) { + stopProxy(udId, target); + Process ps = null; + String commandLine = "%s proxy -u %s -l %d -r %d"; + try { + String system = System.getProperty("os.name").toLowerCase(); + if (system.contains("win")) { + ps = Runtime.getRuntime().exec(new String[]{"cmd", "/c", String.format(commandLine, sib, udId, local, target)}); + } else if (system.contains("linux") || system.contains("mac")) { + ps = Runtime.getRuntime().exec(new String[]{"sh", "-c", String.format(commandLine, sib, udId, local, target)}); + } + InputStreamReader inputStreamReader = new InputStreamReader(ps.getInputStream()); + BufferedReader stdInput = new BufferedReader(inputStreamReader); + InputStreamReader err = new InputStreamReader(ps.getErrorStream()); + BufferedReader stdInputErr = new BufferedReader(err); + Process finalPs = ps; + Thread proErr = new Thread(() -> { + String s; + while (finalPs.isAlive()) { + try { + if ((s = stdInputErr.readLine()) != null) { + logger.info(s); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + try { + stdInputErr.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + err.close(); + } catch (IOException e) { + e.printStackTrace(); + } + logger.info("WebInspector print thread shutdown."); + }); + proErr.start(); + Thread pro = new Thread(() -> { + String s; + while (finalPs.isAlive()) { + try { + if ((s = stdInput.readLine()) != null) { + logger.info(s); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + try { + stdInput.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + inputStreamReader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + logger.info("proxy print thread shutdown."); + }); + pro.start(); + String processName = String.format("process-%s-proxy-%d", udId, target); + GlobalProcessMap.getMap().put(processName, ps); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static int getOrientation(String udId) { + String commandLine = "%s orientation -u %s"; + return BytesTool.getInt(ProcessCommandTool.getProcessLocalCommandStr(String.format(commandLine, sib, udId))); + } + public static List getWebView(String udId) { int port; if (webViewMap.get(udId) != null) { diff --git a/src/main/java/org/cloud/sonic/agent/websockets/IOSWSServer.java b/src/main/java/org/cloud/sonic/agent/websockets/IOSWSServer.java index 5d3f910c..16390af7 100644 --- a/src/main/java/org/cloud/sonic/agent/websockets/IOSWSServer.java +++ b/src/main/java/org/cloud/sonic/agent/websockets/IOSWSServer.java @@ -19,6 +19,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.cloud.sonic.agent.automation.IOSStepHandler; +import org.cloud.sonic.agent.bridge.android.AndroidDeviceThreadPool; import org.cloud.sonic.agent.bridge.ios.IOSDeviceLocalStatus; import org.cloud.sonic.agent.bridge.ios.IOSDeviceThreadPool; import org.cloud.sonic.agent.bridge.ios.SibTool; @@ -276,6 +277,22 @@ public void onMessage(String message, Session session) { break; case "debug": switch (msg.getString("detail")) { + case "poco": { + IOSDeviceThreadPool.cachedThreadPool.execute(() -> { + iosStepHandler.startPocoDriver(new HandleDes(), msg.getString("engine"), msg.getInteger("port")); + JSONObject poco = new JSONObject(); + try { + poco.put("result", iosStepHandler.getPocoDriver().getPageSourceForJsonString()); + } catch (SonicRespException e) { + poco.put("result", ""); + e.printStackTrace(); + } + poco.put("msg", "poco"); + BytesTool.sendText(session, poco.toJSONString()); + iosStepHandler.closePocoDriver(new HandleDes()); + }); + break; + } case "runStep": { JSONObject jsonDebug = new JSONObject(); jsonDebug.put("msg", "findSteps"); From 5bd9afcf0395a3ab995a88e6e87873b00a48d5f0 Mon Sep 17 00:00:00 2001 From: ZhouYixun <291028775@qq.com> Date: Mon, 31 Oct 2022 00:36:51 +0800 Subject: [PATCH 02/12] fix: ios screen bugs --- .../cloud/sonic/agent/websockets/IOSWSServer.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/cloud/sonic/agent/websockets/IOSWSServer.java b/src/main/java/org/cloud/sonic/agent/websockets/IOSWSServer.java index 16390af7..90c76c9b 100644 --- a/src/main/java/org/cloud/sonic/agent/websockets/IOSWSServer.java +++ b/src/main/java/org/cloud/sonic/agent/websockets/IOSWSServer.java @@ -104,11 +104,6 @@ public void onOpen(Session session, @PathParam("key") String secretKey, } saveUdIdMapAndSet(session, udId); int[] ports = SibTool.startWda(udId); - JSONObject picFinish = new JSONObject(); - picFinish.put("msg", "picFinish"); - picFinish.put("wda", ports[0]); - picFinish.put("port", ports[1]); - sendText(session, picFinish.toJSONString()); if (ports[0] != 0) { SibTool.orientationWatcher(udId, session); } @@ -122,11 +117,13 @@ public void onOpen(Session session, @PathParam("key") String secretKey, result.put("status", "success"); result.put("width", iosStepHandler.getDriver().getWindowSize().getWidth()); result.put("height", iosStepHandler.getDriver().getWindowSize().getHeight()); + result.put("wda", ports[0]); + result.put("port", ports[1]); result.put("detail", "初始化 WebDriverAgent 完成!"); JSONObject appiumSettings = new JSONObject(); - appiumSettings.put("mjpegServerFramerate", 100); + appiumSettings.put("mjpegServerFramerate", 60); appiumSettings.put("mjpegScalingFactor", 100); - appiumSettings.put("mjpegServerScreenshotQuality", 25); + appiumSettings.put("mjpegServerScreenshotQuality", 50); iosStepHandler.appiumSettings(appiumSettings); HandlerMap.getIOSMap().put(session.getId(), iosStepHandler); } catch (Exception e) { @@ -186,9 +183,9 @@ public void onMessage(String message, Session session) { appiumSettings.put("mjpegScalingFactor", 50); appiumSettings.put("mjpegServerScreenshotQuality", 10); } else { - appiumSettings.put("mjpegServerFramerate", 100); + appiumSettings.put("mjpegServerFramerate", 60); appiumSettings.put("mjpegScalingFactor", 100); - appiumSettings.put("mjpegServerScreenshotQuality", 25); + appiumSettings.put("mjpegServerScreenshotQuality", 50); } try { iosStepHandler.appiumSettings(appiumSettings); From 1066278ad75b30b3cb8228de76649bb3bb262cd4 Mon Sep 17 00:00:00 2001 From: ZhouYixun <291028775@qq.com> Date: Tue, 1 Nov 2022 00:58:15 +0800 Subject: [PATCH 03/12] fix: DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES --- .../sonic/agent/bridge/android/AndroidDeviceBridgeTool.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java index 20fef347..4b18e5ad 100644 --- a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java +++ b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java @@ -722,7 +722,7 @@ public boolean getIsOpen() { public void run() { forward(iDevice, port, 6790); try { - iDevice.executeShellCommand("am instrument -w io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner", + iDevice.executeShellCommand("am instrument -w io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner -e DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES", new IShellOutputReceiver() { @Override public void addOutput(byte[] bytes, int i, int i1) { From 82ce08243dde0b6baa9dcae3ccce60629d95e3a3 Mon Sep 17 00:00:00 2001 From: ZhouYixun <291028775@qq.com> Date: Tue, 1 Nov 2022 01:11:26 +0800 Subject: [PATCH 04/12] fix: DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES2 --- .../sonic/agent/bridge/android/AndroidDeviceBridgeTool.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java index 4b18e5ad..5ad0d1f2 100644 --- a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java +++ b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java @@ -722,7 +722,7 @@ public boolean getIsOpen() { public void run() { forward(iDevice, port, 6790); try { - iDevice.executeShellCommand("am instrument -w io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner -e DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES", + iDevice.executeShellCommand("am instrument -w io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner -e DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES=true", new IShellOutputReceiver() { @Override public void addOutput(byte[] bytes, int i, int i1) { From 9f09bcf02c2dcf0750b9b500917842fec6cd1d92 Mon Sep 17 00:00:00 2001 From: Eason <291028775@qq.com> Date: Tue, 1 Nov 2022 11:25:23 +0800 Subject: [PATCH 05/12] Update AndroidDeviceBridgeTool.java --- .../sonic/agent/bridge/android/AndroidDeviceBridgeTool.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java index 5ad0d1f2..eb0a755f 100644 --- a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java +++ b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java @@ -722,7 +722,7 @@ public boolean getIsOpen() { public void run() { forward(iDevice, port, 6790); try { - iDevice.executeShellCommand("am instrument -w io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner -e DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES=true", + iDevice.executeShellCommand("am instrument -w io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner -e DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES true", new IShellOutputReceiver() { @Override public void addOutput(byte[] bytes, int i, int i1) { From 6fbd485780954b7c80f857b13c3f6852614ba175 Mon Sep 17 00:00:00 2001 From: ZhouYixun <291028775@qq.com> Date: Tue, 1 Nov 2022 21:20:46 +0800 Subject: [PATCH 06/12] fix: disable analytics --- pom.xml | 4 ++-- .../sonic/agent/bridge/android/AndroidDeviceBridgeTool.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 59526207..3291f9be 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ io.github.soniccloudorg sonic-driver-core - 1.1.9 + 1.1.10 @@ -103,7 +103,7 @@ org.codehaus.groovy groovy-all - 3.0.13 + 3.0.4 pom diff --git a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java index eb0a755f..1a953826 100644 --- a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java +++ b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java @@ -722,7 +722,7 @@ public boolean getIsOpen() { public void run() { forward(iDevice, port, 6790); try { - iDevice.executeShellCommand("am instrument -w io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner -e DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES true", + iDevice.executeShellCommand("am instrument -w io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner -e DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES true -e disableAnalytics true", new IShellOutputReceiver() { @Override public void addOutput(byte[] bytes, int i, int i1) { From 8b7f21c526071a799df04f360149b7c568006955 Mon Sep 17 00:00:00 2001 From: ZhouYixun <291028775@qq.com> Date: Tue, 1 Nov 2022 22:13:12 +0800 Subject: [PATCH 07/12] fix: groovy --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3291f9be..c3d19b8a 100644 --- a/pom.xml +++ b/pom.xml @@ -103,7 +103,7 @@ org.codehaus.groovy groovy-all - 3.0.4 + 3.0.13 pom From 4aa512ff636cc4649191f8e4cf3b11c534e9f689 Mon Sep 17 00:00:00 2001 From: ZhouYixun <291028775@qq.com> Date: Wed, 2 Nov 2022 13:38:50 +0800 Subject: [PATCH 08/12] feat: add poco interval --- .../agent/automation/AndroidStepHandler.java | 69 ++++++++++++++----- .../agent/automation/IOSStepHandler.java | 69 ++++++++++++++----- 2 files changed, 104 insertions(+), 34 deletions(-) diff --git a/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java b/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java index 02b37524..fe66091a 100644 --- a/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java +++ b/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java @@ -1225,27 +1225,59 @@ public void startPocoDriver(HandleDes handleDes, String engine, int port) { pocoDriver = new PocoDriver(PocoEngine.valueOf(engine), pocoPort); } + private int intervalInit = 3000; + private int retryInit = 3; + + public void setDefaultFindPocoElementInterval(HandleDes handleDes, Integer retry, Integer interval) { + handleDes.setStepDes("Set Global Find Poco Element Interval"); + handleDes.setDetail(String.format("Retry count: %d, retry interval: %d ms", retry, interval)); + if (retry != null) { + retryInit = retry; + } + if (interval != null) { + intervalInit = interval; + } + } + public PocoElement findPocoEle(String selector, String pathValue) throws Throwable { PocoElement pocoElement = null; pathValue = TextHandler.replaceTrans(pathValue, globalParams); - pocoDriver.getPageSourceForXmlElement(); - try { - switch (selector) { - case "poco": - pocoElement = pocoDriver.findElement(PocoSelector.POCO, pathValue); - break; - case "xpath": - pocoElement = pocoDriver.findElement(PocoSelector.XPATH, pathValue); - break; - case "cssSelector": - pocoElement = pocoDriver.findElement(PocoSelector.CSS_SELECTOR, pathValue); - break; - default: - log.sendStepLog(StepType.ERROR, "查找控件元素失败", "这个控件元素类型: " + selector + " 不存在!!!"); + int wait = 0; + String errMsg = ""; + while (wait < retryInit) { + wait++; + pocoDriver.getPageSourceForXmlElement(); + try { + switch (selector) { + case "poco": + pocoElement = pocoDriver.findElement(PocoSelector.POCO, pathValue); + break; + case "xpath": + pocoElement = pocoDriver.findElement(PocoSelector.XPATH, pathValue); + break; + case "cssSelector": + pocoElement = pocoDriver.findElement(PocoSelector.CSS_SELECTOR, pathValue); + break; + default: + log.sendStepLog(StepType.ERROR, "查找控件元素失败", "这个控件元素类型: " + selector + " 不存在!!!"); + break; + } + if (pocoElement != null) { break; + } + } catch (Throwable e) { + errMsg = e.getMessage(); + } + if (wait < retryInit) { + try { + Thread.sleep(intervalInit); + } catch (InterruptedException e) { + e.printStackTrace(); + } } - } catch (Throwable e) { - throw e; + } + if (pocoElement == null) { + throw new SonicRespException(errMsg); } return pocoElement; } @@ -1458,7 +1490,7 @@ public AndroidElement findEle(String selector, String pathValue) throws SonicRes } public void setFindElementInterval(HandleDes handleDes, int retry, int interval) { - handleDes.setStepDes("Set Global Find Element Interval"); + handleDes.setStepDes("Set Global Find Android Element Interval"); handleDes.setDetail(String.format("Retry count: %d, retry interval: %d ms", retry, interval)); androidDriver.setDefaultFindElementInterval(retry, interval); } @@ -1802,6 +1834,9 @@ public void runStep(JSONObject stepJSON, HandleDes handleDes) throws Throwable { case "runScript": runScript(handleDes, step.getString("content"), step.getString("text")); break; + case "setDefaultFindPocoElementInterval": + setDefaultFindPocoElementInterval(handleDes, step.getInteger("content"), step.getInteger("text")); + break; case "startPocoDriver": startPocoDriver(handleDes, step.getString("content"), step.getInteger("text")); break; diff --git a/src/main/java/org/cloud/sonic/agent/automation/IOSStepHandler.java b/src/main/java/org/cloud/sonic/agent/automation/IOSStepHandler.java index c3246cb3..4018e7ef 100644 --- a/src/main/java/org/cloud/sonic/agent/automation/IOSStepHandler.java +++ b/src/main/java/org/cloud/sonic/agent/automation/IOSStepHandler.java @@ -770,27 +770,59 @@ public void startPocoDriver(HandleDes handleDes, String engine, int port) { pocoDriver = new PocoDriver(PocoEngine.valueOf(engine), pocoPort); } + private int intervalInit = 3000; + private int retryInit = 3; + + public void setDefaultFindPocoElementInterval(HandleDes handleDes, Integer retry, Integer interval) { + handleDes.setStepDes("Set Global Find Poco Element Interval"); + handleDes.setDetail(String.format("Retry count: %d, retry interval: %d ms", retry, interval)); + if (retry != null) { + retryInit = retry; + } + if (interval != null) { + intervalInit = interval; + } + } + public PocoElement findPocoEle(String selector, String pathValue) throws Throwable { PocoElement pocoElement = null; pathValue = TextHandler.replaceTrans(pathValue, globalParams); - pocoDriver.getPageSourceForXmlElement(); - try { - switch (selector) { - case "poco": - pocoElement = pocoDriver.findElement(PocoSelector.POCO, pathValue); - break; - case "xpath": - pocoElement = pocoDriver.findElement(PocoSelector.XPATH, pathValue); - break; - case "cssSelector": - pocoElement = pocoDriver.findElement(PocoSelector.CSS_SELECTOR, pathValue); - break; - default: - log.sendStepLog(StepType.ERROR, "查找控件元素失败", "这个控件元素类型: " + selector + " 不存在!!!"); + int wait = 0; + String errMsg = ""; + while (wait < retryInit) { + wait++; + pocoDriver.getPageSourceForXmlElement(); + try { + switch (selector) { + case "poco": + pocoElement = pocoDriver.findElement(PocoSelector.POCO, pathValue); + break; + case "xpath": + pocoElement = pocoDriver.findElement(PocoSelector.XPATH, pathValue); + break; + case "cssSelector": + pocoElement = pocoDriver.findElement(PocoSelector.CSS_SELECTOR, pathValue); + break; + default: + log.sendStepLog(StepType.ERROR, "查找控件元素失败", "这个控件元素类型: " + selector + " 不存在!!!"); + break; + } + if (pocoElement != null) { break; + } + } catch (Throwable e) { + errMsg = e.getMessage(); + } + if (wait < retryInit) { + try { + Thread.sleep(intervalInit); + } catch (InterruptedException e) { + e.printStackTrace(); + } } - } catch (Throwable e) { - throw e; + } + if (pocoElement == null) { + throw new SonicRespException(errMsg); } return pocoElement; } @@ -980,7 +1012,7 @@ public IOSElement findEle(String selector, String pathValue) throws SonicRespExc } public void setFindElementInterval(HandleDes handleDes, int retry, int interval) { - handleDes.setStepDes("Set Global Find Element Interval"); + handleDes.setStepDes("Set Global Find XCTest Element Interval"); handleDes.setDetail(String.format("Retry count: %d, retry interval: %d ms", retry, interval)); iosDriver.setDefaultFindElementInterval(retry, interval); } @@ -1197,6 +1229,9 @@ public void runStep(JSONObject stepJSON, HandleDes handleDes) throws Throwable { case "startPocoDriver": startPocoDriver(handleDes, step.getString("content"), step.getInteger("text")); break; + case "setDefaultFindPocoElementInterval": + setDefaultFindPocoElementInterval(handleDes, step.getInteger("content"), step.getInteger("text")); + break; case "isExistPocoEle": isExistPocoEle(handleDes, eleList.getJSONObject(0).getString("eleName"), eleList.getJSONObject(0).getString("eleType") , eleList.getJSONObject(0).getString("eleValue"), step.getBoolean("content")); From 8c449dad6bbb99d179693babeab72ba8a25bdd0b Mon Sep 17 00:00:00 2001 From: ZhouYixun <291028775@qq.com> Date: Thu, 3 Nov 2022 20:08:52 +0800 Subject: [PATCH 09/12] feat: add writeable --- .../android/AndroidDeviceBridgeTool.java | 32 +++++++++++-------- .../bridge/android/AndroidSupplyTool.java | 6 +++- .../cloud/sonic/agent/bridge/ios/SibTool.java | 6 +++- .../org/cloud/sonic/agent/tools/SGMTool.java | 6 +++- .../agent/websockets/AndroidWSServer.java | 24 ++++++++++---- 5 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java index 1a953826..6f83d6ae 100644 --- a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java +++ b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidDeviceBridgeTool.java @@ -859,21 +859,25 @@ public static List getWebView(IDevice iDevice) { } catch (Exception e) { continue; } - ResponseEntity responseEntity = - restTemplate.exchange("http://localhost:" + port + "/json/list", HttpMethod.GET, new HttpEntity(headers), JSONArray.class); - if (responseEntity.getStatusCode() == HttpStatus.OK) { - List child = new ArrayList<>(); - for (Object e : responseEntity.getBody()) { - LinkedHashMap objE = (LinkedHashMap) e; - JSONObject c = new JSONObject(); - c.put("favicon", objE.get("faviconUrl")); - c.put("title", objE.get("title")); - c.put("url", objE.get("url")); - c.put("id", objE.get("id")); - child.add(c); + try { + ResponseEntity responseEntity = + restTemplate.exchange("http://localhost:" + port + "/json/list", HttpMethod.GET, new HttpEntity(headers), JSONArray.class); + if (responseEntity.getStatusCode() == HttpStatus.OK) { + List child = new ArrayList<>(); + for (Object e : responseEntity.getBody()) { + LinkedHashMap objE = (LinkedHashMap) e; + JSONObject c = new JSONObject(); + c.put("favicon", objE.get("faviconUrl")); + c.put("title", objE.get("title")); + c.put("url", objE.get("url")); + c.put("id", objE.get("id")); + child.add(c); + } + r.put("children", child); + result.add(r); } - r.put("children", child); - result.add(r); + } catch (Exception e) { + continue; } } AndroidWebViewMap.getMap().put(iDevice, has); diff --git a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidSupplyTool.java b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidSupplyTool.java index c507abc5..201290e4 100644 --- a/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidSupplyTool.java +++ b/src/main/java/org/cloud/sonic/agent/bridge/android/AndroidSupplyTool.java @@ -14,11 +14,15 @@ @Slf4j public class AndroidSupplyTool { - private static String sas = new File("plugins" + File.separator + "sonic-android-supply").getAbsolutePath(); + private static File sasBinary = new File("plugins" + File.separator + "sonic-android-supply"); + private static String sas = sasBinary.getAbsolutePath(); private static String sasVersion = String.valueOf(SpringTool.getPropertiesValue("sonic.sas")); private static boolean isEnable = Boolean.valueOf(SpringTool.getPropertiesValue("modules.android.use-sas")); public static void startShare(String udId, Session session) { + sasBinary.setExecutable(true); + sasBinary.setWritable(true); + sasBinary.setReadable(true); JSONObject sasJSON = new JSONObject(); sasJSON.put("msg", "sas"); if (isEnable) { diff --git a/src/main/java/org/cloud/sonic/agent/bridge/ios/SibTool.java b/src/main/java/org/cloud/sonic/agent/bridge/ios/SibTool.java index ce25104c..f4a92b70 100644 --- a/src/main/java/org/cloud/sonic/agent/bridge/ios/SibTool.java +++ b/src/main/java/org/cloud/sonic/agent/bridge/ios/SibTool.java @@ -64,7 +64,8 @@ public class SibTool implements ApplicationListener { @Value("${modules.ios.wda-bundle-id}") private String getBundleId; private static String bundleId; - private static String sib = new File("plugins" + File.separator + "sonic-ios-bridge").getAbsolutePath(); + private static File sibBinary = new File("plugins" + File.separator + "sonic-ios-bridge"); + private static String sib = sibBinary.getAbsolutePath(); @Value("${sonic.sib}") private String sibVersion; private static RestTemplate restTemplate; @@ -84,6 +85,9 @@ public void onApplicationEvent(@NonNull ContextRefreshedEvent event) { } public void init() { + sibBinary.setExecutable(true); + sibBinary.setWritable(true); + sibBinary.setReadable(true); restTemplate = restTemplateBean; List ver = ProcessCommandTool.getProcessLocalCommand(String.format("%s version", sib)); if (ver.size() == 0 || !BytesTool.versionCheck(sibVersion, ver.get(0))) { diff --git a/src/main/java/org/cloud/sonic/agent/tools/SGMTool.java b/src/main/java/org/cloud/sonic/agent/tools/SGMTool.java index 017bc85b..5518232e 100644 --- a/src/main/java/org/cloud/sonic/agent/tools/SGMTool.java +++ b/src/main/java/org/cloud/sonic/agent/tools/SGMTool.java @@ -30,7 +30,8 @@ public class SGMTool { private static final Logger logger = LoggerFactory.getLogger(SGMTool.class); private static String pFile = new File("plugins").getAbsolutePath(); - private static String sgm = new File(pFile + File.separator + "sonic-go-mitmproxy").getAbsolutePath(); + private static File sgmBinary = new File(pFile + File.separator + "sonic-go-mitmproxy"); + private static String sgm = sgmBinary.getAbsolutePath(); private static String sgmVersion; @Value("${sonic.sgm}") private String ver; @@ -41,6 +42,9 @@ public void setSgmVer() { } public static void init() { + sgmBinary.setExecutable(true); + sgmBinary.setWritable(true); + sgmBinary.setReadable(true); List ver = ProcessCommandTool.getProcessLocalCommand(String.format("%s -version", sgm)); if (ver.size() == 0 || !BytesTool.versionCheck(sgmVersion, ver.get(0).replace("sonic-go-mitmproxy:", "").trim())) { logger.info(String.format("Start sonic-go-mitmproxy failed! Please use [chmod -R 777 %s], if still failed, you can try with [sudo]", pFile)); diff --git a/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java b/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java index e863fb4e..7000f32a 100644 --- a/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java +++ b/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java @@ -122,14 +122,26 @@ public void onOpen(Session session, @PathParam("key") String secretKey, iDevice.installPackage("plugins/sonic-android-apk.apk", true, new InstallReceiver(), 180L, 180L, TimeUnit.MINUTES , "-r", "-t", "-g"); - AndroidDeviceBridgeTool.executeCommand(iDevice, "appops set org.cloud.sonic.android RUN_IN_BACKGROUND allow"); - AndroidDeviceBridgeTool.executeCommand(iDevice, "dumpsys deviceidle whitelist +org.cloud.sonic.android"); - logger.info("Sonic Apk install successful."); } catch (InstallException e) { - e.printStackTrace(); - logger.info("Sonic Apk install failed."); - return; + if (e.getMessage().contains("Unknown option: -g")) { + try { + iDevice.installPackage("plugins/sonic-android-apk.apk", + true, new InstallReceiver(), 180L, 180L, TimeUnit.MINUTES + , "-r", "-t"); + } catch (InstallException e2) { + e.printStackTrace(); + logger.info("Sonic Apk install failed."); + return; + } + } else { + e.printStackTrace(); + logger.info("Sonic Apk install failed."); + return; + } } + AndroidDeviceBridgeTool.executeCommand(iDevice, "appops set org.cloud.sonic.android RUN_IN_BACKGROUND allow"); + AndroidDeviceBridgeTool.executeCommand(iDevice, "dumpsys deviceidle whitelist +org.cloud.sonic.android"); + logger.info("Sonic Apk install successful."); path = AndroidDeviceBridgeTool.executeCommand(iDevice, "pm path org.cloud.sonic.android").trim() .replaceAll("package:", "") .replaceAll("\n", "") From 0ba90f268071df02c3cd783d12f6beb5f10b00c5 Mon Sep 17 00:00:00 2001 From: ZhouYixun <291028775@qq.com> Date: Thu, 3 Nov 2022 20:11:25 +0800 Subject: [PATCH 10/12] feat: add writeable2 --- .../java/org/cloud/sonic/agent/websockets/AndroidWSServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java b/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java index 7000f32a..a2af72af 100644 --- a/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java +++ b/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java @@ -129,7 +129,7 @@ true, new InstallReceiver(), 180L, 180L, TimeUnit.MINUTES true, new InstallReceiver(), 180L, 180L, TimeUnit.MINUTES , "-r", "-t"); } catch (InstallException e2) { - e.printStackTrace(); + e2.printStackTrace(); logger.info("Sonic Apk install failed."); return; } From a104ad13194702afb30d3a8b4c50f85fe7b0bd75 Mon Sep 17 00:00:00 2001 From: ZhouYixun <291028775@qq.com> Date: Thu, 3 Nov 2022 21:45:08 +0800 Subject: [PATCH 11/12] fix: monkey fastjson bugs --- pom.xml | 2 +- .../cloud/sonic/agent/automation/AndroidStepHandler.java | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index c3d19b8a..58d6ea4c 100644 --- a/pom.xml +++ b/pom.xml @@ -98,7 +98,7 @@ io.github.soniccloudorg sonic-vision-core - 1.0.5-${platform} + 1.0.6-${platform} org.codehaus.groovy diff --git a/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java b/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java index fe66091a..39ea1ddb 100644 --- a/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java +++ b/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java @@ -941,7 +941,7 @@ public void runMonkey(HandleDes handleDes, JSONObject content, List handleDes.setE(new Exception("未安装应用")); return; } - JSONArray options = content.getJSONArray("options"); + List options = content.getJSONArray("options").toJavaList(JSONObject.class); WindowSize windowSize = null; try { windowSize = androidDriver.getWindowSize(); @@ -961,8 +961,7 @@ public void runMonkey(HandleDes handleDes, JSONObject content, List boolean isOpenActivityListener = false; boolean isOpenNetworkListener = false; if (!options.isEmpty()) { - for (int i = options.size() - 1; i >= 0; i--) { - JSONObject jsonOption = (JSONObject) options.get(i); + for (JSONObject jsonOption : options) { if (jsonOption.getString("name").equals("sleepTime")) { sleepTime = jsonOption.getInteger("value"); } @@ -993,7 +992,6 @@ public void runMonkey(HandleDes handleDes, JSONObject content, List if (jsonOption.getString("name").equals("isOpenNetworkListener")) { isOpenNetworkListener = jsonOption.getBoolean("value"); } - options.remove(options.get(i)); } } int finalSleepTime = sleepTime; From f15963732c2b923767c47c8bf9c9934ddcf78aff Mon Sep 17 00:00:00 2001 From: ZhouYixun <291028775@qq.com> Date: Thu, 3 Nov 2022 22:53:08 +0800 Subject: [PATCH 12/12] fix: monkey fastjson bugs --- .../cloud/sonic/agent/automation/AndroidStepHandler.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java b/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java index 39ea1ddb..62a46b50 100644 --- a/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java +++ b/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java @@ -16,6 +16,7 @@ */ package org.cloud.sonic.agent.automation; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.android.ddmlib.IDevice; @@ -941,7 +942,7 @@ public void runMonkey(HandleDes handleDes, JSONObject content, List handleDes.setE(new Exception("未安装应用")); return; } - List options = content.getJSONArray("options").toJavaList(JSONObject.class); + JSONArray options = content.getJSONArray("options"); WindowSize windowSize = null; try { windowSize = androidDriver.getWindowSize(); @@ -961,7 +962,8 @@ public void runMonkey(HandleDes handleDes, JSONObject content, List boolean isOpenActivityListener = false; boolean isOpenNetworkListener = false; if (!options.isEmpty()) { - for (JSONObject jsonOption : options) { + for (Object j : options) { + JSONObject jsonOption = JSON.parseObject(j.toString()); if (jsonOption.getString("name").equals("sleepTime")) { sleepTime = jsonOption.getInteger("value"); } @@ -1103,7 +1105,6 @@ public void runMonkey(HandleDes handleDes, JSONObject content, List h5Time = 0; } } catch (Throwable e) { - e.printStackTrace(); } } }