1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.documentsui.bots; 18 19 import static androidx.test.espresso.Espresso.onView; 20 import static androidx.test.espresso.action.ViewActions.swipeLeft; 21 import static androidx.test.espresso.action.ViewActions.swipeRight; 22 import static androidx.test.espresso.matcher.ViewMatchers.withId; 23 24 import android.content.Context; 25 import android.util.Log; 26 import android.view.View; 27 28 import androidx.test.uiautomator.UiDevice; 29 import androidx.test.uiautomator.UiObject; 30 import androidx.test.uiautomator.UiObjectNotFoundException; 31 import androidx.test.uiautomator.UiScrollable; 32 import androidx.test.uiautomator.UiSelector; 33 34 import com.android.documentsui.R; 35 36 import junit.framework.Assert; 37 38 import java.util.ArrayList; 39 import java.util.Arrays; 40 import java.util.List; 41 42 /** 43 * A test helper class that provides support for controlling and asserting against 44 * the roots list drawer. 45 */ 46 public class SidebarBot extends Bots.BaseBot { 47 private static final String TAG = "RootsListBot"; 48 49 private final String mRootListId; 50 SidebarBot(UiDevice device, Context context, int timeout)51 public SidebarBot(UiDevice device, Context context, int timeout) { 52 super(device, context, timeout); 53 mRootListId = mTargetPackage + ":id/roots_list"; 54 } 55 findRoot(String label)56 private UiObject findRoot(String label) throws UiObjectNotFoundException { 57 // We might need to expand drawer if not visible 58 openDrawer(); 59 60 final UiSelector rootsList = new UiSelector().resourceId( 61 mTargetPackage + ":id/container_roots").childSelector( 62 new UiSelector().resourceId(mRootListId)); 63 64 // Wait for the first list item to appear 65 new UiObject(rootsList.childSelector(new UiSelector())).waitForExists(mTimeout); 66 67 // Now scroll around to find our item 68 new UiScrollable(rootsList).scrollIntoView(new UiSelector().text(label)); 69 return new UiObject(rootsList.childSelector(new UiSelector().text(label))); 70 } 71 openRoot(String label)72 public void openRoot(String label) throws UiObjectNotFoundException { 73 findRoot(label).click(); 74 // Close the drawer in case we select a pre-selected root already 75 closeDrawer(); 76 } 77 openDrawer()78 public void openDrawer() throws UiObjectNotFoundException { 79 final UiSelector rootsList = new UiSelector().resourceId( 80 mTargetPackage + ":id/container_roots").childSelector( 81 new UiSelector().resourceId(mRootListId)); 82 83 // We might need to expand drawer if not visible 84 if (!new UiObject(rootsList).waitForExists(mTimeout)) { 85 Log.d(TAG, "Failed to find roots list; trying to expand"); 86 final UiSelector hamburger = new UiSelector().resourceId( 87 mTargetPackage + ":id/toolbar").childSelector( 88 new UiSelector().className("android.widget.ImageButton").clickable(true)); 89 new UiObject(hamburger).click(); 90 } 91 } 92 closeDrawer()93 public void closeDrawer() { 94 // Espresso will try to close the drawer if it's opened 95 // But if no drawer exists (Tablet devices), we will have to catch the exception 96 // and continue on the test 97 // Why can't we do something like .exist() first? 98 // http://stackoverflow.com/questions/20807131/espresso-return-boolean-if-view-exists 99 try { 100 if (mContext.getResources().getConfiguration() 101 .getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { 102 onView(withId(R.id.drawer_layout)).perform(swipeRight()); 103 } else { 104 onView(withId(R.id.drawer_layout)).perform(swipeLeft()); 105 } 106 } catch (Exception e) { 107 } 108 } 109 assertRootsPresent(String... labels)110 public void assertRootsPresent(String... labels) throws UiObjectNotFoundException { 111 List<String> missing = new ArrayList<>(); 112 for (String label : labels) { 113 if (!findRoot(label).exists()) { 114 missing.add(label); 115 } 116 } 117 if (!missing.isEmpty()) { 118 Assert.fail( 119 "Expected roots " + Arrays.asList(labels) + ", but missing " + missing); 120 } 121 } 122 assertRootsAbsent(String... labels)123 public void assertRootsAbsent(String... labels) throws UiObjectNotFoundException { 124 List<String> unexpected = new ArrayList<>(); 125 for (String label : labels) { 126 if (findRoot(label).exists()) { 127 unexpected.add(label); 128 } 129 } 130 if (!unexpected.isEmpty()) { 131 Assert.fail("Unexpected roots " + unexpected); 132 } 133 } 134 assertHasFocus()135 public void assertHasFocus() { 136 assertHasFocus(mRootListId); 137 } 138 } 139