aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Jin <kjin@google.com>2015-03-05 00:59:56 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-03-05 00:59:56 +0000
commit1fc31e3fd3f398fcde9e047b0973fdfe520c51f8 (patch)
treed2837fe8234298033d445050b363ce641cb82ca2
parent26cc74f049a54e7efb9a6a89b8d98d060898a1ed (diff)
parent3c34ee0c7e6a74c37483c4e0fdd3691e639cc8c2 (diff)
downloaddroiddriver-1fc31e3fd3f398fcde9e047b0973fdfe520c51f8.tar.gz
am 3c34ee0c: am f2c56347: Merge "Add droiddriver-android_support_test"
* commit '3c34ee0c7e6a74c37483c4e0fdd3691e639cc8c2': Add droiddriver-android_support_test
-rw-r--r--droiddriver-android_support_test/Android.mk19
-rw-r--r--droiddriver-android_support_test/AndroidManifest.xml5
-rw-r--r--droiddriver-android_support_test/build.gradle58
-rw-r--r--droiddriver-android_support_test/readme.md5
-rw-r--r--droiddriver-android_support_test/src/io/appium/droiddriver/android_support_test/D2AndroidJUnitRunner.java140
-rw-r--r--manualtest/build.gradle2
-rw-r--r--src/io/appium/droiddriver/runner/TestRunner.java18
7 files changed, 240 insertions, 7 deletions
diff --git a/droiddriver-android_support_test/Android.mk b/droiddriver-android_support_test/Android.mk
new file mode 100644
index 0000000..22c6c0a
--- /dev/null
+++ b/droiddriver-android_support_test/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := droiddriver-android_support_test
+LOCAL_MODULE_TAGS := optional
+LOCAL_SDK_VERSION := 19
+
+LOCAL_JAVACFLAGS += -Xlint:deprecation -Xlint:unchecked
+
+# android-support-test requires /frameworks/testing, /external/junit, /external/hamcrest
+LOCAL_JAVA_LIBRARIES := droiddriver android-support-test
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/droiddriver-android_support_test/AndroidManifest.xml b/droiddriver-android_support_test/AndroidManifest.xml
new file mode 100644
index 0000000..f9f47f8
--- /dev/null
+++ b/droiddriver-android_support_test/AndroidManifest.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest
+ package="io.appium.droiddriver.android_support_test">
+
+</manifest>
diff --git a/droiddriver-android_support_test/build.gradle b/droiddriver-android_support_test/build.gradle
new file mode 100644
index 0000000..8dab32a
--- /dev/null
+++ b/droiddriver-android_support_test/build.gradle
@@ -0,0 +1,58 @@
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ // this requires Gradle 2
+ classpath 'com.android.tools.build:gradle:1.0.1'
+ classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0'
+ }
+}
+
+apply plugin: 'android-sdk-manager'
+apply plugin: 'com.android.library'
+
+repositories {
+ jcenter()
+}
+
+dependencies {
+ // During development, this should be set to droiddriver SNAPSHOT
+ compile 'io.appium:droiddriver:0.9.1'
+ compile 'com.android.support.test:testing-support-lib:0.1'
+}
+
+tasks.withType(JavaCompile) {
+ options.compilerArgs << '-Xlint:deprecation'
+}
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion '21.1.2'
+
+ defaultConfig {
+ minSdkVersion 8
+ targetSdkVersion 21
+ versionCode 1
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+
+ sourceSets {
+ main {
+ manifest.srcFile 'AndroidManifest.xml'
+ java.srcDirs = ['src']
+ }
+ }
+
+ lintOptions {
+ // Aborting on lint errors prevents jenkins from processing the Lint output
+ // https://wiki.jenkins-ci.org/display/JENKINS/Android%20Lint%20Plugin
+ abortOnError false
+ }
+}
+
+//TODO: add script for publishing
diff --git a/droiddriver-android_support_test/readme.md b/droiddriver-android_support_test/readme.md
new file mode 100644
index 0000000..f4d7ebb
--- /dev/null
+++ b/droiddriver-android_support_test/readme.md
@@ -0,0 +1,5 @@
+# droiddriver-android_support_test
+
+An optional library that integrates DroidDriver with [the Android Support Test Library](https://code.google.com/p/android-test-kit/wiki/AndroidJUnitRunnerUserGuide).
+This is an experimental library because the Android Support Test Library is at early stage and many
+APIs are in internal packages. \ No newline at end of file
diff --git a/droiddriver-android_support_test/src/io/appium/droiddriver/android_support_test/D2AndroidJUnitRunner.java b/droiddriver-android_support_test/src/io/appium/droiddriver/android_support_test/D2AndroidJUnitRunner.java
new file mode 100644
index 0000000..7924380
--- /dev/null
+++ b/droiddriver-android_support_test/src/io/appium/droiddriver/android_support_test/D2AndroidJUnitRunner.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2015 DroidDriver committers
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.appium.droiddriver.android_support_test;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Looper;
+import android.support.test.internal.runner.lifecycle.ActivityLifecycleMonitorRegistry;
+import android.support.test.runner.AndroidJUnitRunner;
+import android.support.test.runner.lifecycle.Stage;
+import android.util.Log;
+
+import java.util.Iterator;
+import java.util.concurrent.Callable;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+
+import io.appium.droiddriver.exceptions.DroidDriverException;
+import io.appium.droiddriver.exceptions.TimeoutException;
+import io.appium.droiddriver.helpers.DroidDrivers;
+import io.appium.droiddriver.util.ActivityUtils;
+import io.appium.droiddriver.util.Logs;
+
+/**
+ * Integrates DroidDriver with AndroidJUnitRunner. <p> TODO: support DroidDriver test filter
+ * annotations.
+ */
+public class D2AndroidJUnitRunner extends AndroidJUnitRunner {
+ private static final Callable<Activity> GET_RUNNING_ACTIVITY = new Callable<Activity>() {
+ @Override
+ public Activity call() {
+ Iterator<Activity> activityIterator = ActivityLifecycleMonitorRegistry.getInstance()
+ .getActivitiesInStage(Stage.RESUMED).iterator();
+ return activityIterator.hasNext() ? activityIterator.next() : null;
+ }
+ };
+
+ /**
+ * {@inheritDoc} <p> Sets the values for the convenience methods {@link
+ * DroidDrivers#getInstrumentation()} and {@link DroidDrivers#getOptions()}.
+ */
+ @Override
+ public void onCreate(Bundle arguments) {
+ DroidDrivers.initInstrumentation(this, arguments);
+ super.onCreate(arguments);
+ }
+
+ /**
+ * {@inheritDoc} <p> Hooks {@link ActivityUtils#setRunningActivitySupplier} to {@link
+ * ActivityLifecycleMonitorRegistry}.
+ */
+ @Override
+ public void onStart() {
+ ActivityUtils.setRunningActivitySupplier(new ActivityUtils.Supplier<Activity>() {
+ @Override
+ public Activity get() {
+ try {
+ // If this is called on main (UI) thread, don't call runOnMainSync
+ if (Looper.myLooper() == Looper.getMainLooper()) {
+ return GET_RUNNING_ACTIVITY.call();
+ }
+
+ return runOnMainSyncWithTimeout(GET_RUNNING_ACTIVITY);
+ } catch (Exception e) {
+ Logs.log(Log.WARN, e);
+ return null;
+ }
+ }
+ });
+ super.onStart();
+ }
+
+ /**
+ * Runs {@code callable} on the main thread on best-effort basis up to a time limit, which
+ * defaults to {@code 10000L} and can be set as an <a href= "http://developer.android.com/tools/testing/testing_otheride.html#AMOptionsSyntax">
+ * am instrument option</a> under the key {@code dd.runOnMainSyncTimeout}. <p>This is a safer
+ * variation of {@link #runOnMainSync} because the latter may hang. But it is heavy because a new
+ * thread is created for each call unless the am command line specifies {@code
+ * dd.runOnMainSyncTimeout <=0} such as "-e dd.runOnMainSyncTimeout 0".</p>The {@code callable}
+ * may never run, for example, in case that the main Looper has exited due to uncaught exception.
+ */
+ // TODO: move this to DroidDrivers
+ // TODO: call runOnMainSync on a single worker thread?
+ private <V> V runOnMainSyncWithTimeout(Callable<V> callable) {
+ final RunOnMainSyncFutureTask<V> futureTask = new RunOnMainSyncFutureTask<>(callable);
+
+ String timeoutMillisString = DroidDrivers.getOptions().getString("dd.runOnMainSyncTimeout");
+ long timeoutMillis = timeoutMillisString == null? 10000L : Long.parseLong(timeoutMillisString);
+ if (timeoutMillis <= 0L) {
+ // Call runOnMainSync on current thread without time limit.
+ futureTask.runOnMainSyncNoThrow();
+ } else {
+ new Thread() {
+ @Override
+ public void run() {
+ futureTask.runOnMainSyncNoThrow();
+ }
+ }.start();
+ }
+
+ try {
+ return futureTask.get(timeoutMillis, TimeUnit.MILLISECONDS);
+ } catch (java.util.concurrent.TimeoutException e) {
+ throw new TimeoutException("Timed out after " + timeoutMillis
+ + " milliseconds waiting for Instrumentation.runOnMainSync", e);
+ } catch (Throwable e) {
+ throw new DroidDriverException(e);
+ } finally {
+ futureTask.cancel(false);
+ }
+ }
+
+ private class RunOnMainSyncFutureTask<V> extends FutureTask<V> {
+ public RunOnMainSyncFutureTask(Callable<V> callable) {
+ super(callable);
+ }
+
+ public void runOnMainSyncNoThrow() {
+ try {
+ runOnMainSync(this);
+ } catch (Throwable e) {
+ setException(e);
+ }
+ }
+ }
+}
diff --git a/manualtest/build.gradle b/manualtest/build.gradle
index 91fb5eb..a732fe3 100644
--- a/manualtest/build.gradle
+++ b/manualtest/build.gradle
@@ -16,7 +16,7 @@ android {
buildToolsVersion '21.1.2'
defaultConfig {
- minSdkVersion 12
+ minSdkVersion 8
targetSdkVersion 21
// Force remove the suffix '.test'
testApplicationId 'io.appium.droiddriver.manualtest'
diff --git a/src/io/appium/droiddriver/runner/TestRunner.java b/src/io/appium/droiddriver/runner/TestRunner.java
index ec97f9c..be92b44 100644
--- a/src/io/appium/droiddriver/runner/TestRunner.java
+++ b/src/io/appium/droiddriver/runner/TestRunner.java
@@ -16,7 +16,6 @@
package io.appium.droiddriver.runner;
-import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
@@ -64,15 +63,22 @@ public class TestRunner extends InstrumentationTestRunner {
/**
* {@inheritDoc}
* <p>
+ * Sets the values for the convenience methods {@link DroidDrivers#getInstrumentation()} and
+ * {@link DroidDrivers#getOptions()}.
+ */
+ @Override
+ public void onCreate(Bundle arguments) {
+ DroidDrivers.initInstrumentation(this, arguments);
+ super.onCreate(arguments);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
* Adds a {@link TestListener} that finishes all created activities.
*/
@Override
- @TargetApi(18)
public void onStart() {
- if (Build.VERSION.SDK_INT >= 18) {
- DroidDrivers.initInstrumentation(this, getArguments());
- }
-
getAndroidTestRunner().addTestListener(new TestListener() {
@Override
public void endTest(Test test) {