From 37b4b667f01a410c6fa1ae17b21945a0896ac16a Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Fri, 9 May 2014 12:20:21 -0400 Subject: [PATCH] Always setCompressedLayoutHeirarchy --- docs/cn/caps.cn.md | 1 - docs/en/caps.md | 1 - lib/devices/android/adb.js | 1 - lib/devices/android/android-common.js | 6 +- lib/devices/android/android-controller.js | 3 +- .../bootstrap/AndroidCommandExecutor.java | 7 +- .../android/bootstrap/SocketServer.java | 2 + .../handler/DumpWindowHierarchy.java | 74 ++++++++----------- .../DumpWindowHierarchyCompressed.java | 28 ------- .../bootstrap/utils/NotImportantViews.java | 17 +++++ .../android/apidemos/find-element-specs.js | 3 +- 11 files changed, 54 insertions(+), 89 deletions(-) delete mode 100644 lib/devices/android/bootstrap/src/io/appium/android/bootstrap/handler/DumpWindowHierarchyCompressed.java create mode 100644 lib/devices/android/bootstrap/src/io/appium/android/bootstrap/utils/NotImportantViews.java diff --git a/docs/cn/caps.cn.md b/docs/cn/caps.cn.md index 5bfd330eb..4bd6bf485 100644 --- a/docs/cn/caps.cn.md +++ b/docs/cn/caps.cn.md @@ -21,7 +21,6 @@ |`app-package`| 你想运行的Android应用的包名|比如`com.example.android.myApp`, `com.android.settings`| |`app-wait-activity`| 你想要等待启动的Android Activity名称|比如`SplashActivity`| |`device-ready-timeout`| 设置一个模拟器或真机准备就绪的时间|比如`5`| -|``compressXml``| 参考[setCompressedLayoutHeirarchy(true)](http://developer.android.com/tools/help/uiautomator/UiDevice.html#setCompressedLayoutHeirarchy(boolean\))| `true`| ### iOS特有 diff --git a/docs/en/caps.md b/docs/en/caps.md index 773d6799f..0ae74a766 100644 --- a/docs/en/caps.md +++ b/docs/en/caps.md @@ -24,7 +24,6 @@ |`appWaitActivity`| Activity name for the Android activity you want to wait for|`SplashActivity`| |`appWaitPackage`| Java package of the Android app you want to wait for|`com.example.android.myApp`, `com.android.settings`| |`deviceReadyTimeout`| Timeout in seconds while waiting for device to become ready|`5`| -|`compressXml`| [setCompressedLayoutHeirarchy(true)](http://developer.android.com/tools/help/uiautomator/UiDevice.html#setCompressedLayoutHeirarchy%28boolean%29)| `true`| |`androidCoverage`| Fully qualified instrumentation class. Passed to -w in adb shell am instrument -e coverage true -w | `com.my.Pkg/com.my.Pkg.instrumentation.MyInstrumentation`| |`enablePerformanceLogging`| (Chrome and webview only) Enable Chromedriver's performance logging (default `false`)| `true`, `false`| |`avdLaunchTimeout`| How long to wait in milliseconds for an avd to launch and connect to ADB (default `120000`)| `300000`| diff --git a/lib/devices/android/adb.js b/lib/devices/android/adb.js index 7ceee621c..61a6d5fde 100644 --- a/lib/devices/android/adb.js +++ b/lib/devices/android/adb.js @@ -30,7 +30,6 @@ var ADB = function (opts) { if (typeof opts.sdkRoot === "undefined") { opts.sdkRoot = process.env.ANDROID_HOME || ''; } - this.compressXml = opts.compressXml; this.sdkRoot = opts.sdkRoot; this.udid = opts.udid; this.appDeviceReadyTimeout = opts.appDeviceReadyTimeout; diff --git a/lib/devices/android/android-common.js b/lib/devices/android/android-common.js index 4d91b7a90..be3ebcc54 100644 --- a/lib/devices/android/android-common.js +++ b/lib/devices/android/android-common.js @@ -75,11 +75,7 @@ androidCommon.setAndroidArgs = function () { this.setArgFromCap("androidWaitPackage", "appWaitPackage"); this.setArgFromCap("androidWaitActivity", "appWaitActivity"); this.setArgFromCap("androidDeviceReadyTimeout", "deviceReadyTimeout"); - - // must be enabled by default or XPath will be broken on API >= 18 - // compressXml is not available on API <= 17 - this.args.compressXml = true; - this.setArgFromCap("compressXml", "compressXml"); + this.setArgFromCap("androidCoverage", "androidCoverage"); this.args.systemPort = this.args.bootstrapPort; this.args.appPackage = this.args.androidPackage; this.args.appActivity = this.args.androidActivity; diff --git a/lib/devices/android/android-controller.js b/lib/devices/android/android-controller.js index 311ee86ab..120212660 100644 --- a/lib/devices/android/android-controller.js +++ b/lib/devices/android/android-controller.js @@ -361,8 +361,7 @@ androidController.getPageSource = function (cb) { async.series( [ function (cb) { - var dumpCommand = this.args.compressXml ? "dumpWindowHierarchyCompressed" : "dumpWindowHierarchy"; - this.proxy([dumpCommand], cb); + this.proxy(["dumpWindowHierarchy"], cb); }.bind(this), function (cb) { var cmd = this.adb.adbCmd + ' pull ' + onDeviceXmlPath + ' "' + xmlFile + '"'; diff --git a/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/AndroidCommandExecutor.java b/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/AndroidCommandExecutor.java index 95e66e69d..eb5def465 100644 --- a/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/AndroidCommandExecutor.java +++ b/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/AndroidCommandExecutor.java @@ -5,7 +5,6 @@ import io.appium.android.bootstrap.handler.Clear; import io.appium.android.bootstrap.handler.Click; import io.appium.android.bootstrap.handler.Drag; import io.appium.android.bootstrap.handler.DumpWindowHierarchy; -import io.appium.android.bootstrap.handler.DumpWindowHierarchyCompressed; import io.appium.android.bootstrap.handler.Find; import io.appium.android.bootstrap.handler.Flick; import io.appium.android.bootstrap.handler.GetAttribute; @@ -69,11 +68,7 @@ class AndroidCommandExecutor { map.put("getSize", new GetSize()); map.put("wake", new Wake()); map.put("pressBack", new PressBack()); - final DumpWindowHierarchy dumpWindowHierarchy = new DumpWindowHierarchy(); - DumpWindowHierarchy.instance = dumpWindowHierarchy; - map.put("dumpWindowHierarchy", dumpWindowHierarchy); - map.put("dumpWindowHierarchyCompressed", - new DumpWindowHierarchyCompressed()); + map.put("dumpWindowHierarchy", new DumpWindowHierarchy()); map.put("pressKeyCode", new PressKeyCode()); map.put("takeScreenshot", new TakeScreenshot()); map.put("getStrings", new GetStrings()); diff --git a/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/SocketServer.java b/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/SocketServer.java index 41240a790..eac4c2331 100644 --- a/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/SocketServer.java +++ b/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/SocketServer.java @@ -4,6 +4,7 @@ import io.appium.android.bootstrap.exceptions.AndroidCommandException; import io.appium.android.bootstrap.exceptions.CommandTypeException; import io.appium.android.bootstrap.exceptions.SocketServerException; import io.appium.android.bootstrap.handler.Find; +import io.appium.android.bootstrap.utils.NotImportantViews; import io.appium.android.bootstrap.utils.TheWatchers; import java.io.BufferedReader; @@ -46,6 +47,7 @@ class SocketServer { * @throws SocketServerException */ public SocketServer(final int port) throws SocketServerException { + NotImportantViews.discard(true); // must be set for API 18+ keepListening = true; executor = new AndroidCommandExecutor(); try { diff --git a/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/handler/DumpWindowHierarchy.java b/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/handler/DumpWindowHierarchy.java index 10726de0d..efb77240a 100644 --- a/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/handler/DumpWindowHierarchy.java +++ b/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/handler/DumpWindowHierarchy.java @@ -3,11 +3,9 @@ package io.appium.android.bootstrap.handler; import io.appium.android.bootstrap.AndroidCommand; import io.appium.android.bootstrap.AndroidCommandResult; import io.appium.android.bootstrap.CommandHandler; -import io.appium.android.bootstrap.Logger; import java.io.File; -import android.os.Build; import android.os.Environment; import android.os.SystemClock; @@ -20,54 +18,44 @@ import com.android.uiautomator.core.UiDevice; * /library/core-src/com/android/uiautomator/core/UiDevice.java */ public class DumpWindowHierarchy extends CommandHandler { - public static DumpWindowHierarchy instance = null; + // Note that + // "new File(new File(Environment.getDataDirectory(), "local/tmp"), fileName)" + // is directly from the UiDevice.java source code. + private static final File dumpFolder = new File(Environment.getDataDirectory(), "local/tmp"); + private static final String dumpFileName = "dump.xml"; + private static final File dumpFile = new File(dumpFolder, dumpFileName); - // Note that - // "new File(new File(Environment.getDataDirectory(), "local/tmp"), fileName)" - // is directly from the UiDevice.java source code. - private static final File dumpFolder = new File(Environment.getDataDirectory(), "local/tmp"); - private static final String dumpFileName = "dump.xml"; - private static final File dumpFile = new File(dumpFolder, dumpFileName); - private static boolean compressed = false; + /* + * @param command The {@link AndroidCommand} used for this handler. + * + * @return {@link AndroidCommandResult} + * + * @throws JSONException + * + * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android. + * bootstrap.AndroidCommand) + */ + @Override + public AndroidCommandResult execute(final AndroidCommand command) { + dumpFolder.mkdirs(); - public static boolean isCompressed() { - return compressed; + if (dumpFile.exists()) { + dumpFile.delete(); } - public static void setCompressed(final boolean compress) { - compressed = compress; - } - - /* - * @param command The {@link AndroidCommand} used for this handler. - * - * @return {@link AndroidCommandResult} - * - * @throws JSONException - * - * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android. - * bootstrap.AndroidCommand) - */ - @Override - public AndroidCommandResult execute(final AndroidCommand command) { - dumpFolder.mkdirs(); - - if (dumpFile.exists()) { - dumpFile.delete(); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - Logger.debug("dumpWindowHierarchy. Compressed? " + compressed); - UiDevice.getInstance().setCompressedLayoutHeirarchy(compressed); - } + UiDevice.getInstance().dumpWindowHierarchy(dumpFileName); + if (!dumpFile.exists()) { + for (int count = 0; count < 30; count++) { + SystemClock.sleep(1000); UiDevice.getInstance().dumpWindowHierarchy(dumpFileName); - if (!dumpFile.exists()) { - SystemClock.sleep(1000); - UiDevice.getInstance().dumpWindowHierarchy(dumpFileName); + if (dumpFile.exists()) { + break; } - - return getSuccessResult(dumpFile.exists()); + } } + + return getSuccessResult(dumpFile.exists()); + } } \ No newline at end of file diff --git a/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/handler/DumpWindowHierarchyCompressed.java b/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/handler/DumpWindowHierarchyCompressed.java deleted file mode 100644 index 313056b39..000000000 --- a/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/handler/DumpWindowHierarchyCompressed.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.appium.android.bootstrap.handler; - -import io.appium.android.bootstrap.AndroidCommand; -import io.appium.android.bootstrap.AndroidCommandResult; -import io.appium.android.bootstrap.CommandHandler; - -public class DumpWindowHierarchyCompressed extends CommandHandler { - - private static void enableCompression() { - DumpWindowHierarchy.setCompressed(true); - } - - /* - * @param command The {@link AndroidCommand} used for this handler. - * - * @return {@link AndroidCommandResult} - * - * @throws JSONException - * - * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android. - * bootstrap.AndroidCommand) - */ - @Override - public AndroidCommandResult execute(final AndroidCommand command) { - enableCompression(); - return DumpWindowHierarchy.instance.execute(command); - } -} \ No newline at end of file diff --git a/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/utils/NotImportantViews.java b/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/utils/NotImportantViews.java new file mode 100644 index 000000000..3dba0a9d6 --- /dev/null +++ b/lib/devices/android/bootstrap/src/io/appium/android/bootstrap/utils/NotImportantViews.java @@ -0,0 +1,17 @@ +package io.appium.android.bootstrap.utils; + +import android.os.Build; + +import com.android.uiautomator.core.UiDevice; + +public abstract class NotImportantViews { + // setCompressedLayoutHeirarchy doesn't exist on API <= 17 + // http://developer.android.com/reference/android/accessibilityservice/AccessibilityServiceInfo.html#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS + private static boolean canDiscard = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2; + + public static void discard(boolean discard) { + if (canDiscard) { + UiDevice.getInstance().setCompressedLayoutHeirarchy(discard); + } + } +} \ No newline at end of file diff --git a/test/functional/android/apidemos/find-element-specs.js b/test/functional/android/apidemos/find-element-specs.js index 61c65d129..52ac2b724 100644 --- a/test/functional/android/apidemos/find-element-specs.js +++ b/test/functional/android/apidemos/find-element-specs.js @@ -130,7 +130,6 @@ describe("apidemo - find elements -", function () { var f = "android.widget.FrameLayout"; var l = alv; var t = atv; - var v = "android.view.View"; it('should find element by type', function (done) { driver .elementByXPath('//' + t).text() @@ -158,7 +157,7 @@ describe("apidemo - find elements -", function () { }); it('should find element by xpath index and child', function (done) { driver - .elementByXPath("//" + f + "[1]/" + v + "[1]/" + f + "[2]/" + l + "[1]/" + t + "[3]").text() + .elementByXPath("//" + f + "[1]/" + l + "[1]/" + t + "[3]").text() .should.become("App") .nodeify(done); });