1 /* 2 * Copyright (C) 2023 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.adservices.tests.ui.libs.pages; 17 18 import static com.android.adservices.tests.ui.libs.UiConstants.NOTIFICATION_SCROLLER; 19 import static com.android.adservices.tests.ui.libs.UiUtils.LAUNCH_TIMEOUT; 20 import static com.android.adservices.tests.ui.libs.UiUtils.PRIMITIVE_UI_OBJECTS_LAUNCH_TIMEOUT; 21 import static com.android.adservices.tests.ui.libs.UiUtils.SCROLL_WAIT_TIME; 22 import static com.android.adservices.tests.ui.libs.UiUtils.getElement; 23 import static com.android.adservices.tests.ui.libs.UiUtils.getPageElement; 24 import static com.android.adservices.tests.ui.libs.UiUtils.getString; 25 import static com.android.adservices.tests.ui.libs.UiUtils.sysuiResSelector; 26 27 import static com.google.common.truth.Truth.assertThat; 28 29 import android.content.Context; 30 import android.util.Log; 31 32 import androidx.test.uiautomator.By; 33 import androidx.test.uiautomator.UiDevice; 34 import androidx.test.uiautomator.UiObject2; 35 import androidx.test.uiautomator.UiObjectNotFoundException; 36 import androidx.test.uiautomator.UiSelector; 37 import androidx.test.uiautomator.Until; 38 39 import com.android.adservices.api.R; 40 import com.android.adservices.tests.ui.libs.UiConstants; 41 42 public class NotificationPages { verifyNotification( Context context, UiDevice device, boolean isDisplayed, boolean isEuTest, UiConstants.UX ux, boolean isV2, boolean isPas, boolean isPasRenotify)43 public static void verifyNotification( 44 Context context, 45 UiDevice device, 46 boolean isDisplayed, 47 boolean isEuTest, 48 UiConstants.UX ux, 49 boolean isV2, 50 boolean isPas, 51 boolean isPasRenotify) 52 throws Exception { 53 device.openNotification(); 54 Thread.sleep(LAUNCH_TIMEOUT); 55 56 int notificationTitle = -1; 57 int notificationHeader = -1; 58 switch (ux) { 59 case GA_UX: 60 // Should match the contentTitle string in ConsentNotificationTrigger.java. 61 if (isPas || isPasRenotify) { 62 notificationTitle = 63 isPasRenotify 64 ? R.string.notificationUI_pas_re_notification_title 65 : R.string.notificationUI_pas_notification_title; 66 notificationHeader = 67 isPasRenotify 68 ? R.string.notificationUI_pas_renotify_header_title 69 : R.string.notificationUI_pas_header_title; 70 } else { 71 notificationTitle = 72 isEuTest 73 ? R.string.notificationUI_notification_ga_title_eu_v2 74 : R.string.notificationUI_notification_ga_title_v2; 75 // Should match the text in consent_notification_screen_1_ga_v2_eu.xml and 76 // consent_notification_screen_1_ga_v2_row.xml, respectively. 77 notificationHeader = 78 isEuTest 79 ? R.string.notificationUI_fledge_measurement_title_v2 80 : R.string.notificationUI_header_ga_title_v2; 81 } 82 break; 83 case BETA_UX: 84 notificationTitle = 85 isEuTest 86 ? R.string.notificationUI_notification_title_eu 87 : R.string.notificationUI_notification_title; 88 notificationHeader = 89 isEuTest 90 ? R.string.notificationUI_header_title_eu 91 : R.string.notificationUI_header_title; 92 break; 93 case U18_UX: 94 notificationTitle = R.string.notificationUI_u18_notification_title; 95 notificationHeader = R.string.notificationUI_u18_header_title; 96 break; 97 } 98 99 Log.d( 100 "adservices", 101 "Expected notification card title is: " + getString(context, notificationTitle)); 102 Log.d( 103 "adservices", 104 "Expected notification landing page title is: " 105 + getString(context, notificationHeader)); 106 107 UiSelector notificationCardSelector = 108 new UiSelector().text(getString(context, notificationTitle)); 109 110 UiObject2 scroller = 111 device.wait( 112 Until.findObject(sysuiResSelector(NOTIFICATION_SCROLLER)), LAUNCH_TIMEOUT); 113 114 UiObject2 notificationCard = 115 scroller.findObject(By.textContains(getString(context, notificationTitle))); 116 if (!isDisplayed) { 117 assertThat(notificationCard).isNull(); 118 return; 119 } 120 121 assertThat(notificationCard).isNotNull(); 122 notificationCard.click(); 123 Thread.sleep(LAUNCH_TIMEOUT); 124 UiObject2 title = getPageElement(context, device, notificationHeader); 125 126 assertThat(title).isNotNull(); 127 } 128 betaNotificationPage( Context context, UiDevice device, boolean isEuDevice, boolean isGoSettings, boolean isOptin)129 public static void betaNotificationPage( 130 Context context, 131 UiDevice device, 132 boolean isEuDevice, 133 boolean isGoSettings, 134 boolean isOptin) 135 throws UiObjectNotFoundException, InterruptedException { 136 int leftButtonResId = 137 isEuDevice 138 ? R.string.notificationUI_left_control_button_text_eu 139 : R.string.notificationUI_left_control_button_text; 140 141 int rightButtonResId = 142 isEuDevice 143 ? R.string.notificationUI_right_control_button_text_eu 144 : R.string.notificationUI_right_control_button_text; 145 146 goThroughNotificationPage(context, device, leftButtonResId, rightButtonResId); 147 UiObject2 leftControlButton = getElement(context, device, leftButtonResId); 148 UiObject2 rightControlButton = getElement(context, device, rightButtonResId); 149 150 if (isEuDevice) { 151 if (!isOptin) { 152 leftControlButton.click(); 153 } else { 154 rightControlButton.click(); 155 Thread.sleep(PRIMITIVE_UI_OBJECTS_LAUNCH_TIMEOUT); 156 UiObject2 acceptedTitle = 157 getElement( 158 context, device, R.string.notificationUI_confirmation_accept_title); 159 assertThat(acceptedTitle).isNotNull(); 160 } 161 } else { 162 if (isGoSettings) { 163 leftControlButton.click(); 164 } else { 165 rightControlButton.click(); 166 } 167 Thread.sleep(PRIMITIVE_UI_OBJECTS_LAUNCH_TIMEOUT); 168 } 169 } 170 betaNotificationConfirmPage( Context context, UiDevice device, boolean isGoSettings)171 public static void betaNotificationConfirmPage( 172 Context context, UiDevice device, boolean isGoSettings) 173 throws UiObjectNotFoundException, InterruptedException { 174 int leftButtonResId = R.string.notificationUI_confirmation_left_control_button_text; 175 int rightButtonResId = R.string.notificationUI_confirmation_right_control_button_text; 176 177 UiObject2 leftControlButton = getElement(context, device, leftButtonResId); 178 UiObject2 rightControlButton = getElement(context, device, rightButtonResId); 179 180 if (isGoSettings) { 181 leftControlButton.click(); 182 } else { 183 rightControlButton.click(); 184 } 185 Thread.sleep(PRIMITIVE_UI_OBJECTS_LAUNCH_TIMEOUT); 186 } 187 euNotificationLandingPageMsmtAndFledgePage( Context context, UiDevice device, boolean isGoSettings, boolean isFlip)188 public static void euNotificationLandingPageMsmtAndFledgePage( 189 Context context, UiDevice device, boolean isGoSettings, boolean isFlip) 190 throws UiObjectNotFoundException, InterruptedException { 191 int leftButtonResId = R.string.notificationUI_left_control_button_text; 192 int rightButtonResId = R.string.notificationUI_right_control_button_text; 193 goThroughNotificationPage(context, device, leftButtonResId, rightButtonResId); 194 UiObject2 leftControlButton = getElement(context, device, leftButtonResId); 195 UiObject2 rightControlButton = getElement(context, device, rightButtonResId); 196 if (isGoSettings) { 197 leftControlButton.clickAndWait(Until.newWindow(), PRIMITIVE_UI_OBJECTS_LAUNCH_TIMEOUT); 198 } else { 199 rightControlButton.clickAndWait(Until.newWindow(), PRIMITIVE_UI_OBJECTS_LAUNCH_TIMEOUT); 200 if (isFlip) { 201 UiObject2 title2 = 202 getElement(context, device, R.string.notificationUI_header_ga_title_eu_v2); 203 assertThat(title2).isNotNull(); 204 } 205 } 206 } 207 euNotificationLandingPageTopicsPage( Context context, UiDevice device, boolean isOptin, boolean isFlip)208 public static void euNotificationLandingPageTopicsPage( 209 Context context, UiDevice device, boolean isOptin, boolean isFlip) 210 throws UiObjectNotFoundException, InterruptedException { 211 int leftButtonResId = R.string.notificationUI_left_control_button_text_eu; 212 int rightButtonResId = 213 isFlip 214 ? R.string.notificationUI_right_control_button_ga_text_eu_v2 215 : R.string.notificationUI_right_control_button_ga_text_eu; 216 goThroughNotificationPage(context, device, leftButtonResId, rightButtonResId); 217 UiObject2 leftControlButton = getElement(context, device, leftButtonResId); 218 UiObject2 rightControlButton = getElement(context, device, rightButtonResId); 219 if (isOptin) { 220 rightControlButton.click(); 221 if (!isFlip) { 222 Thread.sleep(PRIMITIVE_UI_OBJECTS_LAUNCH_TIMEOUT); 223 UiObject2 acceptedTitle = 224 getElement( 225 context, device, R.string.notificationUI_fledge_measurement_title); 226 assertThat(acceptedTitle).isNotNull(); 227 } 228 } else { 229 leftControlButton.click(); 230 } 231 } 232 rowNotificationLandingPage( Context context, UiDevice device, boolean isGoSettings)233 public static void rowNotificationLandingPage( 234 Context context, UiDevice device, boolean isGoSettings) 235 throws UiObjectNotFoundException, InterruptedException { 236 int leftButtonResId = R.string.notificationUI_left_control_button_text; 237 int rightButtonResId = R.string.notificationUI_right_control_button_text; 238 goThroughNotificationPage(context, device, leftButtonResId, rightButtonResId); 239 UiObject2 leftControlButton = getElement(context, device, leftButtonResId); 240 UiObject2 rightControlButton = getElement(context, device, rightButtonResId); 241 if (isGoSettings) { 242 leftControlButton.click(); 243 } else { 244 rightControlButton.click(); 245 } 246 Thread.sleep(PRIMITIVE_UI_OBJECTS_LAUNCH_TIMEOUT); 247 } 248 u18NotifiacitonLandingPage( Context context, UiDevice device, boolean isGoSettings)249 public static void u18NotifiacitonLandingPage( 250 Context context, UiDevice device, boolean isGoSettings) 251 throws UiObjectNotFoundException, InterruptedException { 252 int leftButtonResId = R.string.notificationUI_u18_left_control_button_text; 253 int rightButtonResId = R.string.notificationUI_u18_right_control_button_text; 254 goThroughNotificationPage(context, device, leftButtonResId, rightButtonResId); 255 UiObject2 leftControlButton = getElement(context, device, leftButtonResId); 256 UiObject2 rightControlButton = getElement(context, device, rightButtonResId); 257 if (isGoSettings) { 258 leftControlButton.click(); 259 } else { 260 rightControlButton.click(); 261 } 262 Thread.sleep(PRIMITIVE_UI_OBJECTS_LAUNCH_TIMEOUT); 263 UiObject2 topicTitle = getElement(context, device, R.string.settingsUI_topics_ga_title); 264 assertThat(topicTitle).isNotNull(); 265 } 266 goThroughNotificationPage( Context context, UiDevice device, int leftButtonResId, int rightButtonResId)267 public static void goThroughNotificationPage( 268 Context context, UiDevice device, int leftButtonResId, int rightButtonResId) 269 throws UiObjectNotFoundException, InterruptedException { 270 UiObject2 leftControlButton = getElement(context, device, leftButtonResId); 271 UiObject2 rightControlButton = getElement(context, device, rightButtonResId); 272 UiObject2 moreButton = 273 getElement(context, device, R.string.notificationUI_more_button_text); 274 UiObject2 scrollView = device.findObject(By.clazz("android.widget.ScrollView")); 275 if (scrollView.isScrollable()) { 276 assertThat(leftControlButton).isNull(); 277 assertThat(rightControlButton).isNull(); 278 assertThat(moreButton).isNotNull(); 279 int clickCount = 10; 280 while (moreButton != null && clickCount-- > 0) { 281 moreButton.click(); 282 Thread.sleep(SCROLL_WAIT_TIME); 283 moreButton = getElement(context, device, R.string.notificationUI_more_button_text); 284 } 285 } else { 286 leftControlButton = getElement(context, device, leftButtonResId); 287 rightControlButton = getElement(context, device, rightButtonResId); 288 assertThat(leftControlButton).isNotNull(); 289 assertThat(rightControlButton).isNotNull(); 290 assertThat(moreButton).isNull(); 291 } 292 } 293 } 294