DirectoryListBot.java revision 85ec0d676297724f211213c7cb188839f1d3601b
15e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay/* 25e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * Copyright (C) 2015 The Android Open Source Project 35e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * 45e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * Licensed under the Apache License, Version 2.0 (the "License"); 55e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * you may not use this file except in compliance with the License. 65e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * You may obtain a copy of the License at 75e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * 85e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * http://www.apache.org/licenses/LICENSE-2.0 95e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * 105e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * Unless required by applicable law or agreed to in writing, software 115e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * distributed under the License is distributed on an "AS IS" BASIS, 125e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * See the License for the specific language governing permissions and 145e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * limitations under the License. 155e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay */ 165e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 175e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKaypackage com.android.documentsui.bots; 185e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 195e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport static junit.framework.Assert.assertEquals; 205e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport static junit.framework.Assert.assertNotNull; 215e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport static junit.framework.Assert.assertTrue; 225e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 235e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.content.Context; 2485ec0d676297724f211213c7cb188839f1d3601bSteve McKayimport android.support.test.espresso.Espresso; 2585ec0d676297724f211213c7cb188839f1d3601bSteve McKayimport android.support.test.espresso.matcher.ViewMatchers; 265e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.By; 275e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.BySelector; 285e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.Configurator; 295e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.UiDevice; 305e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.UiObject; 315e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.UiObject2; 325e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.UiObjectNotFoundException; 335e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.UiSelector; 345e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.Until; 3585ec0d676297724f211213c7cb188839f1d3601bSteve McKayimport android.support.v7.widget.RecyclerView; 36515e51391722649479b6bac357fd363ea17de1f7Ben Linimport android.view.KeyEvent; 375e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.view.MotionEvent; 385e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 3985ec0d676297724f211213c7cb188839f1d3601bSteve McKayimport com.android.documentsui.R; 4085ec0d676297724f211213c7cb188839f1d3601bSteve McKay 415e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport junit.framework.Assert; 425e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 435e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport java.util.ArrayList; 445e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport java.util.Arrays; 455e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport java.util.List; 465e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport java.util.regex.Pattern; 475e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 485e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay/** 495e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * A test helper class that provides support for controlling directory list 505e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * and making assertions against the state of it. 515e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay */ 5285ec0d676297724f211213c7cb188839f1d3601bSteve McKaypublic class DirectoryListBot extends Bots.BaseBot { 535e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay private static final String DIR_LIST_ID = "com.android.documentsui:id/dir_list"; 545e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 555e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay private static final BySelector SNACK_DELETE = 565e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay By.desc(Pattern.compile("^Deleting [0-9]+ file.+")); 575e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 585e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public DirectoryListBot(UiDevice device, Context context, int timeout) { 595e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay super(device, context, timeout); 605e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 615e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 625e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertDocumentsCount(int count) throws UiObjectNotFoundException { 635e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay UiObject docsList = findDocumentsList(); 645e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertEquals(count, docsList.getChildCount()); 655e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 665e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 675e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertDocumentsPresent(String... labels) throws UiObjectNotFoundException { 685e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay List<String> absent = new ArrayList<>(); 695e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay for (String label : labels) { 705e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay if (!findDocument(label).exists()) { 715e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay absent.add(label); 725e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 735e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 745e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay if (!absent.isEmpty()) { 755e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay Assert.fail("Expected documents " + Arrays.asList(labels) 765e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay + ", but missing " + absent); 775e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 785e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 795e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 805e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertDocumentsAbsent(String... labels) throws UiObjectNotFoundException { 815e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay List<String> found = new ArrayList<>(); 825e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay for (String label : labels) { 835e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay if (findDocument(label).exists()) { 845e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay found.add(label); 855e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 865e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 875e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay if (!found.isEmpty()) { 885e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay Assert.fail("Expected documents not present" + Arrays.asList(labels) 895e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay + ", but present " + found); 905e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 915e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 925e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 935e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertDocumentsCountOnList(boolean exists, int count) throws UiObjectNotFoundException { 945e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay UiObject docsList = findDocumentsList(); 955e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertEquals(exists, docsList.exists()); 965e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay if(docsList.exists()) { 975e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertEquals(count, docsList.getChildCount()); 985e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 995e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1005e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1015e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertMessageTextView(String message) throws UiObjectNotFoundException { 1025e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay UiObject messageTextView = findMessageTextView(); 1035e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertTrue(messageTextView.exists()); 1045e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1055e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay String msg = String.valueOf(message); 1065e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertEquals(String.format(msg, "TEST_ROOT_0"), messageTextView.getText()); 1075e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1085e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1095e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1105e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay private UiObject findMessageTextView() { 1115e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return findObject( 1125e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay "com.android.documentsui:id/container_directory", 1135e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay "com.android.documentsui:id/message"); 1145e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1155e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1165e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertSnackbar(int id) { 1175e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertNotNull(getSnackbar(mContext.getString(id))); 1185e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1195e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1205e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void openDocument(String label) throws UiObjectNotFoundException { 1215e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay int toolType = Configurator.getInstance().getToolType(); 1225e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER); 1235e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay UiObject doc = findDocument(label); 1245e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay doc.click(); 1255e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay Configurator.getInstance().setToolType(toolType); 1265e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1275e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1285e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void clickDocument(String label) throws UiObjectNotFoundException { 1295e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay findDocument(label).click(); 1305e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1315e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1325e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public UiObject selectDocument(String label) throws UiObjectNotFoundException { 13385ec0d676297724f211213c7cb188839f1d3601bSteve McKay waitForDocument(label); 1345e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay UiObject doc = findDocument(label); 1355e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay doc.longClick(); 1365e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return doc; 1375e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1385e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 139515e51391722649479b6bac357fd363ea17de1f7Ben Lin public void copyFilesToClipboard(String...labels) throws UiObjectNotFoundException { 140515e51391722649479b6bac357fd363ea17de1f7Ben Lin for (String label: labels) { 141515e51391722649479b6bac357fd363ea17de1f7Ben Lin clickDocument(label); 142515e51391722649479b6bac357fd363ea17de1f7Ben Lin } 143515e51391722649479b6bac357fd363ea17de1f7Ben Lin mDevice.pressKeyCode(KeyEvent.KEYCODE_C, KeyEvent.META_CTRL_ON); 144515e51391722649479b6bac357fd363ea17de1f7Ben Lin } 145515e51391722649479b6bac357fd363ea17de1f7Ben Lin 146515e51391722649479b6bac357fd363ea17de1f7Ben Lin public void pasteFilesFromClipboard() { 147515e51391722649479b6bac357fd363ea17de1f7Ben Lin mDevice.pressKeyCode(KeyEvent.KEYCODE_V, KeyEvent.META_CTRL_ON); 148515e51391722649479b6bac357fd363ea17de1f7Ben Lin } 149515e51391722649479b6bac357fd363ea17de1f7Ben Lin 1505e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public UiObject2 getSnackbar(String message) { 1515e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return mDevice.wait(Until.findObject(By.text(message)), mTimeout); 1525e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1535e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1545e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void waitForDeleteSnackbar() { 1555e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay mDevice.wait(Until.findObject(SNACK_DELETE), mTimeout); 1565e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1575e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1585e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void waitForDeleteSnackbarGone() { 1595e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay // wait a little longer for snackbar to go away, as it disappears after a timeout. 1605e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay mDevice.wait(Until.gone(SNACK_DELETE), mTimeout * 2); 1615e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1625e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1635e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void waitForDocument(String label) throws UiObjectNotFoundException { 1645e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay findDocument(label).waitForExists(mTimeout); 1655e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1665e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1675e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public UiObject findDocument(String label) throws UiObjectNotFoundException { 1685e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay final UiSelector docList = new UiSelector().resourceId( 1695e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay "com.android.documentsui:id/container_directory").childSelector( 1705e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay new UiSelector().resourceId(DIR_LIST_ID)); 1715e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1725e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay // Wait for the first list item to appear 1735e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay new UiObject(docList.childSelector(new UiSelector())).waitForExists(mTimeout); 1745e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1755e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay // new UiScrollable(docList).scrollIntoView(new UiSelector().text(label)); 1765e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return mDevice.findObject(docList.childSelector(new UiSelector().text(label))); 1775e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1785e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1795e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public boolean hasDocuments(String... labels) throws UiObjectNotFoundException { 1805e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay for (String label : labels) { 1815e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay if (!findDocument(label).exists()) { 1825e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return false; 1835e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1845e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1855e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return true; 1865e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1875e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 188811777ecf0bc23cb698dad6d9e29a5956a6f54ecTomasz Mikolajewski public UiObject findDocumentsList() { 1895e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return findObject( 1905e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay "com.android.documentsui:id/container_directory", 1915e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay DIR_LIST_ID); 1925e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1935e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1945e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertHasFocus() { 1955e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertHasFocus(DIR_LIST_ID); 1965e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1975e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay} 198