1 /*
2  * Copyright (C) 2018 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.traceur.uitest;
18 
19 import static org.junit.Assert.assertNotNull;
20 
21 import android.content.Context;
22 import android.content.Intent;
23 import android.os.RemoteException;
24 import android.platform.test.annotations.Presubmit;
25 import android.support.test.uiautomator.By;
26 import android.support.test.uiautomator.UiDevice;
27 import android.support.test.uiautomator.UiObjectNotFoundException;
28 import android.support.test.uiautomator.UiSelector;
29 import android.support.test.uiautomator.UiScrollable;
30 import android.support.test.uiautomator.Until;
31 
32 import androidx.test.InstrumentationRegistry;
33 import androidx.test.runner.AndroidJUnit4;
34 
35 import org.junit.After;
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 
40 import java.util.regex.Pattern;
41 
42 @RunWith(AndroidJUnit4.class)
43 public class TraceurAppTests {
44 
45     private static final String TRACEUR_PACKAGE = "com.android.traceur";
46     private static final int TIMEOUT = 20000;   // milliseconds
47 
48     private UiDevice mDevice;
49 
50     @Before
setUp()51     public void setUp() throws Exception {
52         mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
53 
54         try {
55             if (!mDevice.isScreenOn()) {
56                 mDevice.wakeUp();
57             }
58 
59             // Press Menu to skip the lock screen.
60             // In case we weren't on the lock screen, press Home to return to a clean launcher.
61             mDevice.pressMenu();
62             mDevice.pressHome();
63 
64             mDevice.setOrientationNatural();
65         } catch (RemoteException e) {
66             throw new RuntimeException("Failed to freeze device orientation.", e);
67         }
68 
69         mDevice.waitForIdle();
70 
71         Context context = InstrumentationRegistry.getContext();
72         Intent intent = context.getPackageManager().getLaunchIntentForPackage(TRACEUR_PACKAGE);
73         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);    // Clear out any previous instances
74         context.startActivity(intent);
75 
76        // Wait for the app to appear
77         mDevice.wait(Until.hasObject(By.pkg(TRACEUR_PACKAGE).depth(0)), TIMEOUT);
78     }
79 
80     @After
tearDown()81     public void tearDown() throws Exception {
82         mDevice.unfreezeRotation();
83         // Finish Traceur activity.
84         mDevice.pressBack();
85         mDevice.pressHome();
86     }
87 
88     @Presubmit
89     @Test
testElementsOnMainScreen()90     public void testElementsOnMainScreen() throws Exception {
91         assertNotNull("Record trace switch not found.",
92                 mDevice.wait(Until.findObject(By.text("Record trace")),
93                 TIMEOUT));
94         assertNotNull("Applications element not found.",
95                 mDevice.wait(Until.findObject(By.text("Trace debuggable applications")),
96                 TIMEOUT));
97         assertNotNull("Categories element not found.",
98                 mDevice.wait(Until.findObject(By.text("Categories")),
99                 TIMEOUT));
100         assertNotNull("Restore default categories element not found.",
101                 mDevice.wait(Until.findObject(By.text("Restore default categories")),
102                 TIMEOUT));
103         assertNotNull("Per-CPU buffer size element not found.",
104                 mDevice.wait(Until.findObject(By.text("Per-CPU buffer size")),
105                 TIMEOUT));
106 
107         UiScrollable mainScreen = new UiScrollable(new UiSelector().scrollable(true));
108         try {
109             mainScreen.scrollToEnd(4);
110         } catch (UiObjectNotFoundException e) {
111           // if the screen is not scrollable, all elements should be visible already
112         }
113 
114         // Remove post-scroll cehcks until we validate cuttlefish behavior.
115         /*
116         assertNotNull("Clear saved traces element not found.",
117                 mDevice.wait(Until.findObject(By.text("Clear saved traces")),
118                 TIMEOUT));
119         assertNotNull("Long traces element not found.",
120                 mDevice.wait(Until.findObject(By.text("Long traces")),
121                 TIMEOUT));
122         assertNotNull("Maximum long trace size element not found.",
123                 mDevice.wait(Until.findObject(By.text("Maximum long trace size")),
124                 TIMEOUT));
125         assertNotNull("Maximum long trace duration element not found.",
126                 mDevice.wait(Until.findObject(By.text("Maximum long trace duration")),
127                 TIMEOUT));
128         assertNotNull("Show Quick Settings tile switch not found.",
129                 mDevice.wait(Until.findObject(By.text("Show Quick Settings tile")),
130                 TIMEOUT));
131         */
132     }
133 
134     /*
135      * In this test:
136      * Take a trace by toggling 'Record trace' in the UI
137      * Tap the notification once the trace is saved, and verify the share dialog appears.
138      */
139     @Presubmit
140     @Test
testSuccessfulTracing()141     public void testSuccessfulTracing() throws Exception {
142         mDevice.wait(Until.findObject(By.text("Record trace")), TIMEOUT);
143 
144         mDevice.findObject(By.text("Record trace")).click();
145         mDevice.wait(Until.hasObject(By.text("Trace is being recorded")), TIMEOUT);
146         mDevice.findObject(By.text("Record trace")).click();
147 
148         // Wait for the popover notification to appear and then disappear,
149         // so we can reliably click the notification in the notification shade.
150         mDevice.wait(Until.hasObject(By.text("Tap to share your trace")), TIMEOUT);
151         mDevice.wait(Until.gone(By.text("Tap to share your trace")), TIMEOUT);
152 
153         mDevice.openNotification();
154         mDevice.wait(Until.hasObject(By.text("Tap to share your trace")), TIMEOUT);
155         mDevice.findObject(By.text("Tap to share your trace")).click();
156 
157         mDevice.wait(Until.hasObject(By.text("Only share system traces with people and apps you trust.")), TIMEOUT);
158         // The buttons on dialogs sometimes have their capitalization manipulated by themes.
159         mDevice.findObject(By.text(Pattern.compile("share", Pattern.CASE_INSENSITIVE))).click();
160 
161         mDevice.wait(Until.hasObject(By.text("Share with")), TIMEOUT);
162     }
163 }
164