package com.mercandalli.android.apps.files;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.RemoteException;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.core.deps.guava.collect.Iterables;
import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
import android.support.test.runner.lifecycle.Stage;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiSelector;
import com.squareup.spoon.Spoon;
import junit.framework.Assert;
import java.text.DateFormat;
import java.util.Date;
import static android.support.test.InstrumentationRegistry.getInstrumentation;
import static android.support.test.espresso.matcher.ViewMatchers.assertThat;
import static org.hamcrest.CoreMatchers.instanceOf;
/**
* An abstract test that launch the app and provide useful test methods.
*/
@SuppressWarnings("unused")
public class UiAutomatorLib {
/**
* A simple thread sleep.
*
* @param timeMillis The time in millis.
*/
public static void sleep(final int timeMillis) {
try {
Thread.sleep(timeMillis);
} catch (InterruptedException ignored) {
}
}
public static String getCurrentDateString() {
return DateFormat.getDateTimeInstance().format(new Date())
.replaceAll("\\s", "").replaceAll(":", "").replaceAll(",", "").trim();
}
public static Activity getActivity() {
final Activity[] activity = new Activity[1];
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
activity[0] = Iterables.getOnlyElement(ActivityLifecycleMonitorRegistry.getInstance()
.getActivitiesInStage(Stage.RESUMED));
}
});
return activity[0];
}
public static Context getContext() {
return InstrumentationRegistry.getTargetContext();
}
public static Resources getResources() {
return InstrumentationRegistry.getTargetContext().getResources();
}
//region UI AUTOMATOR base
public static UiDevice getDevice() {
return UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
}
public static void pressBack() {
getDevice().pressBack();
}
//endregion UI AUTOMATOR base
//region - find object and determine object stats
/**
* Find an {@link UiObject} with the resource id.
*
* @param id The resource id (e.g. R.id.toolbar).
* @return The UiObject.
*/
@NonNull
public static UiObject findObjectById(@IdRes final int id) {
return findObjectById(getResources().getResourceName(id));
}
/**
* Find an {@link UiObject} with the resource id.
*
* @param id The resource id (e.g. the_package_name:id/the_id).
* @return The UiObject.
*/
@NonNull
public static UiObject findObjectById(final String id) {
return getDevice().findObject(new UiSelector().resourceId(id));
}
/**
* Find an {@link UiObject} with a specific {@link String} displayed.
*
* @param text A text displayed.
* @return The UiObject.
*/
@NonNull
public static UiObject findObjectContainsText(final String text) {
return getDevice().findObject(new UiSelector().textContains(text));
}
/**
* Find an {@link UiObject} with a specific {@link String} displayed.
*
* @param containsTextId The string resource id (e.g. R.string.the_id).
* @return The UiObject.
*/
@NonNull
public static UiObject findObjectContainsText(@StringRes final int containsTextId) {
return getDevice().findObject(new UiSelector().textContains(getResources().getString(containsTextId)));
}
/**
* Is this {@link UiObject} clickable.
*
* @param uiObject A {@link UiObject}.
* @return True if clickable.
* @throws UiObjectNotFoundException Throw an exception if not found.
*/
public static boolean isObjectClickable(final UiObject uiObject) throws UiObjectNotFoundException {
return uiObject != null && uiObject.exists() && uiObject.isClickable();
}
//endregion - find object and determine object stats
//region - click & swipe
/**
* Call clickAndWaitForNewWindow.
*
* @param id The view id.
* @throws UiObjectNotFoundException
*/
public static boolean click(
@IdRes final int id) throws UiObjectNotFoundException {
return findObjectById(id).click();
}
/**
* Call clickAndWaitForNewWindow.
*
* @param id The view id.
* @throws UiObjectNotFoundException
*/
public static boolean clickWaitNewWindow(
@IdRes final int id) throws UiObjectNotFoundException {
return clickWaitNewWindow(id, 5_500);
}
/**
* Call clickAndWaitForNewWindow.
*
* @param id The view id.
* @param timeout timeout before giving up on waiting for a new window
* @throws UiObjectNotFoundException Throw an exception if not found.
*/
public static boolean clickWaitNewWindow(
@IdRes final int id,
final long timeout) throws UiObjectNotFoundException {
return findObjectById(id).clickAndWaitForNewWindow(timeout);
}
/**
* Call clickAndWaitForNewWindow. You can use this method to click on external app view
* like a system popup or the launcher screen...
*
* @param id The full string id given by sdk/tools/uiautomatorviewer.bat.
* (e.g. the_package_name:id/the_id).
* @return The clickAndWaitForNewWindow result.
* @throws UiObjectNotFoundException Throw an exception if not found.
*/
public static boolean clickWaitNewWindow(
final String id) throws UiObjectNotFoundException {
return findObjectById(id).clickAndWaitForNewWindow(5_500);
}
/**
* Check if the object exists and click on it (wait new windows).
*
* @param containsText The text displayed.
* @return The clickAndWaitForNewWindow result.
* @throws UiObjectNotFoundException Throw an exception if not found.
*/
public static boolean clickWaitNewWindowContainsText(
final String containsText) throws UiObjectNotFoundException {
final UiObject uiObject = findObjectContainsText(containsText);
Assert.assertTrue(uiObject.exists());
return uiObject.clickAndWaitForNewWindow(5_500);
}
/**
* Check if the object exists and click on it (wait new windows).
*
* @param containsTextId The text displayed.
* @return The clickAndWaitForNewWindow result.
* @throws UiObjectNotFoundException Throw an exception if not found.
*/
public static boolean clickWaitNewWindowContainsText(
@StringRes final int containsTextId) throws UiObjectNotFoundException {
final UiObject uiObject = findObjectContainsText(containsTextId);
Assert.assertTrue(uiObject.exists());
return uiObject.clickAndWaitForNewWindow(5_500);
}
public static boolean swipeUpById(
@IdRes final int id,
final int speedSteps) throws UiObjectNotFoundException {
return findObjectById(id).swipeUp(speedSteps);
}
public static boolean swipeDownById(
@IdRes final int id,
final int speedSteps) throws UiObjectNotFoundException {
return findObjectById(id).swipeDown(speedSteps);
}
public static boolean swipeLeftById(
@IdRes final int id,
final int speedSteps) throws UiObjectNotFoundException {
return findObjectById(id).swipeLeft(speedSteps);
}
public static boolean swipeRightById(
@IdRes final int id,
final int speedSteps) throws UiObjectNotFoundException {
return findObjectById(id).swipeRight(speedSteps);
}
//endregion - click & swipe
//region - setText
public static void setText(
final String id,
final String text) throws UiObjectNotFoundException {
final UiObject objectById = findObjectById(id);
objectById.clickAndWaitForNewWindow(100);
objectById.setText(text);
}
public static void setText(
@IdRes final int id,
final String text) throws UiObjectNotFoundException {
setText(getResources().getResourceName(id), text);
}
//endregion - setText
//region - assert
public static void assertExists(@IdRes final int id) throws UiObjectNotFoundException {
Assert.assertTrue(isObjectClickable(id));
}
public static void assertExistsContains(final String textContains) {
Assert.assertTrue(isObjectExistsContains(textContains));
}
public static boolean isObjectClickable(@IdRes final int id) throws UiObjectNotFoundException {
return findObjectById(id).exists();
}
public static boolean isObjectExistsContains(final String textContains) {
return getDevice().findObject(new UiSelector()
.textContains(textContains))
.exists();
}
//endregion - assert
//region - device actions
public static void orientationLeft() {
try {
getDevice().setOrientationRight();
} catch (RemoteException e) {
e.printStackTrace();
}
sleep(100);
}
public static void orientationRight() {
try {
getDevice().setOrientationLeft();
} catch (RemoteException e) {
e.printStackTrace();
}
sleep(100);
}
public static void orientationPortrait() {
try {
getDevice().setOrientationNatural();
} catch (RemoteException e) {
e.printStackTrace();
}
sleep(100);
}
//endregion - device actions
public static void takeScreenShot(final String title) {
takeScreenShot(getActivity(), title);
}
public static void takeScreenShot(final Activity activity, final String title) {
Spoon.screenshot(activity, title);
}
/**
* Assert that the current activity is an instance of a given class and finish it.
*
* @param activityClass the {@link Class}
* @throws Throwable
*/
public static void finish(Class<? extends Activity> activityClass) {
sleep(800);
final Activity currentActivity = getActivity();
assertThat(currentActivity, instanceOf(activityClass));
currentActivity.finish();
sleep(800);
}
}