Loading tests/src/com/android/documentsui/SortDocumentUiTest.java 0 → 100644 +197 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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 android.net.Uri; import android.support.test.filters.LargeTest; import com.android.documentsui.sorting.SortDimension; import com.android.documentsui.sorting.SortModel; @LargeTest public class SortDocumentUiTest extends ActivityTest<FilesActivity> { private static final String DIR_1 = "folder_1"; private static final String DIR_2 = "dir_2"; private static final String FILE_1 = "file_1"; private static final String FILE_2 = "doc_2"; private static final String FILE_3 = "image_3"; private static final String[] FILES = { FILE_1, FILE_3, FILE_2 }; private static final String[] DIRS = { DIR_1, DIR_2 }; private static final String[] DIRS_IN_NAME_ASC = { DIR_2, DIR_1 }; private static final String[] DIRS_IN_NAME_DESC = reverse(DIRS_IN_NAME_ASC); private static final String[] FILES_IN_NAME_ASC = { FILE_2, FILE_1, FILE_3 }; private static final String[] FILES_IN_NAME_DESC = reverse(FILES_IN_NAME_ASC); private static final String[] FILES_IN_SIZE_ASC = { FILE_2, FILE_1, FILE_3 }; private static final String[] FILES_IN_SIZE_DESC = reverse(FILES_IN_SIZE_ASC); private static final String[] DIRS_IN_MODIFIED_DESC = reverse(DIRS); private static final String[] FILES_IN_MODIFIED_DESC = reverse(FILES); public SortDocumentUiTest() { super(FilesActivity.class); } @Override public void setUp() throws Exception { super.setUp(); bots.roots.closeDrawer(); } private void initFiles() throws Exception { initFiles(0); } /** * Initiate test files. It allows waiting between creations of files, so that we can assure * the modified date of each document is different. * @param sleep time to sleep in ms */ private void initFiles(long sleep) throws Exception { for (String file : FILES) { Uri uri = mDocsHelper.createDocument(rootDir0, "text/plain", file); mDocsHelper.writeDocument(uri, file.getBytes()); Thread.sleep(sleep); } for (String dir : DIRS) { mDocsHelper.createFolder(rootDir0, dir); Thread.sleep(sleep); } } public void testDefaultSortByNameAscending() throws Exception { initFiles(); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_NAME_ASC); } public void testSortByName_Descending_listMode() throws Exception { initFiles(); bots.main.switchToListMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_NAME_DESC, FILES_IN_NAME_DESC); } public void testSortBySize_Ascending_listMode() throws Exception { initFiles(); bots.main.switchToListMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_ASC); } public void testSortBySize_Descending_listMode() throws Exception { initFiles(); bots.main.switchToListMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_DESC); } public void testSortByModified_Ascending_listMode() throws Exception { initFiles(1000); bots.main.switchToListMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.assertOrder(DIRS, FILES); } public void testSortByModified_Descending_listMode() throws Exception { initFiles(1000); bots.main.switchToListMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_MODIFIED_DESC, FILES_IN_MODIFIED_DESC); } public void testSortByName_Descending_gridMode() throws Exception { initFiles(); bots.main.switchToGridMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_NAME_DESC, FILES_IN_NAME_DESC); } public void testSortBySize_Ascending_gridMode() throws Exception { initFiles(); bots.main.switchToGridMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_ASC); } public void testSortBySize_Descending_gridMode() throws Exception { initFiles(); bots.main.switchToGridMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_DESC); } public void testSortByModified_Ascending_gridMode() throws Exception { initFiles(1000); bots.main.switchToGridMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.assertOrder(DIRS, FILES); } public void testSortByModified_Descending_gridMode() throws Exception { initFiles(1000); bots.main.switchToGridMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_MODIFIED_DESC, FILES_IN_MODIFIED_DESC); } private static String[] reverse(String[] array) { String[] ret = new String[array.length]; for (int i = 0; i < array.length; ++i) { ret[ret.length - i - 1] = array[i]; } return ret; } } tests/src/com/android/documentsui/bots/DirectoryListBot.java +171 −8 Original line number Diff line number Diff line Loading @@ -16,13 +16,26 @@ package com.android.documentsui.bots; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA; import static android.support.test.espresso.matcher.ViewMatchers.withChild; import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withParent; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static com.android.documentsui.sorting.SortDimension.SORT_DIRECTION_ASCENDING; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertTrue; import static org.hamcrest.Matchers.allOf; import android.content.Context; import android.support.test.espresso.Espresso; import android.support.test.espresso.matcher.ViewMatchers; import android.graphics.Rect; import android.support.annotation.StringRes; import android.support.test.uiautomator.By; import android.support.test.uiautomator.BySelector; import android.support.test.uiautomator.Configurator; Loading @@ -32,15 +45,20 @@ 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.support.v7.widget.RecyclerView; import android.view.KeyEvent; import android.view.MotionEvent; import android.widget.RelativeLayout; import android.view.View; import com.android.documentsui.R; import com.android.documentsui.sorting.SortDimension; import com.android.documentsui.sorting.SortDimension.SortDirection; import com.android.documentsui.sorting.SortModel; import com.android.documentsui.sorting.SortModel.SortDimensionId; import junit.framework.Assert; import org.hamcrest.Matcher; import java.util.ArrayList; import java.util.Arrays; import java.util.List; Loading @@ -51,13 +69,21 @@ import java.util.regex.Pattern; * and making assertions against the state of it. */ public class DirectoryListBot extends Bots.BaseBot { private static final String DIR_CONTAINER_ID = "com.android.documentsui:id/container_directory"; 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.+")); private final SortModel mSortModel = SortModel.createModel(); private final DropdownSortBot mDropdownBot; private final HeaderSortBot mHeaderBot; public DirectoryListBot(UiDevice device, Context context, int timeout) { super(device, context, timeout); mDropdownBot = new DropdownSortBot(); mHeaderBot = new HeaderSortBot(); } public void assertDocumentsCount(int count) throws UiObjectNotFoundException { Loading Loading @@ -110,7 +136,7 @@ public class DirectoryListBot extends Bots.BaseBot { private UiObject findMessageTextView() { return findObject( "com.android.documentsui:id/container_directory", DIR_CONTAINER_ID, "com.android.documentsui:id/message"); } Loading Loading @@ -167,7 +193,7 @@ public class DirectoryListBot extends Bots.BaseBot { public UiObject findDocument(String label) throws UiObjectNotFoundException { final UiSelector docList = new UiSelector().resourceId( "com.android.documentsui:id/container_directory").childSelector( DIR_CONTAINER_ID).childSelector( new UiSelector().resourceId(DIR_LIST_ID)); // Wait for the first list item to appear Loading @@ -188,7 +214,7 @@ public class DirectoryListBot extends Bots.BaseBot { public void assertFirstDocumentHasFocus() throws UiObjectNotFoundException { final UiSelector docList = new UiSelector().resourceId( "com.android.documentsui:id/container_directory").childSelector( DIR_CONTAINER_ID).childSelector( new UiSelector().resourceId(DIR_LIST_ID)); // Wait for the first list item to appear Loading @@ -200,11 +226,148 @@ public class DirectoryListBot extends Bots.BaseBot { public UiObject findDocumentsList() { return findObject( "com.android.documentsui:id/container_directory", DIR_CONTAINER_ID, DIR_LIST_ID); } public void assertHasFocus() { assertHasFocus(DIR_LIST_ID); } public void sortBy(@SortDimensionId int id, @SortDirection int direction) { assert(direction != SortDimension.SORT_DIRECTION_NONE); final @StringRes int labelId = mSortModel.getDimensionById(id).getLabelId(); final String label = mContext.getString(labelId); final boolean result; if (Matchers.present(mDropdownBot.MATCHER)) { result = mDropdownBot.sortBy(label, direction); } else { result = mHeaderBot.sortBy(label, direction); } assertTrue("Sorting by id: " + id + " in direction: " + direction + " failed.", result); } public void assertOrder(String[] dirs, String[] files) throws UiObjectNotFoundException { for (int i = 0; i < dirs.length - 1; ++i) { assertOrder(dirs[i], dirs[i + 1]); } if (dirs.length > 0 && files.length > 0) { assertOrder(dirs[dirs.length - 1], files[0]); } for (int i = 0; i < files.length - 1; ++i) { assertOrder(files[i], files[i + 1]); } } private void assertOrder(String first, String second) throws UiObjectNotFoundException { final UiObject firstObj = findDocument(first); final UiObject secondObj = findDocument(second); final int layoutDirection = mContext.getResources().getConfiguration().getLayoutDirection(); final Rect firstBound = firstObj.getVisibleBounds(); final Rect secondBound = secondObj.getVisibleBounds(); if (layoutDirection == View.LAYOUT_DIRECTION_LTR) { assertTrue( "\"" + first + "\" is not located above or to the left of \"" + second + "\" in LTR", firstBound.bottom < secondBound.top || firstBound.right < secondBound.left); } else { assertTrue( "\"" + first + "\" is not located above or to the right of \"" + second + "\" in RTL", firstBound.bottom < secondBound.top || firstBound.left > secondBound.right); } } private static class DropdownSortBot { private static final Matcher<View> MATCHER = withId(R.id.dropdown_sort_widget); private static final Matcher<View> DROPDOWN_MATCHER = allOf( withId(R.id.sort_dimen_dropdown), withParent(MATCHER)); private static final Matcher<View> SORT_ARROW_MATCHER = allOf( withId(R.id.sort_arrow), withParent(MATCHER)); private boolean sortBy(String label, @SortDirection int direction) { onView(DROPDOWN_MATCHER).perform(click()); onView(withText(label)).perform(click()); if (direction != getDirection()) { onView(SORT_ARROW_MATCHER).perform(click()); } return Matchers.present(allOf( DROPDOWN_MATCHER, withText(label))) && getDirection() == direction; } private @SortDirection int getDirection() { final boolean ascending = Matchers.present( allOf( SORT_ARROW_MATCHER, withContentDescription(R.string.sort_direction_ascending))); if (ascending) { return SORT_DIRECTION_ASCENDING; } final boolean descending = Matchers.present( allOf( SORT_ARROW_MATCHER, withContentDescription(R.string.sort_direction_descending))); return descending ? SortDimension.SORT_DIRECTION_DESCENDING : SortDimension.SORT_DIRECTION_NONE; } } private static class HeaderSortBot { private static final Matcher<View> MATCHER = withId(R.id.table_header); private boolean sortBy(String label, @SortDirection int direction) { final Matcher<View> cellMatcher = allOf( withChild(withText(label)), isDescendantOfA(MATCHER)); onView(cellMatcher).perform(click()); final @SortDirection int viewDirection = getDirection(cellMatcher); if (viewDirection != direction) { onView(cellMatcher).perform(click()); } return getDirection(cellMatcher) == direction; } private @SortDirection int getDirection(Matcher<View> cellMatcher) { final boolean ascending = Matchers.present( allOf( withContentDescription(R.string.sort_direction_ascending), withParent(cellMatcher))); if (ascending) { return SORT_DIRECTION_ASCENDING; } final boolean descending = Matchers.present( allOf( withContentDescription(R.string.sort_direction_descending), withParent(cellMatcher))); return descending ? SortDimension.SORT_DIRECTION_DESCENDING : SortDimension.SORT_DIRECTION_NONE; } } } tests/src/com/android/documentsui/bots/Matchers.java +6 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import android.support.test.espresso.ViewInteraction; import android.view.View; import junit.framework.AssertionFailedError; import org.hamcrest.Matcher; /** Loading @@ -41,7 +43,10 @@ public final class Matchers { vi.check(matches(matcher)); vi.check(matches(isDisplayed())); return true; } catch (Exception e) { } // Catch AssertionFailedError because vi.check(matches(isDisplayed())) throws that if // assertion fails. catch (Exception|AssertionFailedError e) { return false; } } Loading tests/src/com/android/documentsui/bots/UiBot.java +11 −6 Original line number Diff line number Diff line Loading @@ -130,12 +130,17 @@ public class UiBot extends Bots.BaseBot { return !inFixedLayout(); } void switchViewMode() { UiObject2 mode = menuGridMode(); if (mode != null) { mode.click(); } else { menuListMode().click(); public void switchToListMode() { final UiObject2 listMode = menuListMode(); if (listMode != null) { listMode.click(); } } public void switchToGridMode() { final UiObject2 gridMode = menuGridMode(); if (gridMode != null) { gridMode.click(); } } Loading Loading
tests/src/com/android/documentsui/SortDocumentUiTest.java 0 → 100644 +197 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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 android.net.Uri; import android.support.test.filters.LargeTest; import com.android.documentsui.sorting.SortDimension; import com.android.documentsui.sorting.SortModel; @LargeTest public class SortDocumentUiTest extends ActivityTest<FilesActivity> { private static final String DIR_1 = "folder_1"; private static final String DIR_2 = "dir_2"; private static final String FILE_1 = "file_1"; private static final String FILE_2 = "doc_2"; private static final String FILE_3 = "image_3"; private static final String[] FILES = { FILE_1, FILE_3, FILE_2 }; private static final String[] DIRS = { DIR_1, DIR_2 }; private static final String[] DIRS_IN_NAME_ASC = { DIR_2, DIR_1 }; private static final String[] DIRS_IN_NAME_DESC = reverse(DIRS_IN_NAME_ASC); private static final String[] FILES_IN_NAME_ASC = { FILE_2, FILE_1, FILE_3 }; private static final String[] FILES_IN_NAME_DESC = reverse(FILES_IN_NAME_ASC); private static final String[] FILES_IN_SIZE_ASC = { FILE_2, FILE_1, FILE_3 }; private static final String[] FILES_IN_SIZE_DESC = reverse(FILES_IN_SIZE_ASC); private static final String[] DIRS_IN_MODIFIED_DESC = reverse(DIRS); private static final String[] FILES_IN_MODIFIED_DESC = reverse(FILES); public SortDocumentUiTest() { super(FilesActivity.class); } @Override public void setUp() throws Exception { super.setUp(); bots.roots.closeDrawer(); } private void initFiles() throws Exception { initFiles(0); } /** * Initiate test files. It allows waiting between creations of files, so that we can assure * the modified date of each document is different. * @param sleep time to sleep in ms */ private void initFiles(long sleep) throws Exception { for (String file : FILES) { Uri uri = mDocsHelper.createDocument(rootDir0, "text/plain", file); mDocsHelper.writeDocument(uri, file.getBytes()); Thread.sleep(sleep); } for (String dir : DIRS) { mDocsHelper.createFolder(rootDir0, dir); Thread.sleep(sleep); } } public void testDefaultSortByNameAscending() throws Exception { initFiles(); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_NAME_ASC); } public void testSortByName_Descending_listMode() throws Exception { initFiles(); bots.main.switchToListMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_NAME_DESC, FILES_IN_NAME_DESC); } public void testSortBySize_Ascending_listMode() throws Exception { initFiles(); bots.main.switchToListMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_ASC); } public void testSortBySize_Descending_listMode() throws Exception { initFiles(); bots.main.switchToListMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_DESC); } public void testSortByModified_Ascending_listMode() throws Exception { initFiles(1000); bots.main.switchToListMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.assertOrder(DIRS, FILES); } public void testSortByModified_Descending_listMode() throws Exception { initFiles(1000); bots.main.switchToListMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_MODIFIED_DESC, FILES_IN_MODIFIED_DESC); } public void testSortByName_Descending_gridMode() throws Exception { initFiles(); bots.main.switchToGridMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_NAME_DESC, FILES_IN_NAME_DESC); } public void testSortBySize_Ascending_gridMode() throws Exception { initFiles(); bots.main.switchToGridMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_ASC); } public void testSortBySize_Descending_gridMode() throws Exception { initFiles(); bots.main.switchToGridMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_DESC); } public void testSortByModified_Ascending_gridMode() throws Exception { initFiles(1000); bots.main.switchToGridMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.assertOrder(DIRS, FILES); } public void testSortByModified_Descending_gridMode() throws Exception { initFiles(1000); bots.main.switchToGridMode(); bots.directory.sortBy( SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_MODIFIED_DESC, FILES_IN_MODIFIED_DESC); } private static String[] reverse(String[] array) { String[] ret = new String[array.length]; for (int i = 0; i < array.length; ++i) { ret[ret.length - i - 1] = array[i]; } return ret; } }
tests/src/com/android/documentsui/bots/DirectoryListBot.java +171 −8 Original line number Diff line number Diff line Loading @@ -16,13 +16,26 @@ package com.android.documentsui.bots; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA; import static android.support.test.espresso.matcher.ViewMatchers.withChild; import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withParent; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static com.android.documentsui.sorting.SortDimension.SORT_DIRECTION_ASCENDING; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertTrue; import static org.hamcrest.Matchers.allOf; import android.content.Context; import android.support.test.espresso.Espresso; import android.support.test.espresso.matcher.ViewMatchers; import android.graphics.Rect; import android.support.annotation.StringRes; import android.support.test.uiautomator.By; import android.support.test.uiautomator.BySelector; import android.support.test.uiautomator.Configurator; Loading @@ -32,15 +45,20 @@ 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.support.v7.widget.RecyclerView; import android.view.KeyEvent; import android.view.MotionEvent; import android.widget.RelativeLayout; import android.view.View; import com.android.documentsui.R; import com.android.documentsui.sorting.SortDimension; import com.android.documentsui.sorting.SortDimension.SortDirection; import com.android.documentsui.sorting.SortModel; import com.android.documentsui.sorting.SortModel.SortDimensionId; import junit.framework.Assert; import org.hamcrest.Matcher; import java.util.ArrayList; import java.util.Arrays; import java.util.List; Loading @@ -51,13 +69,21 @@ import java.util.regex.Pattern; * and making assertions against the state of it. */ public class DirectoryListBot extends Bots.BaseBot { private static final String DIR_CONTAINER_ID = "com.android.documentsui:id/container_directory"; 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.+")); private final SortModel mSortModel = SortModel.createModel(); private final DropdownSortBot mDropdownBot; private final HeaderSortBot mHeaderBot; public DirectoryListBot(UiDevice device, Context context, int timeout) { super(device, context, timeout); mDropdownBot = new DropdownSortBot(); mHeaderBot = new HeaderSortBot(); } public void assertDocumentsCount(int count) throws UiObjectNotFoundException { Loading Loading @@ -110,7 +136,7 @@ public class DirectoryListBot extends Bots.BaseBot { private UiObject findMessageTextView() { return findObject( "com.android.documentsui:id/container_directory", DIR_CONTAINER_ID, "com.android.documentsui:id/message"); } Loading Loading @@ -167,7 +193,7 @@ public class DirectoryListBot extends Bots.BaseBot { public UiObject findDocument(String label) throws UiObjectNotFoundException { final UiSelector docList = new UiSelector().resourceId( "com.android.documentsui:id/container_directory").childSelector( DIR_CONTAINER_ID).childSelector( new UiSelector().resourceId(DIR_LIST_ID)); // Wait for the first list item to appear Loading @@ -188,7 +214,7 @@ public class DirectoryListBot extends Bots.BaseBot { public void assertFirstDocumentHasFocus() throws UiObjectNotFoundException { final UiSelector docList = new UiSelector().resourceId( "com.android.documentsui:id/container_directory").childSelector( DIR_CONTAINER_ID).childSelector( new UiSelector().resourceId(DIR_LIST_ID)); // Wait for the first list item to appear Loading @@ -200,11 +226,148 @@ public class DirectoryListBot extends Bots.BaseBot { public UiObject findDocumentsList() { return findObject( "com.android.documentsui:id/container_directory", DIR_CONTAINER_ID, DIR_LIST_ID); } public void assertHasFocus() { assertHasFocus(DIR_LIST_ID); } public void sortBy(@SortDimensionId int id, @SortDirection int direction) { assert(direction != SortDimension.SORT_DIRECTION_NONE); final @StringRes int labelId = mSortModel.getDimensionById(id).getLabelId(); final String label = mContext.getString(labelId); final boolean result; if (Matchers.present(mDropdownBot.MATCHER)) { result = mDropdownBot.sortBy(label, direction); } else { result = mHeaderBot.sortBy(label, direction); } assertTrue("Sorting by id: " + id + " in direction: " + direction + " failed.", result); } public void assertOrder(String[] dirs, String[] files) throws UiObjectNotFoundException { for (int i = 0; i < dirs.length - 1; ++i) { assertOrder(dirs[i], dirs[i + 1]); } if (dirs.length > 0 && files.length > 0) { assertOrder(dirs[dirs.length - 1], files[0]); } for (int i = 0; i < files.length - 1; ++i) { assertOrder(files[i], files[i + 1]); } } private void assertOrder(String first, String second) throws UiObjectNotFoundException { final UiObject firstObj = findDocument(first); final UiObject secondObj = findDocument(second); final int layoutDirection = mContext.getResources().getConfiguration().getLayoutDirection(); final Rect firstBound = firstObj.getVisibleBounds(); final Rect secondBound = secondObj.getVisibleBounds(); if (layoutDirection == View.LAYOUT_DIRECTION_LTR) { assertTrue( "\"" + first + "\" is not located above or to the left of \"" + second + "\" in LTR", firstBound.bottom < secondBound.top || firstBound.right < secondBound.left); } else { assertTrue( "\"" + first + "\" is not located above or to the right of \"" + second + "\" in RTL", firstBound.bottom < secondBound.top || firstBound.left > secondBound.right); } } private static class DropdownSortBot { private static final Matcher<View> MATCHER = withId(R.id.dropdown_sort_widget); private static final Matcher<View> DROPDOWN_MATCHER = allOf( withId(R.id.sort_dimen_dropdown), withParent(MATCHER)); private static final Matcher<View> SORT_ARROW_MATCHER = allOf( withId(R.id.sort_arrow), withParent(MATCHER)); private boolean sortBy(String label, @SortDirection int direction) { onView(DROPDOWN_MATCHER).perform(click()); onView(withText(label)).perform(click()); if (direction != getDirection()) { onView(SORT_ARROW_MATCHER).perform(click()); } return Matchers.present(allOf( DROPDOWN_MATCHER, withText(label))) && getDirection() == direction; } private @SortDirection int getDirection() { final boolean ascending = Matchers.present( allOf( SORT_ARROW_MATCHER, withContentDescription(R.string.sort_direction_ascending))); if (ascending) { return SORT_DIRECTION_ASCENDING; } final boolean descending = Matchers.present( allOf( SORT_ARROW_MATCHER, withContentDescription(R.string.sort_direction_descending))); return descending ? SortDimension.SORT_DIRECTION_DESCENDING : SortDimension.SORT_DIRECTION_NONE; } } private static class HeaderSortBot { private static final Matcher<View> MATCHER = withId(R.id.table_header); private boolean sortBy(String label, @SortDirection int direction) { final Matcher<View> cellMatcher = allOf( withChild(withText(label)), isDescendantOfA(MATCHER)); onView(cellMatcher).perform(click()); final @SortDirection int viewDirection = getDirection(cellMatcher); if (viewDirection != direction) { onView(cellMatcher).perform(click()); } return getDirection(cellMatcher) == direction; } private @SortDirection int getDirection(Matcher<View> cellMatcher) { final boolean ascending = Matchers.present( allOf( withContentDescription(R.string.sort_direction_ascending), withParent(cellMatcher))); if (ascending) { return SORT_DIRECTION_ASCENDING; } final boolean descending = Matchers.present( allOf( withContentDescription(R.string.sort_direction_descending), withParent(cellMatcher))); return descending ? SortDimension.SORT_DIRECTION_DESCENDING : SortDimension.SORT_DIRECTION_NONE; } } }
tests/src/com/android/documentsui/bots/Matchers.java +6 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import android.support.test.espresso.ViewInteraction; import android.view.View; import junit.framework.AssertionFailedError; import org.hamcrest.Matcher; /** Loading @@ -41,7 +43,10 @@ public final class Matchers { vi.check(matches(matcher)); vi.check(matches(isDisplayed())); return true; } catch (Exception e) { } // Catch AssertionFailedError because vi.check(matches(isDisplayed())) throws that if // assertion fails. catch (Exception|AssertionFailedError e) { return false; } } Loading
tests/src/com/android/documentsui/bots/UiBot.java +11 −6 Original line number Diff line number Diff line Loading @@ -130,12 +130,17 @@ public class UiBot extends Bots.BaseBot { return !inFixedLayout(); } void switchViewMode() { UiObject2 mode = menuGridMode(); if (mode != null) { mode.click(); } else { menuListMode().click(); public void switchToListMode() { final UiObject2 listMode = menuListMode(); if (listMode != null) { listMode.click(); } } public void switchToGridMode() { final UiObject2 gridMode = menuGridMode(); if (gridMode != null) { gridMode.click(); } } Loading