-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f260d24
Showing
13 changed files
with
788 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
.idea | ||
*.iml | ||
.gradle | ||
local.properties | ||
.DS_Store | ||
build | ||
/captures |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
apply plugin: 'com.android.library' | ||
|
||
android { | ||
compileSdkVersion 23 | ||
buildToolsVersion "23.0.1" | ||
|
||
defaultConfig { | ||
minSdkVersion 18 | ||
targetSdkVersion 23 | ||
versionCode 1 | ||
versionName "0.1.0" | ||
} | ||
} | ||
|
||
dependencies { | ||
compile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1' | ||
compile 'com.android.support.test:runner:0.4.1' | ||
compile 'com.android.support.test:rules:0.4.1' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<manifest package="com.lukekorth.deviceautomator"> | ||
</manifest> |
65 changes: 65 additions & 0 deletions
65
DeviceAutomator/src/main/java/com/lukekorth/deviceautomator/AutomatorAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package com.lukekorth.deviceautomator; | ||
|
||
import android.support.test.uiautomator.UiObject; | ||
import android.support.test.uiautomator.UiObjectNotFoundException;import java.lang.Override;import java.lang.RuntimeException;import java.lang.String; | ||
|
||
/** | ||
* A collection of actions for use with {@link DeviceAutomator}. | ||
*/ | ||
public abstract class AutomatorAction { | ||
|
||
/** | ||
* Performs a click on the ui element specified in | ||
* {@link DeviceAutomator#onDevice(UiObjectMatcher)}. | ||
* | ||
* @return | ||
*/ | ||
public static AutomatorAction click() { | ||
return new AutomatorAction() { | ||
@Override | ||
void wrappedPerform(UiObject object) throws UiObjectNotFoundException { | ||
object.click(); | ||
} | ||
}; | ||
} | ||
|
||
/** | ||
* Sets the text on the ui element specified in | ||
* {@link DeviceAutomator#onDevice(UiObjectMatcher)}. | ||
* | ||
* @return | ||
*/ | ||
public static AutomatorAction setText(final String text) { | ||
return new AutomatorAction() { | ||
@Override | ||
void wrappedPerform(UiObject object) throws UiObjectNotFoundException { | ||
object.setText(text); | ||
} | ||
}; | ||
} | ||
|
||
/** | ||
* Clears the text field on the ui element specified in | ||
* {@link DeviceAutomator#onDevice(UiObjectMatcher)}. | ||
* | ||
* @return | ||
*/ | ||
public static AutomatorAction clearTextField() { | ||
return new AutomatorAction() { | ||
@Override | ||
void wrappedPerform(UiObject object) throws UiObjectNotFoundException { | ||
object.clearTextField(); | ||
} | ||
}; | ||
} | ||
|
||
void perform(UiObject object) { | ||
try { | ||
wrappedPerform(object); | ||
} catch (UiObjectNotFoundException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
abstract void wrappedPerform(UiObject object) throws UiObjectNotFoundException; | ||
} |
80 changes: 80 additions & 0 deletions
80
DeviceAutomator/src/main/java/com/lukekorth/deviceautomator/AutomatorAssertion.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package com.lukekorth.deviceautomator; | ||
|
||
import android.graphics.Rect; | ||
import android.support.test.uiautomator.UiObject; | ||
import android.support.test.uiautomator.UiObjectNotFoundException; | ||
|
||
import org.hamcrest.Matcher; | ||
import org.hamcrest.StringDescription; | ||
|
||
import java.lang.Override;import java.lang.RuntimeException;import static junit.framework.Assert.assertTrue; | ||
|
||
/** | ||
* A collection of assertions for use with {@link DeviceAutomator}. | ||
*/ | ||
public abstract class AutomatorAssertion { | ||
|
||
/** | ||
* Asserts that the ui element specified in {@link DeviceAutomator#onDevice(UiObjectMatcher)} | ||
* has text that matches the given matcher. | ||
* | ||
* @param matcher The <a href="http://hamcrest.org/JavaHamcrest/">Hamcrest</a> to match against. | ||
* @return | ||
*/ | ||
public static AutomatorAssertion text(final Matcher matcher) { | ||
return new AutomatorAssertion() { | ||
@Override | ||
void wrappedCheck(UiObject object) throws UiObjectNotFoundException { | ||
assertObjectVisible(object); | ||
if (!matcher.matches(object.getText())) { | ||
StringDescription description = new StringDescription(); | ||
description.appendText("Expected "); | ||
matcher.describeTo(description); | ||
description.appendText(" "); | ||
matcher.describeMismatch(object.getText(), description); | ||
assertTrue(description.toString(), false); | ||
} | ||
} | ||
}; | ||
} | ||
|
||
/** | ||
* Asserts that the ui element specified in {@link DeviceAutomator#onDevice(UiObjectMatcher)} | ||
* has a content description that matches the given matcher. | ||
* | ||
* @param matcher The <a href="http://hamcrest.org/JavaHamcrest/">Hamcrest</a> to match against. | ||
* @return | ||
*/ | ||
public static AutomatorAssertion contentDescription(final Matcher matcher) { | ||
return new AutomatorAssertion() { | ||
@Override | ||
void wrappedCheck(UiObject object) throws UiObjectNotFoundException { | ||
assertObjectVisible(object); | ||
if (!matcher.matches(object.getContentDescription())) { | ||
StringDescription description = new StringDescription(); | ||
description.appendText("Expected "); | ||
matcher.describeTo(description); | ||
description.appendText(" "); | ||
matcher.describeMismatch(object.getText(), description); | ||
assertTrue(description.toString(), false); | ||
} | ||
} | ||
}; | ||
} | ||
|
||
void check(UiObject object) { | ||
try { | ||
wrappedCheck(object); | ||
} catch (UiObjectNotFoundException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
abstract void wrappedCheck(UiObject object) throws UiObjectNotFoundException; | ||
|
||
private static void assertObjectVisible(UiObject object) throws UiObjectNotFoundException { | ||
Rect bounds = object.getVisibleBounds(); | ||
assertTrue("Matched view was not visible", bounds.width() > 0); | ||
assertTrue("Matched view was not visible", bounds.height() > 0); | ||
} | ||
} |
180 changes: 180 additions & 0 deletions
180
DeviceAutomator/src/main/java/com/lukekorth/deviceautomator/DeviceAutomator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
package com.lukekorth.deviceautomator; | ||
|
||
import android.content.Intent; | ||
import android.support.test.InstrumentationRegistry; | ||
import android.support.test.uiautomator.By; | ||
import android.support.test.uiautomator.UiDevice; | ||
import android.support.test.uiautomator.UiObject; | ||
import android.support.test.uiautomator.Until; | ||
|
||
import java.lang.String;import static android.support.test.InstrumentationRegistry.getContext; | ||
import static android.support.test.uiautomator.Until.hasObject; | ||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.core.IsNull.notNullValue; | ||
|
||
/** | ||
* The entry point for using the DeviceAutomator library. | ||
*/ | ||
public class DeviceAutomator { | ||
|
||
private UiDevice mDevice; | ||
private UiObjectMatcher mMatcher; | ||
|
||
public DeviceAutomator(UiDevice device, UiObjectMatcher matcher) { | ||
mDevice = device; | ||
mMatcher = matcher; | ||
} | ||
|
||
/** | ||
* @return {@link DeviceAutomator} without a {@link UiObjectMatcher}. Suitable for performing | ||
* global actions and launching apps. | ||
*/ | ||
public static DeviceAutomator onDevice() { | ||
return onDevice(null); | ||
} | ||
|
||
/** | ||
* @param matcher {@link UiObjectMatcher} used to specify the ui element to interact with. | ||
* @return {@link DeviceAutomator} for the supplied {@link UiObjectMatcher}. All further methods | ||
* called on this instance of {@link DeviceAutomator} will interact with the supplied | ||
* {@link UiObjectMatcher} only. | ||
*/ | ||
public static DeviceAutomator onDevice(UiObjectMatcher matcher) { | ||
return new DeviceAutomator(UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()), | ||
matcher); | ||
} | ||
|
||
/** | ||
* Presses the home button and waits for the launcher with a timeout of 5 seconds. | ||
* | ||
* @return {@link DeviceAutomator} for method chaining. | ||
*/ | ||
public DeviceAutomator onHomeScreen() { | ||
return onHomeScreen(5000); | ||
} | ||
|
||
/** | ||
* Presses the home button and waits for the launcher with the given timeout. | ||
* | ||
* @param timeout length of time in milliseconds to wait for the launcher to appear before | ||
* timing out. | ||
* @return {@link DeviceAutomator} for method chaining. | ||
*/ | ||
public DeviceAutomator onHomeScreen(long timeout) { | ||
mDevice.pressHome(); | ||
|
||
String launcherPackage = mDevice.getLauncherPackageName(); | ||
assertThat(launcherPackage, notNullValue()); | ||
mDevice.wait(hasObject(By.pkg(launcherPackage).depth(0)), timeout); | ||
|
||
return this; | ||
} | ||
|
||
/** | ||
* Launches the app with the given package name and waits for it to start with a timeout of 5 seconds. | ||
* | ||
* @param packageName package name of the app to launch. | ||
* @return {@link DeviceAutomator} for method chaining. | ||
*/ | ||
public DeviceAutomator launchApp(String packageName) { | ||
return launchApp(packageName, 5000); | ||
} | ||
|
||
/** | ||
* Launches the app with the given package name and waits for it to start with the given timeout. | ||
* | ||
* @param packageName package name of the app to launch. | ||
* @param timeout length of time in milliseconds to wait for the app to appear before timing out. | ||
* @return {@link DeviceAutomator} for method chaining. | ||
*/ | ||
public DeviceAutomator launchApp(String packageName, long timeout) { | ||
return launchApp(getContext().getPackageManager().getLaunchIntentForPackage(packageName), timeout); | ||
} | ||
|
||
/** | ||
* Launches the intent and waits for it to start with a timeout of 5 seconds. | ||
* | ||
* @param intent {@link Intent} to launch | ||
* @return {@link DeviceAutomator} for method chaining. | ||
*/ | ||
public DeviceAutomator launchApp(Intent intent) { | ||
return launchApp(intent, 5000); | ||
} | ||
|
||
/** | ||
* Launches the intent and waits for it to start with the given timeout. | ||
* | ||
* @param intent {@link Intent} to launch | ||
* @param timeout length of time in milliseconds to wait for the app to appear before timing out. | ||
* @return {@link DeviceAutomator} for method chaining. | ||
*/ | ||
public DeviceAutomator launchApp(Intent intent, long timeout) { | ||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); | ||
getContext().startActivity(intent); | ||
|
||
mDevice.wait(hasObject(By.pkg(intent.getPackage()).depth(0)), timeout); | ||
|
||
return this; | ||
} | ||
|
||
/** | ||
* Waits for the ui element specified in {@link #onDevice(UiObjectMatcher)} to be enabled with | ||
* a timeout of 5 seconds. | ||
* | ||
* @return {@link DeviceAutomator} for method chaining. | ||
*/ | ||
public DeviceAutomator waitForEnabled() { | ||
return waitForEnabled(5000); | ||
} | ||
|
||
/** | ||
* Waits for the ui element specified in {@link #onDevice(UiObjectMatcher)} to be enabled with | ||
* the given timeout. | ||
* | ||
* @return {@link DeviceAutomator} for method chaining. | ||
*/ | ||
public DeviceAutomator waitForEnabled(final long timeout) { | ||
mDevice.findObject(mMatcher.getBySelector()).wait(Until.enabled(true), timeout); | ||
return this; | ||
} | ||
|
||
/** | ||
* @param action the {@link AutomatorAction} to perform on the ui element specified in | ||
* {@link #onDevice(UiObjectMatcher)}. | ||
*/ | ||
public void perform(AutomatorAction action) { | ||
action.perform(getUiObject()); | ||
} | ||
|
||
/** | ||
* @param actions the {@link AutomatorAction}s to perform on the ui element specified in | ||
* {@link #onDevice(UiObjectMatcher)}. | ||
*/ | ||
public void perform(AutomatorAction... actions) { | ||
for (AutomatorAction action : actions) { | ||
action.perform(getUiObject()); | ||
} | ||
} | ||
|
||
/** | ||
* @param assertion the {@link AutomatorAssertion} to assert on the ui element specified in | ||
* {@link #onDevice(UiObjectMatcher)}. | ||
*/ | ||
public void check(AutomatorAssertion assertion) { | ||
assertion.check(getUiObject()); | ||
} | ||
|
||
/** | ||
* @param assertions the {@link AutomatorAssertion}s to assert on the ui element specified in | ||
* {@link #onDevice(UiObjectMatcher)}. | ||
*/ | ||
public void check(AutomatorAssertion... assertions) { | ||
for (AutomatorAssertion assertion : assertions) { | ||
assertion.check(getUiObject()); | ||
} | ||
} | ||
|
||
private UiObject getUiObject() { | ||
return mMatcher.getUiObject(mDevice); | ||
} | ||
} |
Oops, something went wrong.