1 /* 2 * Copyright (C) 2022 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 package com.android.launcher3.tapl; 17 18 import static com.android.launcher3.testing.shared.TestProtocol.NORMAL_STATE_ORDINAL; 19 20 import android.graphics.Rect; 21 import android.widget.TextView; 22 23 import androidx.test.uiautomator.By; 24 import androidx.test.uiautomator.BySelector; 25 import androidx.test.uiautomator.Direction; 26 import androidx.test.uiautomator.UiObject2; 27 28 import java.util.ArrayList; 29 30 /** 31 * Operations on search result page opened from qsb. 32 */ 33 public class SearchResultFromQsb implements SearchInputSource { 34 private static final String BOTTOM_SHEET_RES_ID = "bottom_sheet_background"; 35 36 // This particular ID change should happen with caution 37 private static final String SEARCH_CONTAINER_RES_ID = "search_results_list_view"; 38 protected final LauncherInstrumentation mLauncher; 39 private final UiObject2 mSearchContainer; 40 SearchResultFromQsb(LauncherInstrumentation launcher)41 SearchResultFromQsb(LauncherInstrumentation launcher) { 42 mLauncher = launcher; 43 mLauncher.waitForLauncherObject("search_container_all_apps"); 44 mSearchContainer = mLauncher.waitForSystemLauncherObject(SEARCH_CONTAINER_RES_ID); 45 } 46 47 /** Find the app from search results with app name. */ findAppIcon(String appName)48 public AppIcon findAppIcon(String appName) { 49 UiObject2 icon = mLauncher.waitForLauncherObject(AppIcon.getAppIconSelector(appName)); 50 return createAppIcon(icon); 51 } 52 createAppIcon(UiObject2 icon)53 protected AppIcon createAppIcon(UiObject2 icon) { 54 return new AllAppsAppIcon(mLauncher, icon); 55 } 56 57 /** Find the web suggestion from search suggestion's title text */ findWebSuggestion(String text)58 public SearchWebSuggestion findWebSuggestion(String text) { 59 UiObject2 webSuggestion = mLauncher.waitForObjectInContainer(mSearchContainer, 60 getSearchResultSelector(text)); 61 return createWebSuggestion(webSuggestion); 62 } 63 createWebSuggestion(UiObject2 webSuggestion)64 protected SearchWebSuggestion createWebSuggestion(UiObject2 webSuggestion) { 65 return new SearchWebSuggestion(mLauncher, webSuggestion); 66 } 67 68 /** Find the total amount of views being displayed and return the size */ getSearchResultItemSize()69 public int getSearchResultItemSize() { 70 ArrayList<UiObject2> searchResultItems = 71 new ArrayList<>(mLauncher.waitForObjectsInContainer(mSearchContainer, 72 By.clazz(TextView.class))); 73 return searchResultItems.size(); 74 } 75 76 /** 77 * Scroll down to make next page search results rendered. 78 */ getNextPageSearchResults()79 public void getNextPageSearchResults() { 80 final int searchContainerHeight = mLauncher.getVisibleBounds(mSearchContainer).height(); 81 // Start scrolling from center of the screen to top of the screen. 82 mLauncher.scroll(mSearchContainer, 83 Direction.DOWN, 84 new Rect(0, 0, 0, searchContainerHeight / 2), 85 /* steps= */ 10, 86 /*slowDown= */ false); 87 } 88 89 /** 90 * Taps outside bottom sheet to dismiss and return to workspace. Available on tablets only. 91 * @param tapRight Tap on the right of bottom sheet if true, or left otherwise. 92 */ dismissByTappingOutsideForTablet(boolean tapRight)93 public void dismissByTappingOutsideForTablet(boolean tapRight) { 94 try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck(); 95 LauncherInstrumentation.Closable c = mLauncher.addContextLayer( 96 "want to tap outside AllApps bottom sheet on the " 97 + (tapRight ? "right" : "left"))) { 98 final UiObject2 allAppsBottomSheet = 99 mLauncher.waitForLauncherObject(BOTTOM_SHEET_RES_ID); 100 tapOutside(tapRight, allAppsBottomSheet); 101 try (LauncherInstrumentation.Closable tapped = mLauncher.addContextLayer( 102 "tapped outside AllApps bottom sheet")) { 103 verifyVisibleContainerOnDismiss(); 104 } 105 } 106 } 107 tapOutside(boolean tapRight, UiObject2 allAppsBottomSheet)108 protected void tapOutside(boolean tapRight, UiObject2 allAppsBottomSheet) { 109 mLauncher.runToState( 110 () -> mLauncher.touchOutsideContainer(allAppsBottomSheet, tapRight), 111 NORMAL_STATE_ORDINAL, 112 "tappig outside"); 113 } 114 verifyVisibleContainerOnDismiss()115 protected void verifyVisibleContainerOnDismiss() { 116 mLauncher.getWorkspace(); 117 } 118 119 @Override getLauncher()120 public LauncherInstrumentation getLauncher() { 121 return mLauncher; 122 } 123 124 @Override getSearchResultForInput()125 public SearchResultFromQsb getSearchResultForInput() { 126 return this; 127 } 128 129 /** Verify a tile is present by checking its title and subtitle. */ verifyTileIsPresent(String title, String subtitle)130 public void verifyTileIsPresent(String title, String subtitle) { 131 mLauncher.waitForObjectInContainer(mSearchContainer, 132 getSearchResultSelector(title)); 133 mLauncher.waitForObjectInContainer(mSearchContainer, 134 getSearchResultSelector(subtitle)); 135 } 136 getSearchResultSelector(String text)137 private BySelector getSearchResultSelector(String text) { 138 return By.clazz(TextView.class).text(text); 139 } 140 } 141