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