DirectoryListBot.java revision 515e51391722649479b6bac357fd363ea17de1f7
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; 245e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.By; 255e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.BySelector; 265e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.Configurator; 275e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.UiDevice; 285e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.UiObject; 295e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.UiObject2; 305e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.UiObjectNotFoundException; 315e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.UiSelector; 325e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.support.test.uiautomator.Until; 33515e51391722649479b6bac357fd363ea17de1f7Ben Linimport android.view.KeyEvent; 345e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport android.view.MotionEvent; 355e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 365e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport junit.framework.Assert; 375e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 385e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport java.util.ArrayList; 395e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport java.util.Arrays; 405e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport java.util.List; 415e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKayimport java.util.regex.Pattern; 425e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 435e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay/** 445e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * A test helper class that provides support for controlling directory list 455e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay * and making assertions against the state of it. 465e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay */ 475e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKaypublic class DirectoryListBot extends BaseBot { 485e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay private static final String DIR_LIST_ID = "com.android.documentsui:id/dir_list"; 495e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 505e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay private static final BySelector SNACK_DELETE = 515e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay By.desc(Pattern.compile("^Deleting [0-9]+ file.+")); 525e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 535e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public DirectoryListBot(UiDevice device, Context context, int timeout) { 545e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay super(device, context, timeout); 555e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 565e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 575e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertDocumentsCount(int count) throws UiObjectNotFoundException { 585e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay UiObject docsList = findDocumentsList(); 595e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertEquals(count, docsList.getChildCount()); 605e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 615e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 625e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertDocumentsPresent(String... labels) throws UiObjectNotFoundException { 635e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay List<String> absent = new ArrayList<>(); 645e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay for (String label : labels) { 655e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay if (!findDocument(label).exists()) { 665e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay absent.add(label); 675e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 685e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 695e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay if (!absent.isEmpty()) { 705e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay Assert.fail("Expected documents " + Arrays.asList(labels) 715e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay + ", but missing " + absent); 725e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 735e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 745e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 755e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertDocumentsAbsent(String... labels) throws UiObjectNotFoundException { 765e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay List<String> found = new ArrayList<>(); 775e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay for (String label : labels) { 785e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay if (findDocument(label).exists()) { 795e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay found.add(label); 805e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 815e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 825e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay if (!found.isEmpty()) { 835e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay Assert.fail("Expected documents not present" + Arrays.asList(labels) 845e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay + ", but present " + found); 855e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 865e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 875e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 885e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertDocumentsCountOnList(boolean exists, int count) throws UiObjectNotFoundException { 895e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay UiObject docsList = findDocumentsList(); 905e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertEquals(exists, docsList.exists()); 915e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay if(docsList.exists()) { 925e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertEquals(count, docsList.getChildCount()); 935e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 945e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 955e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 965e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertMessageTextView(String message) throws UiObjectNotFoundException { 975e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay UiObject messageTextView = findMessageTextView(); 985e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertTrue(messageTextView.exists()); 995e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1005e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay String msg = String.valueOf(message); 1015e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertEquals(String.format(msg, "TEST_ROOT_0"), messageTextView.getText()); 1025e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1035e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1045e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1055e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay private UiObject findMessageTextView() { 1065e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return findObject( 1075e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay "com.android.documentsui:id/container_directory", 1085e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay "com.android.documentsui:id/message"); 1095e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1105e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1115e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertSnackbar(int id) { 1125e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertNotNull(getSnackbar(mContext.getString(id))); 1135e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1145e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1155e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void openDocument(String label) throws UiObjectNotFoundException { 1165e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay int toolType = Configurator.getInstance().getToolType(); 1175e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER); 1185e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay UiObject doc = findDocument(label); 1195e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay doc.click(); 1205e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay Configurator.getInstance().setToolType(toolType); 1215e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1225e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1235e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void clickDocument(String label) throws UiObjectNotFoundException { 1245e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay findDocument(label).click(); 1255e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1265e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1275e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public UiObject selectDocument(String label) throws UiObjectNotFoundException { 1285e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay UiObject doc = findDocument(label); 1295e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay doc.longClick(); 1305e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return doc; 1315e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1325e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 133515e51391722649479b6bac357fd363ea17de1f7Ben Lin public void copyFilesToClipboard(String...labels) throws UiObjectNotFoundException { 134515e51391722649479b6bac357fd363ea17de1f7Ben Lin for (String label: labels) { 135515e51391722649479b6bac357fd363ea17de1f7Ben Lin clickDocument(label); 136515e51391722649479b6bac357fd363ea17de1f7Ben Lin } 137515e51391722649479b6bac357fd363ea17de1f7Ben Lin mDevice.pressKeyCode(KeyEvent.KEYCODE_C, KeyEvent.META_CTRL_ON); 138515e51391722649479b6bac357fd363ea17de1f7Ben Lin } 139515e51391722649479b6bac357fd363ea17de1f7Ben Lin 140515e51391722649479b6bac357fd363ea17de1f7Ben Lin public void pasteFilesFromClipboard() { 141515e51391722649479b6bac357fd363ea17de1f7Ben Lin mDevice.pressKeyCode(KeyEvent.KEYCODE_V, KeyEvent.META_CTRL_ON); 142515e51391722649479b6bac357fd363ea17de1f7Ben Lin } 143515e51391722649479b6bac357fd363ea17de1f7Ben Lin 1445e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public UiObject2 getSnackbar(String message) { 1455e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return mDevice.wait(Until.findObject(By.text(message)), mTimeout); 1465e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1475e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1485e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void waitForDeleteSnackbar() { 1495e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay mDevice.wait(Until.findObject(SNACK_DELETE), mTimeout); 1505e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1515e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1525e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void waitForDeleteSnackbarGone() { 1535e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay // wait a little longer for snackbar to go away, as it disappears after a timeout. 1545e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay mDevice.wait(Until.gone(SNACK_DELETE), mTimeout * 2); 1555e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1565e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1575e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void waitForDocument(String label) throws UiObjectNotFoundException { 1585e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay findDocument(label).waitForExists(mTimeout); 1595e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1605e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1615e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public UiObject findDocument(String label) throws UiObjectNotFoundException { 1625e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay final UiSelector docList = new UiSelector().resourceId( 1635e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay "com.android.documentsui:id/container_directory").childSelector( 1645e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay new UiSelector().resourceId(DIR_LIST_ID)); 1655e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1665e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay // Wait for the first list item to appear 1675e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay new UiObject(docList.childSelector(new UiSelector())).waitForExists(mTimeout); 1685e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1695e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay // new UiScrollable(docList).scrollIntoView(new UiSelector().text(label)); 1705e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return mDevice.findObject(docList.childSelector(new UiSelector().text(label))); 1715e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1725e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1735e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public boolean hasDocuments(String... labels) throws UiObjectNotFoundException { 1745e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay for (String label : labels) { 1755e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay if (!findDocument(label).exists()) { 1765e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return false; 1775e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1785e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1795e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return true; 1805e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1815e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 182811777ecf0bc23cb698dad6d9e29a5956a6f54ecTomasz Mikolajewski public UiObject findDocumentsList() { 1835e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay return findObject( 1845e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay "com.android.documentsui:id/container_directory", 1855e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay DIR_LIST_ID); 1865e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1875e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay 1885e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay public void assertHasFocus() { 1895e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay assertHasFocus(DIR_LIST_ID); 1905e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay } 1915e1acc9f71ca4c2a07ba64ec9c050b20303993e2Steve McKay} 192