Merge "Move directory and roots support to own ui bots." into nyc-dev
This commit is contained in:
@@ -317,6 +317,12 @@ public abstract class BaseActivity extends Activity
|
||||
CreateDirectoryFragment.show(getFragmentManager());
|
||||
}
|
||||
|
||||
void onDirectoryCreated(DocumentInfo doc) {
|
||||
// By default we do nothing, just let the new directory appear.
|
||||
// DocumentsActivity auto-opens directories after creating them
|
||||
// As that is more attuned to the "picker" use cases it supports.
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a directory can be created in the current location.
|
||||
* @return
|
||||
@@ -331,11 +337,6 @@ public abstract class BaseActivity extends Activity
|
||||
&& !root.isDownloads();
|
||||
}
|
||||
|
||||
void onDirectoryCreated(DocumentInfo doc) {
|
||||
checkArgument(doc.isDirectory());
|
||||
openContainerDocument(doc);
|
||||
}
|
||||
|
||||
void openContainerDocument(DocumentInfo doc) {
|
||||
checkArgument(doc.isContainer());
|
||||
mState.pushDocument(doc);
|
||||
|
||||
@@ -23,6 +23,7 @@ import static com.android.documentsui.State.ACTION_OPEN;
|
||||
import static com.android.documentsui.State.ACTION_OPEN_TREE;
|
||||
import static com.android.documentsui.State.ACTION_PICK_COPY_DESTINATION;
|
||||
import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE;
|
||||
import static com.android.internal.util.Preconditions.checkArgument;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
@@ -316,6 +317,12 @@ public class DocumentsActivity extends BaseActivity {
|
||||
.executeOnExecutor(getExecutorForCurrentDirectory());
|
||||
}
|
||||
|
||||
@Override
|
||||
void onDirectoryCreated(DocumentInfo doc) {
|
||||
checkArgument(doc.isDirectory());
|
||||
openContainerDocument(doc);
|
||||
}
|
||||
|
||||
void onSaveRequested(String mimeType, String displayName) {
|
||||
new CreateFinishTask(this, mimeType, displayName)
|
||||
.executeOnExecutor(getExecutorForCurrentDirectory());
|
||||
|
||||
@@ -33,7 +33,6 @@ import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
@@ -21,21 +21,22 @@ import static com.android.documentsui.StubProvider.ROOT_0_ID;
|
||||
import static com.android.documentsui.StubProvider.ROOT_1_ID;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Instrumentation;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.DocumentsContract.Document;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.Configurator;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObjectNotFoundException;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.documentsui.bots.DirectoryListBot;
|
||||
import com.android.documentsui.bots.KeyboardBot;
|
||||
import com.android.documentsui.bots.RootsListBot;
|
||||
import com.android.documentsui.bots.UiBot;
|
||||
import com.android.documentsui.model.RootInfo;
|
||||
|
||||
/**
|
||||
@@ -56,7 +57,7 @@ public abstract class ActivityTest<T extends Activity> extends ActivityInstrumen
|
||||
public static final String fileName4 = "poodles.text";
|
||||
public static final String fileNameNoRename = "NO_RENAMEfile.txt";
|
||||
|
||||
public UiBot bot;
|
||||
public Bots bots;
|
||||
public UiDevice device;
|
||||
public Context context;
|
||||
|
||||
@@ -76,10 +77,11 @@ public abstract class ActivityTest<T extends Activity> extends ActivityInstrumen
|
||||
device = UiDevice.getInstance(getInstrumentation());
|
||||
// NOTE: Must be the "target" context, else security checks in content provider will fail.
|
||||
context = getInstrumentation().getTargetContext();
|
||||
bot = new UiBot(device, context, TIMEOUT);
|
||||
|
||||
bots = new Bots(device, context, TIMEOUT);
|
||||
|
||||
Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE);
|
||||
bot.revealLauncher();
|
||||
bots.main.revealLauncher();
|
||||
|
||||
mResolver = context.getContentResolver();
|
||||
mClient = mResolver.acquireUnstableContentProviderClient(DEFAULT_AUTHORITY);
|
||||
@@ -90,7 +92,7 @@ public abstract class ActivityTest<T extends Activity> extends ActivityInstrumen
|
||||
|
||||
launchActivity();
|
||||
|
||||
bot.revealApp();
|
||||
bots.main.revealApp();
|
||||
resetStorage();
|
||||
}
|
||||
|
||||
@@ -125,12 +127,31 @@ public abstract class ActivityTest<T extends Activity> extends ActivityInstrumen
|
||||
}
|
||||
|
||||
void assertDefaultContentOfTestDir0() throws UiObjectNotFoundException {
|
||||
bot.assertDocumentsCount(ROOT_0_ID, 4);
|
||||
bot.assertHasDocuments(fileName1, fileName2, dirName1, fileNameNoRename);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
bots.directory.assertDocumentsCount(4);
|
||||
bots.directory.assertDocumentsPresent(fileName1, fileName2, dirName1, fileNameNoRename);
|
||||
}
|
||||
|
||||
void assertDefaultContentOfTestDir1() throws UiObjectNotFoundException {
|
||||
bot.assertDocumentsCount(ROOT_1_ID, 2);
|
||||
bot.assertHasDocuments(fileName3, fileName4);
|
||||
bots.roots.openRoot(ROOT_1_ID);
|
||||
bots.directory.assertDocumentsCount(2);
|
||||
bots.directory.assertDocumentsPresent(fileName3, fileName4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handy collection of bots for working with Files app.
|
||||
*/
|
||||
public static final class Bots {
|
||||
public final UiBot main;
|
||||
public final RootsListBot roots;
|
||||
public final DirectoryListBot directory;
|
||||
public final KeyboardBot keyboard;
|
||||
|
||||
private Bots(UiDevice device, Context context, int timeout) {
|
||||
this.main = new UiBot(device, context, TIMEOUT);
|
||||
this.roots = new RootsListBot(device, context, TIMEOUT);
|
||||
this.directory = new DirectoryListBot(device, context, TIMEOUT);
|
||||
this.keyboard = new KeyboardBot(device, context, TIMEOUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,13 +52,13 @@ public class DownloadsActivityUiTest extends ActivityTest<DownloadsActivity> {
|
||||
public void testWindowTitle() throws Exception {
|
||||
initTestFiles();
|
||||
|
||||
bot.assertWindowTitle(ROOT_0_ID);
|
||||
bots.main.assertWindowTitle(ROOT_0_ID);
|
||||
}
|
||||
|
||||
public void testFilesListed() throws Exception {
|
||||
initTestFiles();
|
||||
|
||||
bot.assertHasDocuments("file0.log", "file1.png", "file2.csv");
|
||||
bots.directory.assertDocumentsPresent("file0.log", "file1.png", "file2.csv");
|
||||
}
|
||||
|
||||
public void testFilesList_LiveUpdate() throws Exception {
|
||||
@@ -66,30 +66,31 @@ public class DownloadsActivityUiTest extends ActivityTest<DownloadsActivity> {
|
||||
|
||||
mDocsHelper.createDocument(rootDir0, "yummers/sandwich", "Ham & Cheese.sandwich");
|
||||
|
||||
bot.waitForDocument("Ham & Cheese.sandwich");
|
||||
bot.assertHasDocuments("file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich");
|
||||
bots.directory.waitForDocument("Ham & Cheese.sandwich");
|
||||
bots.directory.assertDocumentsPresent(
|
||||
"file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich");
|
||||
}
|
||||
|
||||
public void testDeleteDocument() throws Exception {
|
||||
initTestFiles();
|
||||
|
||||
bot.clickDocument("file1.png");
|
||||
bots.directory.clickDocument("file1.png");
|
||||
device.waitForIdle();
|
||||
bot.menuDelete().click();
|
||||
bots.main.menuDelete().click();
|
||||
|
||||
bot.waitForDeleteSnackbar();
|
||||
assertFalse(bot.hasDocuments("file1.png"));
|
||||
bots.directory.waitForDeleteSnackbar();
|
||||
bots.directory.assertDocumentsAbsent("file1.png");
|
||||
|
||||
bot.waitForDeleteSnackbarGone();
|
||||
assertFalse(bot.hasDocuments("file1.png"));
|
||||
bots.directory.waitForDeleteSnackbarGone();
|
||||
bots.directory.assertDocumentsAbsent("file1.png");
|
||||
}
|
||||
|
||||
public void testSupportsShare() throws Exception {
|
||||
initTestFiles();
|
||||
|
||||
bot.clickDocument("file1.png");
|
||||
bots.directory.clickDocument("file1.png");
|
||||
device.waitForIdle();
|
||||
assertNotNull(bot.menuShare());
|
||||
assertNotNull(bots.main.menuShare());
|
||||
}
|
||||
|
||||
public void testClosesOnBack() throws Exception {
|
||||
|
||||
@@ -43,11 +43,11 @@ public class FilesActivityUiTest extends ActivityTest<FilesActivity> {
|
||||
public void testRootsListed() throws Exception {
|
||||
initTestFiles();
|
||||
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
|
||||
// Should also have Drive, but that requires pre-configuration of devices
|
||||
// We omit for now.
|
||||
bot.assertHasRoots(
|
||||
bots.roots.assertHasRoots(
|
||||
"Images",
|
||||
"Videos",
|
||||
"Audio",
|
||||
@@ -60,93 +60,106 @@ public class FilesActivityUiTest extends ActivityTest<FilesActivity> {
|
||||
public void testFilesListed() throws Exception {
|
||||
initTestFiles();
|
||||
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bot.assertHasDocuments("file0.log", "file1.png", "file2.csv");
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
bots.directory.assertDocumentsPresent("file0.log", "file1.png", "file2.csv");
|
||||
}
|
||||
|
||||
public void testLoadsHomeDirectoryByDefault() throws Exception {
|
||||
initTestFiles();
|
||||
|
||||
device.waitForIdle();
|
||||
bot.assertWindowTitle("Documents");
|
||||
bots.main.assertWindowTitle("Documents");
|
||||
}
|
||||
|
||||
public void testRootClickSetsWindowTitle() throws Exception {
|
||||
initTestFiles();
|
||||
|
||||
bot.openRoot("Downloads");
|
||||
bot.assertWindowTitle("Downloads");
|
||||
bots.roots.openRoot("Downloads");
|
||||
bots.main.assertWindowTitle("Downloads");
|
||||
}
|
||||
|
||||
public void testFilesList_LiveUpdate() throws Exception {
|
||||
initTestFiles();
|
||||
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
mDocsHelper.createDocument(rootDir0, "yummers/sandwich", "Ham & Cheese.sandwich");
|
||||
|
||||
bot.waitForDocument("Ham & Cheese.sandwich");
|
||||
bot.assertHasDocuments("file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich");
|
||||
bots.directory.waitForDocument("Ham & Cheese.sandwich");
|
||||
bots.directory.assertDocumentsPresent(
|
||||
"file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich");
|
||||
}
|
||||
|
||||
public void testCreateDirectory() throws Exception {
|
||||
initTestFiles();
|
||||
|
||||
bots.main.openOverflowMenu();
|
||||
bots.main.menuNewFolder().click();
|
||||
bots.main.setDialogText("Kung Fu Panda");
|
||||
|
||||
bots.keyboard.pressEnter();
|
||||
|
||||
bots.directory.assertDocumentsPresent("Kung Fu Panda");
|
||||
}
|
||||
|
||||
public void testDeleteDocument() throws Exception {
|
||||
initTestFiles();
|
||||
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
|
||||
bot.clickDocument("file1.png");
|
||||
bots.directory.clickDocument("file1.png");
|
||||
device.waitForIdle();
|
||||
bot.menuDelete().click();
|
||||
bots.main.menuDelete().click();
|
||||
|
||||
bot.waitForDeleteSnackbar();
|
||||
assertFalse(bot.hasDocuments("file1.png"));
|
||||
bots.directory.waitForDeleteSnackbar();
|
||||
bots.directory.assertDocumentsAbsent("file1.png");
|
||||
|
||||
bot.waitForDeleteSnackbarGone();
|
||||
assertFalse(bot.hasDocuments("file1.png"));
|
||||
bots.directory.waitForDeleteSnackbarGone();
|
||||
bots.directory.assertDocumentsAbsent("file1.png");
|
||||
|
||||
// Now delete from another root.
|
||||
bot.openRoot(ROOT_1_ID);
|
||||
bots.roots.openRoot(ROOT_1_ID);
|
||||
|
||||
bot.clickDocument("poodles.text");
|
||||
bots.directory.clickDocument("poodles.text");
|
||||
device.waitForIdle();
|
||||
bot.menuDelete().click();
|
||||
bots.main.menuDelete().click();
|
||||
|
||||
bot.waitForDeleteSnackbar();
|
||||
assertFalse(bot.hasDocuments("poodles.text"));
|
||||
bots.directory.waitForDeleteSnackbar();
|
||||
bots.directory.assertDocumentsAbsent("poodles.text");
|
||||
|
||||
bot.waitForDeleteSnackbarGone();
|
||||
assertFalse(bot.hasDocuments("poodles.text"));
|
||||
bots.directory.waitForDeleteSnackbarGone();
|
||||
bots.directory.assertDocumentsAbsent("poodles.text");
|
||||
}
|
||||
|
||||
// Tests that pressing tab switches focus between the roots and directory listings.
|
||||
public void testKeyboard_tab() throws Exception {
|
||||
bot.pressKey(KeyEvent.KEYCODE_TAB);
|
||||
bot.assertHasFocus("com.android.documentsui:id/roots_list");
|
||||
bot.pressKey(KeyEvent.KEYCODE_TAB);
|
||||
bot.assertHasFocus("com.android.documentsui:id/dir_list");
|
||||
bots.main.pressKey(KeyEvent.KEYCODE_TAB);
|
||||
bots.roots.assertHasFocus();
|
||||
bots.main.pressKey(KeyEvent.KEYCODE_TAB);
|
||||
bots.directory.assertHasFocus();
|
||||
}
|
||||
|
||||
// Tests that arrow keys do not switch focus away from the dir list.
|
||||
public void testKeyboard_arrowsDirList() throws Exception {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
bot.pressKey(KeyEvent.KEYCODE_DPAD_LEFT);
|
||||
bot.assertHasFocus("com.android.documentsui:id/dir_list");
|
||||
bots.main.pressKey(KeyEvent.KEYCODE_DPAD_LEFT);
|
||||
bots.directory.assertHasFocus();
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
bot.pressKey(KeyEvent.KEYCODE_DPAD_RIGHT);
|
||||
bot.assertHasFocus("com.android.documentsui:id/dir_list");
|
||||
bots.main.pressKey(KeyEvent.KEYCODE_DPAD_RIGHT);
|
||||
bots.directory.assertHasFocus();
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that arrow keys do not switch focus away from the roots list.
|
||||
public void testKeyboard_arrowsRootsList() throws Exception {
|
||||
bot.pressKey(KeyEvent.KEYCODE_TAB);
|
||||
bots.main.pressKey(KeyEvent.KEYCODE_TAB);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
bot.pressKey(KeyEvent.KEYCODE_DPAD_RIGHT);
|
||||
bot.assertHasFocus("com.android.documentsui:id/roots_list");
|
||||
bots.main.pressKey(KeyEvent.KEYCODE_DPAD_RIGHT);
|
||||
bots.roots.assertHasFocus();
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
bot.pressKey(KeyEvent.KEYCODE_DPAD_LEFT);
|
||||
bot.assertHasFocus("com.android.documentsui:id/roots_list");
|
||||
bots.main.pressKey(KeyEvent.KEYCODE_DPAD_LEFT);
|
||||
bots.roots.assertHasFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ import android.test.suitebuilder.annotation.LargeTest;
|
||||
@LargeTest
|
||||
public class RenameDocumentUiTest extends ActivityTest<FilesActivity> {
|
||||
|
||||
private static final String TAG = "RenamDocumentUiTest";
|
||||
|
||||
private final String newName = "kitties.log";
|
||||
|
||||
public RenameDocumentUiTest() {
|
||||
@@ -35,125 +33,119 @@ public class RenameDocumentUiTest extends ActivityTest<FilesActivity> {
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
initTestFiles();
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
}
|
||||
|
||||
public void testRenameEnabled_SingleSelection() throws Exception {
|
||||
bot.selectDocument(fileName1);
|
||||
bot.openOverflowMenu();
|
||||
bot.assertMenuEnabled(R.string.menu_rename, true);
|
||||
bots.directory.selectDocument(fileName1);
|
||||
bots.main.openOverflowMenu();
|
||||
bots.main.assertMenuEnabled(R.string.menu_rename, true);
|
||||
|
||||
// Dismiss more options window
|
||||
device.pressBack();
|
||||
}
|
||||
|
||||
public void testNoRenameSupport_SingleSelection() throws Exception {
|
||||
bot.selectDocument(fileNameNoRename);
|
||||
bot.openOverflowMenu();
|
||||
bot.assertMenuEnabled(R.string.menu_rename, false);
|
||||
bots.directory.selectDocument(fileNameNoRename);
|
||||
bots.main.openOverflowMenu();
|
||||
bots.main.assertMenuEnabled(R.string.menu_rename, false);
|
||||
|
||||
// Dismiss more options window
|
||||
device.pressBack();
|
||||
}
|
||||
|
||||
public void testOneHasRenameSupport_MultipleSelection() throws Exception {
|
||||
bot.selectDocument(fileName1);
|
||||
bot.selectDocument(fileNameNoRename);
|
||||
bot.openOverflowMenu();
|
||||
bot.assertMenuEnabled(R.string.menu_rename, false);
|
||||
bots.directory.selectDocument(fileName1);
|
||||
bots.directory.selectDocument(fileNameNoRename);
|
||||
bots.main.openOverflowMenu();
|
||||
bots.main.assertMenuEnabled(R.string.menu_rename, false);
|
||||
|
||||
// Dismiss more options window
|
||||
device.pressBack();
|
||||
}
|
||||
|
||||
public void testRenameDisabled_MultipleSelection() throws Exception {
|
||||
bot.selectDocument(fileName1);
|
||||
bot.selectDocument(fileName2);
|
||||
bot.openOverflowMenu();
|
||||
bot.assertMenuEnabled(R.string.menu_rename, false);
|
||||
bots.directory.selectDocument(fileName1);
|
||||
bots.directory.selectDocument(fileName2);
|
||||
bots.main.openOverflowMenu();
|
||||
bots.main.assertMenuEnabled(R.string.menu_rename, false);
|
||||
|
||||
// Dismiss more options window
|
||||
device.pressBack();
|
||||
}
|
||||
|
||||
public void testRenameFile_OkButton() throws Exception {
|
||||
bot.selectDocument(fileName1);
|
||||
bot.openOverflowMenu();
|
||||
bot.openDialog(R.string.menu_rename);
|
||||
bot.setDialogText(newName);
|
||||
bots.directory.selectDocument(fileName1);
|
||||
bots.main.openOverflowMenu();
|
||||
bots.main.menuRename().click();
|
||||
bots.main.setDialogText(newName);
|
||||
|
||||
device.waitForIdle(TIMEOUT);
|
||||
bot.findRenameDialogOkButton().click();
|
||||
bots.main.findRenameDialogOkButton().click();
|
||||
device.waitForIdle(TIMEOUT);
|
||||
|
||||
bot.assertDocument(fileName1, false);
|
||||
bot.assertDocument(newName, true);
|
||||
bot.assertDocumentsCount(4);
|
||||
bots.directory.assertDocumentsAbsent(fileName1);
|
||||
bots.directory.assertDocumentsPresent(newName);
|
||||
bots.directory.assertDocumentsCount(4);
|
||||
}
|
||||
|
||||
public void testRenameFile_Enter() throws Exception {
|
||||
bot.selectDocument(fileName1);
|
||||
bot.openOverflowMenu();
|
||||
bot.openDialog(R.string.menu_rename);
|
||||
bot.setDialogText(newName);
|
||||
bots.directory.selectDocument(fileName1);
|
||||
bots.main.openOverflowMenu();
|
||||
bots.main.menuRename().click();
|
||||
bots.main.setDialogText(newName);
|
||||
|
||||
pressEnter();
|
||||
bots.keyboard.pressEnter();
|
||||
|
||||
bot.assertDocument(fileName1, false);
|
||||
bot.assertDocument(newName, true);
|
||||
bot.assertDocumentsCount(4);
|
||||
bots.directory.assertDocumentsAbsent(fileName1);
|
||||
bots.directory.assertDocumentsPresent(newName);
|
||||
bots.directory.assertDocumentsCount(4);
|
||||
}
|
||||
|
||||
public void testRenameFile_Cancel() throws Exception {
|
||||
bot.selectDocument(fileName1);
|
||||
bot.openOverflowMenu();
|
||||
bot.openDialog(R.string.menu_rename);
|
||||
bot.setDialogText(newName);
|
||||
bots.directory.selectDocument(fileName1);
|
||||
bots.main.openOverflowMenu();
|
||||
bots.main.menuRename().click();
|
||||
bots.main.setDialogText(newName);
|
||||
|
||||
device.waitForIdle(TIMEOUT);
|
||||
bot.findRenameDialogCancelButton().click();
|
||||
bots.main.findRenameDialogCancelButton().click();
|
||||
device.waitForIdle(TIMEOUT);
|
||||
|
||||
bot.assertDocument(fileName1, true);
|
||||
bot.assertDocument(newName, false);
|
||||
bot.assertDocumentsCount(4);
|
||||
bots.directory.assertDocumentsPresent(fileName1);
|
||||
bots.directory.assertDocumentsAbsent(newName);
|
||||
bots.directory.assertDocumentsCount(4);
|
||||
}
|
||||
|
||||
public void testRenameDir() throws Exception {
|
||||
String oldName = "Dir1";
|
||||
String newName = "Dir123";
|
||||
|
||||
bot.selectDocument(oldName);
|
||||
bot.openOverflowMenu();
|
||||
bot.openDialog(R.string.menu_rename);
|
||||
bot.setDialogText(newName);
|
||||
bots.directory.selectDocument(oldName);
|
||||
bots.main.openOverflowMenu();
|
||||
bots.main.menuRename().click();
|
||||
bots.main.setDialogText(newName);
|
||||
|
||||
pressEnter();
|
||||
bots.keyboard.pressEnter();
|
||||
|
||||
bot.assertDocument(oldName, false);
|
||||
bot.assertDocument(newName, true);
|
||||
bot.assertDocumentsCount(4);
|
||||
bots.directory.assertDocumentsAbsent(oldName);
|
||||
bots.directory.assertDocumentsPresent(newName);
|
||||
bots.directory.assertDocumentsCount(4);
|
||||
}
|
||||
|
||||
public void testRename_NameExists() throws Exception {
|
||||
// Check that document with the new name exists
|
||||
bot.assertDocument(fileName2, true);
|
||||
bot.selectDocument(fileName1);
|
||||
bot.openOverflowMenu();
|
||||
bot.openDialog(R.string.menu_rename);
|
||||
bot.setDialogText(fileName2);
|
||||
bots.directory.assertDocumentsPresent(fileName2);
|
||||
bots.directory.selectDocument(fileName1);
|
||||
bots.main.openOverflowMenu();
|
||||
bots.main.menuRename().click();
|
||||
bots.main.setDialogText(fileName2);
|
||||
|
||||
pressEnter();
|
||||
bots.keyboard.pressEnter();
|
||||
|
||||
bot.assertSnackbar(R.string.rename_error);
|
||||
bot.assertDocument(fileName1, true);
|
||||
bot.assertDocument(fileName2, true);
|
||||
bot.assertDocumentsCount(4);
|
||||
}
|
||||
|
||||
private void pressEnter() {
|
||||
device.waitForIdle(TIMEOUT);
|
||||
device.pressEnter();
|
||||
device.waitForIdle(TIMEOUT);
|
||||
bots.directory.assertSnackbar(R.string.rename_error);
|
||||
bots.directory.assertDocumentsPresent(fileName1);
|
||||
bots.directory.assertDocumentsPresent(fileName2);
|
||||
bots.directory.assertDocumentsCount(4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,19 +18,14 @@ package com.android.documentsui;
|
||||
|
||||
import static com.android.documentsui.StubProvider.ROOT_0_ID;
|
||||
|
||||
import android.support.test.uiautomator.Configurator;
|
||||
import android.support.test.uiautomator.UiObject;
|
||||
import android.support.test.uiautomator.UiObjectNotFoundException;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.LargeTest;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
@LargeTest
|
||||
public class RootUiTest extends ActivityTest<FilesActivity> {
|
||||
public class RootsUiTest extends ActivityTest<FilesActivity> {
|
||||
|
||||
private static final String TAG = "RootUiTest";
|
||||
|
||||
public RootUiTest() {
|
||||
public RootsUiTest() {
|
||||
super(FilesActivity.class);
|
||||
}
|
||||
|
||||
@@ -38,14 +33,14 @@ public class RootUiTest extends ActivityTest<FilesActivity> {
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
initTestFiles();
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
}
|
||||
|
||||
public void testRootTapped_GoToRootFromChildDir() throws Exception {
|
||||
bot.openDocument(dirName1);
|
||||
bot.assertWindowTitle(dirName1);
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bot.assertWindowTitle(ROOT_0_ID);
|
||||
bots.directory.openDocument(dirName1);
|
||||
bots.main.assertWindowTitle(dirName1);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
bots.main.assertWindowTitle(ROOT_0_ID);
|
||||
assertDefaultContentOfTestDir0();
|
||||
}
|
||||
}
|
||||
@@ -24,61 +24,59 @@ import android.test.suitebuilder.annotation.LargeTest;
|
||||
@LargeTest
|
||||
public class SearchViewUiTest extends ActivityTest<FilesActivity> {
|
||||
|
||||
private static final String TAG = "SearchViewUiTest";
|
||||
|
||||
public SearchViewUiTest() {
|
||||
super(FilesActivity.class);
|
||||
}
|
||||
|
||||
public void testSearchView_ExpandsOnClick() throws Exception {
|
||||
bot.openSearchView();
|
||||
bot.assertSearchTextFiledAndIcon(true, false);
|
||||
bots.main.openSearchView();
|
||||
bots.main.assertSearchTextFiledAndIcon(true, false);
|
||||
}
|
||||
|
||||
public void testSearchView_CollapsesOnBack() throws Exception {
|
||||
bot.openSearchView();
|
||||
bots.main.openSearchView();
|
||||
|
||||
device.pressBack();
|
||||
|
||||
bot.assertSearchTextFiledAndIcon(false, true);
|
||||
bots.main.assertSearchTextFiledAndIcon(false, true);
|
||||
}
|
||||
|
||||
public void testSearchView_ClearsTextOnBack() throws Exception {
|
||||
String query = "file2";
|
||||
bot.openSearchView();
|
||||
bot.setSearchQuery(query);
|
||||
bots.main.openSearchView();
|
||||
bots.main.setSearchQuery(query);
|
||||
|
||||
device.pressBack();
|
||||
|
||||
bot.assertSearchTextFiledAndIcon(false, true);
|
||||
bots.main.assertSearchTextFiledAndIcon(false, true);
|
||||
}
|
||||
|
||||
public void testSearch_ResultsFound() throws Exception {
|
||||
initTestFiles();
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
assertDefaultContentOfTestDir0();
|
||||
|
||||
String query = "file1";
|
||||
bot.openSearchView();
|
||||
bot.setSearchQuery(query);
|
||||
bot.assertSearchTextField(true, query);
|
||||
bots.main.openSearchView();
|
||||
bots.main.setSearchQuery(query);
|
||||
bots.main.assertSearchTextField(true, query);
|
||||
|
||||
device.pressEnter();
|
||||
|
||||
bot.assertDocumentsCountOnList(true, 2);
|
||||
bot.assertHasDocuments(fileName1, fileName2);
|
||||
bots.directory.assertDocumentsCountOnList(true, 2);
|
||||
bots.directory.assertDocumentsPresent(fileName1, fileName2);
|
||||
|
||||
bot.assertSearchTextField(false, query);
|
||||
bots.main.assertSearchTextField(false, query);
|
||||
}
|
||||
|
||||
public void testSearchResultsFound_ClearsOnBack() throws Exception {
|
||||
initTestFiles();
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
assertDefaultContentOfTestDir0();
|
||||
|
||||
String query = fileName1;
|
||||
bot.openSearchView();
|
||||
bot.setSearchQuery(query);
|
||||
bots.main.openSearchView();
|
||||
bots.main.setSearchQuery(query);
|
||||
|
||||
device.pressEnter();
|
||||
device.pressBack();
|
||||
@@ -88,32 +86,32 @@ public class SearchViewUiTest extends ActivityTest<FilesActivity> {
|
||||
|
||||
public void testSearch_NoResults() throws Exception {
|
||||
initTestFiles();
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
assertDefaultContentOfTestDir0();
|
||||
|
||||
String query = "chocolate";
|
||||
bot.openSearchView();
|
||||
bot.setSearchQuery(query);
|
||||
bots.main.openSearchView();
|
||||
bots.main.setSearchQuery(query);
|
||||
|
||||
device.pressEnter();
|
||||
|
||||
bot.assertDocumentsCountOnList(false, 0);
|
||||
bots.directory.assertDocumentsCountOnList(false, 0);
|
||||
|
||||
device.waitForIdle();
|
||||
String msg = String.valueOf(context.getString(R.string.no_results));
|
||||
bot.assertMessageTextView(String.format(msg, "TEST_ROOT_0"));
|
||||
bots.directory.assertMessageTextView(String.format(msg, "TEST_ROOT_0"));
|
||||
|
||||
bot.assertSearchTextField(false, query);
|
||||
bots.main.assertSearchTextField(false, query);
|
||||
}
|
||||
|
||||
public void testSearchNoResults_ClearsOnBack() throws Exception {
|
||||
initTestFiles();
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
assertDefaultContentOfTestDir0();
|
||||
|
||||
String query = "chocolate";
|
||||
bot.openSearchView();
|
||||
bot.setSearchQuery(query);
|
||||
bots.main.openSearchView();
|
||||
bots.main.setSearchQuery(query);
|
||||
|
||||
device.pressEnter();
|
||||
device.pressBack();
|
||||
@@ -124,30 +122,30 @@ public class SearchViewUiTest extends ActivityTest<FilesActivity> {
|
||||
|
||||
public void testSearchResultsFound_ClearsOnDirectoryChange() throws Exception {
|
||||
initTestFiles();
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
assertDefaultContentOfTestDir0();
|
||||
|
||||
String query = fileName1;
|
||||
bot.openSearchView();
|
||||
bot.setSearchQuery(query);
|
||||
bots.main.openSearchView();
|
||||
bots.main.setSearchQuery(query);
|
||||
|
||||
device.pressEnter();
|
||||
|
||||
bot.openRoot(ROOT_1_ID);
|
||||
bots.roots.openRoot(ROOT_1_ID);
|
||||
assertDefaultContentOfTestDir1();
|
||||
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
assertDefaultContentOfTestDir0();
|
||||
}
|
||||
|
||||
public void testSearchIconVisible_RootWithSearchSupport() throws Exception {
|
||||
bot.openRoot(ROOT_0_ID);
|
||||
bot.assertSearchTextFiledAndIcon(false, true);
|
||||
bots.roots.openRoot(ROOT_0_ID);
|
||||
bots.main.assertSearchTextFiledAndIcon(false, true);
|
||||
}
|
||||
|
||||
public void testSearchIconHidden_RootNoSearchSupport() throws Exception {
|
||||
bot.openRoot(ROOT_1_ID);
|
||||
bot.assertSearchTextFiledAndIcon(false, false);
|
||||
bots.roots.openRoot(ROOT_1_ID);
|
||||
bots.main.assertSearchTextFiledAndIcon(false, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,432 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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 com.android.documentsui;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.BySelector;
|
||||
import android.support.test.uiautomator.Configurator;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.UiObjectNotFoundException;
|
||||
import android.support.test.uiautomator.UiScrollable;
|
||||
import android.support.test.uiautomator.UiSelector;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A test helper class that provides support for controlling DocumentsUI activities
|
||||
* programmatically, and making assertions against the state of the UI.
|
||||
*/
|
||||
class UiBot {
|
||||
public static final String TARGET_PKG = "com.android.documentsui";
|
||||
|
||||
private static final String TAG = "UiBot";
|
||||
private static final String LAUNCHER_PKG = "com.android.launcher";
|
||||
|
||||
private static final BySelector SNACK_DELETE =
|
||||
By.desc(Pattern.compile("^Deleting [0-9]+ file.+"));
|
||||
|
||||
private UiDevice mDevice;
|
||||
private Context mContext;
|
||||
private int mTimeout;
|
||||
|
||||
public UiBot(UiDevice device, Context context, int timeout) {
|
||||
mDevice = device;
|
||||
mContext = context;
|
||||
mTimeout = timeout;
|
||||
}
|
||||
|
||||
UiObject findRoot(String label) throws UiObjectNotFoundException {
|
||||
final UiSelector rootsList = new UiSelector().resourceId(
|
||||
"com.android.documentsui:id/container_roots").childSelector(
|
||||
new UiSelector().resourceId("com.android.documentsui:id/roots_list"));
|
||||
|
||||
// We might need to expand drawer if not visible
|
||||
if (!new UiObject(rootsList).waitForExists(mTimeout)) {
|
||||
Log.d(TAG, "Failed to find roots list; trying to expand");
|
||||
final UiSelector hamburger = new UiSelector().resourceId(
|
||||
"com.android.documentsui:id/toolbar").childSelector(
|
||||
new UiSelector().className("android.widget.ImageButton").clickable(true));
|
||||
new UiObject(hamburger).click();
|
||||
}
|
||||
|
||||
// Wait for the first list item to appear
|
||||
new UiObject(rootsList.childSelector(new UiSelector())).waitForExists(mTimeout);
|
||||
|
||||
// Now scroll around to find our item
|
||||
new UiScrollable(rootsList).scrollIntoView(new UiSelector().text(label));
|
||||
return new UiObject(rootsList.childSelector(new UiSelector().text(label)));
|
||||
}
|
||||
|
||||
void openRoot(String label) throws UiObjectNotFoundException {
|
||||
findRoot(label).click();
|
||||
mDevice.waitForIdle();
|
||||
}
|
||||
|
||||
void assertWindowTitle(String expected) {
|
||||
// Turns out the title field on a window does not have
|
||||
// an id associated with it at runtime (which confuses the hell out of me)
|
||||
// In code we address this via "android.R.id.title".
|
||||
UiObject2 o = find(By.text(expected));
|
||||
// It's a bit of a conceit that we then *assert* that the title
|
||||
// is the value that we used to identify the UiObject2.
|
||||
// If the preceeding lookup fails, this'll choke with an NPE.
|
||||
// But given the issue described in the comment above, we're
|
||||
// going to do it anyway. Because we shouldn't be looking up
|
||||
// the uiobject by it's expected content :|
|
||||
assertEquals(expected, o.getText());
|
||||
}
|
||||
|
||||
void assertHasRoots(String... labels) throws UiObjectNotFoundException {
|
||||
List<String> missing = new ArrayList<>();
|
||||
for (String label : labels) {
|
||||
if (!findRoot(label).exists()) {
|
||||
missing.add(label);
|
||||
}
|
||||
}
|
||||
if (!missing.isEmpty()) {
|
||||
Assert.fail(
|
||||
"Expected roots " + Arrays.asList(labels) + ", but missing " + missing);
|
||||
}
|
||||
}
|
||||
|
||||
void assertMenuEnabled(int id, boolean enabled) {
|
||||
UiObject2 menu= findMenuWithName(mContext.getString(id));
|
||||
assertNotNull(menu);
|
||||
assertEquals(enabled, menu.isEnabled());
|
||||
}
|
||||
|
||||
void assertDocumentsCount(int count) throws UiObjectNotFoundException {
|
||||
UiObject docsList = findDocumentsList();
|
||||
assertEquals(count, docsList.getChildCount());
|
||||
}
|
||||
|
||||
void assertDocumentsCount(String dir, int count) throws UiObjectNotFoundException {
|
||||
openRoot(dir);
|
||||
UiObject docsList = findDocumentsList();
|
||||
assertEquals(count, docsList.getChildCount());
|
||||
}
|
||||
|
||||
void assertSearchTextField(boolean isFocused, String query)
|
||||
throws UiObjectNotFoundException {
|
||||
UiObject textField = findSearchViewTextField();
|
||||
UiObject searchIcon = findSearchViewIcon();
|
||||
|
||||
assertFalse(searchIcon.exists());
|
||||
assertTrue(textField.exists());
|
||||
assertEquals(isFocused, textField.isFocused());
|
||||
if(query != null) {
|
||||
assertEquals(query, textField.getText());
|
||||
}
|
||||
}
|
||||
|
||||
void assertSearchTextFiledAndIcon(boolean searchTextFieldExists, boolean searchIconExists) {
|
||||
assertEquals(searchTextFieldExists, findSearchViewTextField().exists());
|
||||
assertEquals(searchIconExists, findSearchViewIcon().exists());
|
||||
}
|
||||
|
||||
void assertHasDocuments(String... labels) throws UiObjectNotFoundException {
|
||||
List<String> missing = new ArrayList<>();
|
||||
for (String label : labels) {
|
||||
if (!findDocument(label).exists()) {
|
||||
missing.add(label);
|
||||
}
|
||||
}
|
||||
if (!missing.isEmpty()) {
|
||||
Assert.fail(
|
||||
"Expected documents " + Arrays.asList(labels) + ", but missing " + missing);
|
||||
}
|
||||
}
|
||||
|
||||
void assertDocument(String name, boolean exists) throws UiObjectNotFoundException {
|
||||
UiObject doc = findDocument(name);
|
||||
assertEquals(exists, doc.exists());
|
||||
}
|
||||
|
||||
void assertDocumentsCountOnList(boolean exists, int count) throws UiObjectNotFoundException {
|
||||
UiObject docsList = findDocumentsList();
|
||||
assertEquals(exists, docsList.exists());
|
||||
if(docsList.exists()) {
|
||||
assertEquals(count, docsList.getChildCount());
|
||||
}
|
||||
}
|
||||
|
||||
void assertMessageTextView(String message) throws UiObjectNotFoundException {
|
||||
UiObject messageTextView = findMessageTextView();
|
||||
assertTrue(messageTextView.exists());
|
||||
|
||||
String msg = String.valueOf(message);
|
||||
assertEquals(String.format(msg, "TEST_ROOT_0"), messageTextView.getText());
|
||||
|
||||
}
|
||||
void assertSnackbar(int id) {
|
||||
assertNotNull(getSnackbar(mContext.getString(id)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the specified view or one of its descendents has focus.
|
||||
*/
|
||||
void assertHasFocus(String resourceName) {
|
||||
UiObject2 candidate = mDevice.findObject(By.res(resourceName));
|
||||
assertNotNull("Expected " + resourceName + " to have focus, but it didn't.",
|
||||
candidate.findObject(By.focused(true)));
|
||||
}
|
||||
|
||||
void openDocument(String label) throws UiObjectNotFoundException {
|
||||
int toolType = Configurator.getInstance().getToolType();
|
||||
Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER);
|
||||
UiObject doc = findDocument(label);
|
||||
doc.click();
|
||||
Configurator.getInstance().setToolType(toolType);
|
||||
}
|
||||
|
||||
void clickDocument(String label) throws UiObjectNotFoundException {
|
||||
findDocument(label).click();
|
||||
}
|
||||
|
||||
void openSearchView() throws UiObjectNotFoundException {
|
||||
UiObject searchView = findSearchView();
|
||||
searchView.click();
|
||||
assertTrue(searchView.exists());
|
||||
}
|
||||
|
||||
void setSearchQuery(String query) throws UiObjectNotFoundException {
|
||||
UiObject searchView = findSearchView();
|
||||
assertTrue(searchView.exists());
|
||||
UiObject searchTextField = findSearchViewTextField();
|
||||
searchTextField.setText(query);
|
||||
assertSearchTextField(true, query);
|
||||
}
|
||||
|
||||
UiObject openOverflowMenu() throws UiObjectNotFoundException {
|
||||
UiObject obj = findMenuMoreOptions();
|
||||
obj.click();
|
||||
mDevice.waitForIdle(mTimeout);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void openDialog(int id) {
|
||||
UiObject2 menu= findMenuWithName(mContext.getString(id));
|
||||
assertNotNull(menu);
|
||||
assertEquals(true, menu.isEnabled());
|
||||
menu.click();
|
||||
}
|
||||
|
||||
void setDialogText(String text) throws UiObjectNotFoundException {
|
||||
findDialogEditText().setText(text);
|
||||
}
|
||||
|
||||
UiObject selectDocument(String label) throws UiObjectNotFoundException {
|
||||
UiObject doc = findDocument(label);
|
||||
doc.longClick();
|
||||
return doc;
|
||||
}
|
||||
|
||||
UiObject2 getSnackbar(String message) {
|
||||
return mDevice.wait(Until.findObject(By.text(message)), mTimeout);
|
||||
}
|
||||
|
||||
void waitForDeleteSnackbar() {
|
||||
mDevice.wait(Until.findObject(SNACK_DELETE), mTimeout);
|
||||
}
|
||||
|
||||
void waitForDeleteSnackbarGone() {
|
||||
// wait a little longer for snackbar to go away, as it disappears after a timeout.
|
||||
mDevice.wait(Until.gone(SNACK_DELETE), mTimeout * 2);
|
||||
}
|
||||
|
||||
void waitForDocument(String label) throws UiObjectNotFoundException {
|
||||
findDocument(label).waitForExists(mTimeout);
|
||||
}
|
||||
|
||||
void switchViewMode() {
|
||||
UiObject2 mode = menuGridMode();
|
||||
if (mode != null) {
|
||||
mode.click();
|
||||
} else {
|
||||
menuListMode().click();
|
||||
}
|
||||
}
|
||||
|
||||
UiObject2 menuGridMode() {
|
||||
// Note that we're using By.desc rather than By.res, because of b/25285770
|
||||
return find(By.desc("Grid view"));
|
||||
}
|
||||
|
||||
UiObject2 menuListMode() {
|
||||
// Note that we're using By.desc rather than By.res, because of b/25285770
|
||||
return find(By.desc("List view"));
|
||||
}
|
||||
|
||||
UiObject2 menuDelete() {
|
||||
return find(By.res("com.android.documentsui:id/menu_delete"));
|
||||
}
|
||||
|
||||
UiObject2 menuShare() {
|
||||
return find(By.res("com.android.documentsui:id/menu_share"));
|
||||
}
|
||||
|
||||
private UiObject2 find(BySelector selector) {
|
||||
mDevice.wait(Until.findObject(selector), mTimeout);
|
||||
return mDevice.findObject(selector);
|
||||
}
|
||||
|
||||
private UiObject findObject(String resourceId) {
|
||||
final UiSelector object = new UiSelector().resourceId(resourceId);
|
||||
return mDevice.findObject(object);
|
||||
}
|
||||
|
||||
private UiObject findObject(String parentResourceId, String childResourceId) {
|
||||
final UiSelector selector = new UiSelector()
|
||||
.resourceId(parentResourceId)
|
||||
.childSelector(new UiSelector().resourceId(childResourceId));
|
||||
return mDevice.findObject(selector);
|
||||
}
|
||||
|
||||
UiObject findDocument(String label) throws UiObjectNotFoundException {
|
||||
final UiSelector docList = new UiSelector().resourceId(
|
||||
"com.android.documentsui:id/container_directory").childSelector(
|
||||
new UiSelector().resourceId("com.android.documentsui:id/dir_list"));
|
||||
|
||||
// Wait for the first list item to appear
|
||||
new UiObject(docList.childSelector(new UiSelector())).waitForExists(mTimeout);
|
||||
|
||||
// new UiScrollable(docList).scrollIntoView(new UiSelector().text(label));
|
||||
return mDevice.findObject(docList.childSelector(new UiSelector().text(label)));
|
||||
}
|
||||
|
||||
boolean hasDocuments(String... labels) throws UiObjectNotFoundException {
|
||||
for (String label : labels) {
|
||||
if (!findDocument(label).exists()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
UiObject findDocumentsList() {
|
||||
return findObject(
|
||||
"com.android.documentsui:id/container_directory",
|
||||
"com.android.documentsui:id/dir_list");
|
||||
}
|
||||
|
||||
UiObject findSearchView() {
|
||||
return findObject("com.android.documentsui:id/menu_search");
|
||||
}
|
||||
|
||||
UiObject findSearchViewTextField() {
|
||||
return findObject("com.android.documentsui:id/menu_search", "android:id/search_src_text");
|
||||
}
|
||||
|
||||
UiObject findSearchViewIcon() {
|
||||
return findObject("com.android.documentsui:id/menu_search", "android:id/search_button");
|
||||
}
|
||||
|
||||
UiObject findMessageTextView() {
|
||||
return findObject(
|
||||
"com.android.documentsui:id/container_directory",
|
||||
"com.android.documentsui:id/message");
|
||||
}
|
||||
|
||||
UiObject findActionModeBar() {
|
||||
return findObject("android:id/action_mode_bar");
|
||||
}
|
||||
|
||||
UiObject findDialogEditText() {
|
||||
return findObject("android:id/content", "android:id/text1");
|
||||
}
|
||||
|
||||
UiObject findRenameDialogOkButton() {
|
||||
return findObject("android:id/content", "android:id/button1");
|
||||
}
|
||||
|
||||
UiObject findRenameDialogCancelButton() {
|
||||
return findObject("android:id/content", "android:id/button2");
|
||||
}
|
||||
|
||||
UiObject findMenuLabelWithName(String label) {
|
||||
UiSelector selector = new UiSelector().text(label);
|
||||
return mDevice.findObject(selector);
|
||||
}
|
||||
|
||||
UiObject2 findMenuWithName(String label) {
|
||||
List<UiObject2> menuItems = mDevice.findObjects(By.clazz("android.widget.LinearLayout"));
|
||||
Iterator<UiObject2> it = menuItems.iterator();
|
||||
|
||||
UiObject2 menuItem = null;
|
||||
while(it.hasNext()) {
|
||||
menuItem = it.next();
|
||||
UiObject2 text = menuItem.findObject(By.text(label));
|
||||
if(text != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
UiObject findMenuMoreOptions() {
|
||||
UiSelector selector = new UiSelector().className("android.widget.ImageButton")
|
||||
.descriptionContains("More options");
|
||||
//TODO: use the system string ? android.R.string.action_menu_overflow_description
|
||||
return mDevice.findObject(selector);
|
||||
}
|
||||
|
||||
// Indirect way to detect the keyboard.
|
||||
boolean isKeyboardPresent() {
|
||||
InputMethodManager inputManager = (InputMethodManager) mContext
|
||||
.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
return inputManager.isAcceptingText();
|
||||
}
|
||||
|
||||
void dismissKeyboardIfPresent() {
|
||||
if(isKeyboardPresent()) {
|
||||
mDevice.pressBack();
|
||||
}
|
||||
}
|
||||
|
||||
void revealLauncher() {
|
||||
mDevice.pressHome();
|
||||
mDevice.wait(Until.hasObject(By.pkg(LAUNCHER_PKG).depth(0)), mTimeout);
|
||||
}
|
||||
|
||||
void revealApp() {
|
||||
mDevice.wait(Until.hasObject(By.pkg(TARGET_PKG).depth(0)), mTimeout);
|
||||
mDevice.waitForIdle();
|
||||
}
|
||||
|
||||
void pressKey(int keyCode) {
|
||||
mDevice.pressKeyCode(keyCode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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 com.android.documentsui.bots;
|
||||
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.BySelector;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.UiSelector;
|
||||
import android.support.test.uiautomator.Until;
|
||||
|
||||
/**
|
||||
* A test helper class that provides support for controlling directory list
|
||||
* and making assertions against the state of it.
|
||||
*/
|
||||
abstract class BaseBot {
|
||||
final UiDevice mDevice;
|
||||
final Context mContext;
|
||||
final int mTimeout;
|
||||
|
||||
BaseBot(UiDevice device, Context context, int timeout) {
|
||||
mDevice = device;
|
||||
mContext = context;
|
||||
mTimeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the specified view or one of its descendents has focus.
|
||||
*/
|
||||
protected void assertHasFocus(String resourceName) {
|
||||
UiObject2 candidate = mDevice.findObject(By.res(resourceName));
|
||||
assertNotNull("Expected " + resourceName + " to have focus, but it didn't.",
|
||||
candidate.findObject(By.focused(true)));
|
||||
}
|
||||
|
||||
protected UiObject2 find(BySelector selector) {
|
||||
mDevice.wait(Until.findObject(selector), mTimeout);
|
||||
return mDevice.findObject(selector);
|
||||
}
|
||||
|
||||
protected UiObject findObject(String resourceId) {
|
||||
final UiSelector object = new UiSelector().resourceId(resourceId);
|
||||
return mDevice.findObject(object);
|
||||
}
|
||||
|
||||
protected UiObject findObject(String parentResourceId, String childResourceId) {
|
||||
final UiSelector selector = new UiSelector()
|
||||
.resourceId(parentResourceId)
|
||||
.childSelector(new UiSelector().resourceId(childResourceId));
|
||||
return mDevice.findObject(selector);
|
||||
}
|
||||
|
||||
protected void waitForIdle() {
|
||||
mDevice.waitForIdle(mTimeout);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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 com.android.documentsui.bots;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.BySelector;
|
||||
import android.support.test.uiautomator.Configurator;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.UiObjectNotFoundException;
|
||||
import android.support.test.uiautomator.UiSelector;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A test helper class that provides support for controlling directory list
|
||||
* and making assertions against the state of it.
|
||||
*/
|
||||
public class DirectoryListBot extends BaseBot {
|
||||
private static final String DIR_LIST_ID = "com.android.documentsui:id/dir_list";
|
||||
|
||||
private static final BySelector SNACK_DELETE =
|
||||
By.desc(Pattern.compile("^Deleting [0-9]+ file.+"));
|
||||
|
||||
public DirectoryListBot(UiDevice device, Context context, int timeout) {
|
||||
super(device, context, timeout);
|
||||
}
|
||||
|
||||
public void assertDocumentsCount(int count) throws UiObjectNotFoundException {
|
||||
UiObject docsList = findDocumentsList();
|
||||
assertEquals(count, docsList.getChildCount());
|
||||
}
|
||||
|
||||
public void assertDocumentsPresent(String... labels) throws UiObjectNotFoundException {
|
||||
List<String> absent = new ArrayList<>();
|
||||
for (String label : labels) {
|
||||
if (!findDocument(label).exists()) {
|
||||
absent.add(label);
|
||||
}
|
||||
}
|
||||
if (!absent.isEmpty()) {
|
||||
Assert.fail("Expected documents " + Arrays.asList(labels)
|
||||
+ ", but missing " + absent);
|
||||
}
|
||||
}
|
||||
|
||||
public void assertDocumentsAbsent(String... labels) throws UiObjectNotFoundException {
|
||||
List<String> found = new ArrayList<>();
|
||||
for (String label : labels) {
|
||||
if (findDocument(label).exists()) {
|
||||
found.add(label);
|
||||
}
|
||||
}
|
||||
if (!found.isEmpty()) {
|
||||
Assert.fail("Expected documents not present" + Arrays.asList(labels)
|
||||
+ ", but present " + found);
|
||||
}
|
||||
}
|
||||
|
||||
public void assertDocumentsCountOnList(boolean exists, int count) throws UiObjectNotFoundException {
|
||||
UiObject docsList = findDocumentsList();
|
||||
assertEquals(exists, docsList.exists());
|
||||
if(docsList.exists()) {
|
||||
assertEquals(count, docsList.getChildCount());
|
||||
}
|
||||
}
|
||||
|
||||
public void assertMessageTextView(String message) throws UiObjectNotFoundException {
|
||||
UiObject messageTextView = findMessageTextView();
|
||||
assertTrue(messageTextView.exists());
|
||||
|
||||
String msg = String.valueOf(message);
|
||||
assertEquals(String.format(msg, "TEST_ROOT_0"), messageTextView.getText());
|
||||
|
||||
}
|
||||
|
||||
private UiObject findMessageTextView() {
|
||||
return findObject(
|
||||
"com.android.documentsui:id/container_directory",
|
||||
"com.android.documentsui:id/message");
|
||||
}
|
||||
|
||||
public void assertSnackbar(int id) {
|
||||
assertNotNull(getSnackbar(mContext.getString(id)));
|
||||
}
|
||||
|
||||
public void openDocument(String label) throws UiObjectNotFoundException {
|
||||
int toolType = Configurator.getInstance().getToolType();
|
||||
Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER);
|
||||
UiObject doc = findDocument(label);
|
||||
doc.click();
|
||||
Configurator.getInstance().setToolType(toolType);
|
||||
}
|
||||
|
||||
public void clickDocument(String label) throws UiObjectNotFoundException {
|
||||
findDocument(label).click();
|
||||
}
|
||||
|
||||
public UiObject selectDocument(String label) throws UiObjectNotFoundException {
|
||||
UiObject doc = findDocument(label);
|
||||
doc.longClick();
|
||||
return doc;
|
||||
}
|
||||
|
||||
public UiObject2 getSnackbar(String message) {
|
||||
return mDevice.wait(Until.findObject(By.text(message)), mTimeout);
|
||||
}
|
||||
|
||||
public void waitForDeleteSnackbar() {
|
||||
mDevice.wait(Until.findObject(SNACK_DELETE), mTimeout);
|
||||
}
|
||||
|
||||
public void waitForDeleteSnackbarGone() {
|
||||
// wait a little longer for snackbar to go away, as it disappears after a timeout.
|
||||
mDevice.wait(Until.gone(SNACK_DELETE), mTimeout * 2);
|
||||
}
|
||||
|
||||
public void waitForDocument(String label) throws UiObjectNotFoundException {
|
||||
findDocument(label).waitForExists(mTimeout);
|
||||
}
|
||||
|
||||
public UiObject findDocument(String label) throws UiObjectNotFoundException {
|
||||
final UiSelector docList = new UiSelector().resourceId(
|
||||
"com.android.documentsui:id/container_directory").childSelector(
|
||||
new UiSelector().resourceId(DIR_LIST_ID));
|
||||
|
||||
// Wait for the first list item to appear
|
||||
new UiObject(docList.childSelector(new UiSelector())).waitForExists(mTimeout);
|
||||
|
||||
// new UiScrollable(docList).scrollIntoView(new UiSelector().text(label));
|
||||
return mDevice.findObject(docList.childSelector(new UiSelector().text(label)));
|
||||
}
|
||||
|
||||
public boolean hasDocuments(String... labels) throws UiObjectNotFoundException {
|
||||
for (String label : labels) {
|
||||
if (!findDocument(label).exists()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private UiObject findDocumentsList() {
|
||||
return findObject(
|
||||
"com.android.documentsui:id/container_directory",
|
||||
DIR_LIST_ID);
|
||||
}
|
||||
|
||||
public void assertHasFocus() {
|
||||
assertHasFocus(DIR_LIST_ID);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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 com.android.documentsui.bots;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
/**
|
||||
* A test helper class that provides support for keyboard manipulation.
|
||||
*/
|
||||
public class KeyboardBot extends BaseBot {
|
||||
|
||||
public KeyboardBot(UiDevice device, Context context, int timeout) {
|
||||
super(device, context, timeout);
|
||||
}
|
||||
|
||||
public void dismissKeyboardIfPresent() {
|
||||
if(isKeyboardPresent()) {
|
||||
mDevice.pressBack();
|
||||
}
|
||||
}
|
||||
|
||||
// Indirect way to detect the keyboard.
|
||||
private boolean isKeyboardPresent() {
|
||||
InputMethodManager inputManager = (InputMethodManager) mContext
|
||||
.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
return inputManager.isAcceptingText();
|
||||
}
|
||||
|
||||
public void pressEnter() {
|
||||
waitForIdle();
|
||||
mDevice.pressEnter();
|
||||
waitForIdle();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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 com.android.documentsui.bots;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject;
|
||||
import android.support.test.uiautomator.UiObjectNotFoundException;
|
||||
import android.support.test.uiautomator.UiScrollable;
|
||||
import android.support.test.uiautomator.UiSelector;
|
||||
import android.util.Log;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A test helper class that provides support for controlling and asserting against
|
||||
* the roots list drawer.
|
||||
*/
|
||||
public class RootsListBot extends BaseBot {
|
||||
private static final String ROOTS_LIST_ID = "com.android.documentsui:id/roots_list";
|
||||
private static final String TAG = "RootsListBot";
|
||||
|
||||
public RootsListBot(UiDevice device, Context context, int timeout) {
|
||||
super(device, context, timeout);
|
||||
}
|
||||
|
||||
private UiObject findRoot(String label) throws UiObjectNotFoundException {
|
||||
final UiSelector rootsList = new UiSelector().resourceId(
|
||||
"com.android.documentsui:id/container_roots").childSelector(
|
||||
new UiSelector().resourceId(ROOTS_LIST_ID));
|
||||
|
||||
// We might need to expand drawer if not visible
|
||||
if (!new UiObject(rootsList).waitForExists(mTimeout)) {
|
||||
Log.d(TAG, "Failed to find roots list; trying to expand");
|
||||
final UiSelector hamburger = new UiSelector().resourceId(
|
||||
"com.android.documentsui:id/toolbar").childSelector(
|
||||
new UiSelector().className("android.widget.ImageButton").clickable(true));
|
||||
new UiObject(hamburger).click();
|
||||
}
|
||||
|
||||
// Wait for the first list item to appear
|
||||
new UiObject(rootsList.childSelector(new UiSelector())).waitForExists(mTimeout);
|
||||
|
||||
// Now scroll around to find our item
|
||||
new UiScrollable(rootsList).scrollIntoView(new UiSelector().text(label));
|
||||
return new UiObject(rootsList.childSelector(new UiSelector().text(label)));
|
||||
}
|
||||
|
||||
public void openRoot(String label) throws UiObjectNotFoundException {
|
||||
findRoot(label).click();
|
||||
mDevice.waitForIdle();
|
||||
}
|
||||
|
||||
public void assertHasRoots(String... labels) throws UiObjectNotFoundException {
|
||||
List<String> missing = new ArrayList<>();
|
||||
for (String label : labels) {
|
||||
if (!findRoot(label).exists()) {
|
||||
missing.add(label);
|
||||
}
|
||||
}
|
||||
if (!missing.isEmpty()) {
|
||||
Assert.fail(
|
||||
"Expected roots " + Arrays.asList(labels) + ", but missing " + missing);
|
||||
}
|
||||
}
|
||||
|
||||
public void assertHasFocus() {
|
||||
assertHasFocus(ROOTS_LIST_ID);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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 com.android.documentsui.bots;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.UiObjectNotFoundException;
|
||||
import android.support.test.uiautomator.UiSelector;
|
||||
import android.support.test.uiautomator.Until;
|
||||
|
||||
import com.android.documentsui.R;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A test helper class that provides support for controlling DocumentsUI activities
|
||||
* programmatically, and making assertions against the state of the UI.
|
||||
*
|
||||
* <p>Support for working directly with Roots and Directory view can be found
|
||||
* in the respective bots.
|
||||
*/
|
||||
public class UiBot extends BaseBot {
|
||||
public static final String TARGET_PKG = "com.android.documentsui";
|
||||
private static final String LAUNCHER_PKG = "com.android.launcher";
|
||||
|
||||
public UiBot(UiDevice device, Context context, int timeout) {
|
||||
super(device, context, timeout);
|
||||
}
|
||||
|
||||
public void assertWindowTitle(String expected) {
|
||||
// Turns out the title field on a window does not have
|
||||
// an id associated with it at runtime (which confuses the hell out of me)
|
||||
// In code we address this via "android.R.id.title".
|
||||
UiObject2 o = find(By.text(expected));
|
||||
// It's a bit of a conceit that we then *assert* that the title
|
||||
// is the value that we used to identify the UiObject2.
|
||||
// If the preceeding lookup fails, this'll choke with an NPE.
|
||||
// But given the issue described in the comment above, we're
|
||||
// going to do it anyway. Because we shouldn't be looking up
|
||||
// the uiobject by it's expected content :|
|
||||
assertEquals(expected, o.getText());
|
||||
}
|
||||
|
||||
public void assertMenuEnabled(int id, boolean enabled) {
|
||||
UiObject2 menu= findMenuWithName(mContext.getString(id));
|
||||
assertNotNull(menu);
|
||||
assertEquals(enabled, menu.isEnabled());
|
||||
}
|
||||
|
||||
public void assertSearchTextField(boolean isFocused, String query)
|
||||
throws UiObjectNotFoundException {
|
||||
UiObject textField = findSearchViewTextField();
|
||||
UiObject searchIcon = findSearchViewIcon();
|
||||
|
||||
assertFalse(searchIcon.exists());
|
||||
assertTrue(textField.exists());
|
||||
assertEquals(isFocused, textField.isFocused());
|
||||
if(query != null) {
|
||||
assertEquals(query, textField.getText());
|
||||
}
|
||||
}
|
||||
|
||||
public void assertSearchTextFiledAndIcon(boolean searchTextFieldExists, boolean searchIconExists) {
|
||||
assertEquals(searchTextFieldExists, findSearchViewTextField().exists());
|
||||
assertEquals(searchIconExists, findSearchViewIcon().exists());
|
||||
}
|
||||
|
||||
public void openSearchView() throws UiObjectNotFoundException {
|
||||
UiObject searchView = findSearchView();
|
||||
searchView.click();
|
||||
assertTrue(searchView.exists());
|
||||
}
|
||||
|
||||
public void setSearchQuery(String query) throws UiObjectNotFoundException {
|
||||
UiObject searchView = findSearchView();
|
||||
assertTrue(searchView.exists());
|
||||
UiObject searchTextField = findSearchViewTextField();
|
||||
searchTextField.setText(query);
|
||||
assertSearchTextField(true, query);
|
||||
}
|
||||
|
||||
public UiObject openOverflowMenu() throws UiObjectNotFoundException {
|
||||
UiObject obj = findMenuMoreOptions();
|
||||
obj.click();
|
||||
mDevice.waitForIdle(mTimeout);
|
||||
return obj;
|
||||
}
|
||||
|
||||
public void setDialogText(String text) throws UiObjectNotFoundException {
|
||||
findDialogEditText().setText(text);
|
||||
}
|
||||
|
||||
void switchViewMode() {
|
||||
UiObject2 mode = menuGridMode();
|
||||
if (mode != null) {
|
||||
mode.click();
|
||||
} else {
|
||||
menuListMode().click();
|
||||
}
|
||||
}
|
||||
|
||||
UiObject2 menuGridMode() {
|
||||
// Note that we're using By.desc rather than By.res, because of b/25285770
|
||||
return find(By.desc("Grid view"));
|
||||
}
|
||||
|
||||
UiObject2 menuListMode() {
|
||||
// Note that we're using By.desc rather than By.res, because of b/25285770
|
||||
return find(By.desc("List view"));
|
||||
}
|
||||
|
||||
public UiObject2 menuDelete() {
|
||||
return find(By.res("com.android.documentsui:id/menu_delete"));
|
||||
}
|
||||
|
||||
public UiObject2 menuShare() {
|
||||
return find(By.res("com.android.documentsui:id/menu_share"));
|
||||
}
|
||||
|
||||
public UiObject2 menuRename() {
|
||||
return findMenuWithName(mContext.getString(R.string.menu_rename));
|
||||
}
|
||||
|
||||
public UiObject2 menuNewFolder() {
|
||||
return findMenuWithName(mContext.getString(R.string.menu_create_dir));
|
||||
}
|
||||
|
||||
UiObject findSearchView() {
|
||||
return findObject("com.android.documentsui:id/menu_search");
|
||||
}
|
||||
|
||||
UiObject findSearchViewTextField() {
|
||||
return findObject("com.android.documentsui:id/menu_search", "android:id/search_src_text");
|
||||
}
|
||||
|
||||
UiObject findSearchViewIcon() {
|
||||
return findObject("com.android.documentsui:id/menu_search", "android:id/search_button");
|
||||
}
|
||||
|
||||
UiObject findActionModeBar() {
|
||||
return findObject("android:id/action_mode_bar");
|
||||
}
|
||||
|
||||
public UiObject findDialogEditText() {
|
||||
return findObject("android:id/content", "android:id/text1");
|
||||
}
|
||||
|
||||
public UiObject findRenameDialogOkButton() {
|
||||
return findObject("android:id/content", "android:id/button1");
|
||||
}
|
||||
|
||||
public UiObject findRenameDialogCancelButton() {
|
||||
return findObject("android:id/content", "android:id/button2");
|
||||
}
|
||||
|
||||
UiObject findMenuLabelWithName(String label) {
|
||||
UiSelector selector = new UiSelector().text(label);
|
||||
return mDevice.findObject(selector);
|
||||
}
|
||||
|
||||
UiObject2 findMenuWithName(String label) {
|
||||
List<UiObject2> menuItems = mDevice.findObjects(By.clazz("android.widget.LinearLayout"));
|
||||
Iterator<UiObject2> it = menuItems.iterator();
|
||||
|
||||
UiObject2 menuItem = null;
|
||||
while(it.hasNext()) {
|
||||
menuItem = it.next();
|
||||
UiObject2 text = menuItem.findObject(By.text(label));
|
||||
if(text != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
UiObject findMenuMoreOptions() {
|
||||
UiSelector selector = new UiSelector().className("android.widget.ImageButton")
|
||||
.descriptionContains("More options");
|
||||
//TODO: use the system string ? android.R.string.action_menu_overflow_description
|
||||
return mDevice.findObject(selector);
|
||||
}
|
||||
|
||||
public void revealLauncher() {
|
||||
mDevice.pressHome();
|
||||
mDevice.wait(Until.hasObject(By.pkg(LAUNCHER_PKG).depth(0)), mTimeout);
|
||||
}
|
||||
|
||||
public void revealApp() {
|
||||
mDevice.wait(Until.hasObject(By.pkg(TARGET_PKG).depth(0)), mTimeout);
|
||||
mDevice.waitForIdle();
|
||||
}
|
||||
|
||||
public void pressKey(int keyCode) {
|
||||
mDevice.pressKeyCode(keyCode);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user