diff options
author | David Yu <dyu@google.com> | 2023-12-07 01:56:28 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2023-12-07 01:56:28 +0000 |
commit | c00cd5eb81ebf4cf8c6213472f449d283064e677 (patch) | |
tree | ed081ac9a5fca5dffacb7d7a71f874d78a7a3278 | |
parent | bb493c4bd8b5b0858e651a052f51ee62bdac5760 (diff) | |
parent | ec7476bd12fe0f55999f6f35fed8e3062423127c (diff) | |
download | adt-infra-aosp-emu-34-dev.tar.gz |
Merge "Add system image UI tests for API 33." into emu-master-devaosp-emu-34-dev
12 files changed, 2837 insertions, 0 deletions
diff --git a/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/AddGoogleAccountTest.java b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/AddGoogleAccountTest.java new file mode 100644 index 00000000..e6c977fb --- /dev/null +++ b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/AddGoogleAccountTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.devtools.systemimage.uitest.smoke.api33; + +import android.app.Instrumentation; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiSelector; + +import com.android.devtools.systemimage.uitest.annotations.TestInfo; +import com.android.devtools.systemimage.uitest.common.Res; +import com.android.devtools.systemimage.uitest.framework.SystemImageTestFramework; +import com.android.devtools.systemimage.uitest.utils.AppLauncher; +import com.android.devtools.systemimage.uitest.utils.Wait; +import com.android.devtools.systemimage.uitest.watchers.watcher; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; +import static org.junit.Assert.assertTrue; + +/** + * Test for adding a Google account. + */ +@RunWith(AndroidJUnit4.class) +public class AddGoogleAccountTest { + @Rule + public final SystemImageTestFramework testFramework = new SystemImageTestFramework(); + + @Rule + public Timeout globalTimeout = Timeout.seconds(120); + + /** + * Verifies able to add a Google account using Contacts app. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TR ID: C14581151 + * <p> + * <pre> + * Test Steps: + * 1. Start the emulator. + * 2. Open Contacts app. + * 3. Tap on "Add Account" + * Verify: + * User is prompted to sign in to a Google Account. + * </pre> + */ + @Test + @TestInfo(id = "14581151") + public void testAddAccountUsingContactsApp() throws Exception { + final Instrumentation instrumentation = testFramework.getInstrumentation(); + final UiDevice mDevice = testFramework.getDevice(); + + AppLauncher.launch(instrumentation, "Contacts"); + // Check if the app is running for the first time. + UiObject checkingInfo = + mDevice.findObject(new UiSelector().textContains("Checking Info")); + if (checkingInfo.exists()) { + mDevice.pressBack(); + } + AppLauncher.launch(instrumentation, "Contacts"); + + UiObject addAccount = mDevice.findObject( + new UiSelector().resourceId((Res.ADD_NEW_CONTACT))); + + boolean isFound = addAccount.waitForExists(5L); + if (isFound) { + addAccount.clickAndWaitForNewWindow(); + } + + UiObject signInHeader = mDevice.findObject( + new UiSelector().textMatches(("(?i)sign in(?-i)")).resourceId("headingText")); + boolean isSignInPage = signInHeader.waitForExists(1000); + + UiObject createNewContact = mDevice.findObject( + new UiSelector().text("Create new contact")); + + boolean isNewContactsPage = false; + + if (!isSignInPage) { + new watcher(mDevice, Res.ADD_GOOGLE_ACC_WATCHER_PATTERN).checkForCondition(); + isNewContactsPage = createNewContact.waitForExists(1000); + } + + assertTrue("Add Google account page not found", + isSignInPage || isNewContactsPage); + } +} diff --git a/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/ApiDemosTest.java b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/ApiDemosTest.java new file mode 100644 index 00000000..44c809fa --- /dev/null +++ b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/ApiDemosTest.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.devtools.systemimage.uitest.smoke.api33; + +import android.app.Instrumentation; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiScrollable; +import android.support.test.uiautomator.UiSelector; + +import com.android.devtools.systemimage.uitest.annotations.TestInfo; +import com.android.devtools.systemimage.uitest.common.Res; +import com.android.devtools.systemimage.uitest.framework.SystemImageTestFramework; +import com.android.devtools.systemimage.uitest.utils.ApiDemosInstaller; +import com.android.devtools.systemimage.uitest.utils.ApiDemosTestUtil; +import com.android.devtools.systemimage.uitest.utils.AppLauncher; +import com.android.devtools.systemimage.uitest.utils.SettingsUtil; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; + +import java.util.concurrent.TimeUnit; + +/** + * Test to verify the functionality of "PASSWORD CONTROLS". + */ +@RunWith(AndroidJUnit4.class) +public class ApiDemosTest { + + @Rule + public final SystemImageTestFramework testFramework = new SystemImageTestFramework(); + + @Rule + public Timeout globalTimeout = Timeout.seconds(800); + + private Instrumentation instrumentation = testFramework.getInstrumentation(); + private UiDevice device = testFramework.getDevice(); + + @Before + public void activateDeviceAdmin() throws Exception { + ApiDemosInstaller.installApp("Security", "Device admin apps", false); + } + + /** + * To test if the password is adhering to the conditions set in "PASSWORD QUALITY". + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TR ID: T144630615 + * <p> + * <pre> + * Test Steps: + * 1. Goto API Demos —> App —> Device Admin —> Password quality. + * 2. Set Password Quality fields by following following rules: + * Password quality: Complex Minimum. + * Minimum Length: 6 Minimum. + * Minimum Letters: 1. + * Minimum Numeric: 1. + * Minimum Lower case: 1. + * Minimum Upper Case: 1. + * Minimum Symbols: 1. + * Minimum non-Letters: 1. + * Verify: + * 1. Settings —> Security —> Screen Lock —> Set it to Password. + * You are asked to set password according to rules mentioned above. + * </pre> + * + */ + @Test + @TestInfo(id = "T144630615") + public void testPasswordQuality() throws Exception { + AppLauncher.launch(instrumentation, "API Demos"); + + UiScrollable itemList = + new UiScrollable(new UiSelector().resourceId(Res.ANDROID_LIST_RES)); + itemList.setAsVerticalList(); + Assert.assertTrue("Could not list items", itemList.exists()); + + UiObject appItem = itemList.getChildByText( + new UiSelector().className("android.widget.TextView"), "App"); + appItem.waitForExists(TimeUnit.SECONDS.toMillis(6L)); + if (appItem.exists()) { + appItem.click(); + } + UiObject deviceAdminItem = itemList.getChildByText( + new UiSelector().className("android.widget.TextView"), "Device Admin"); + deviceAdminItem.waitForExists(TimeUnit.SECONDS.toMillis(6L)); + if (deviceAdminItem.exists()) { + deviceAdminItem.click(); + } + UiObject passwordQualityItem = itemList.getChildByText( + new UiSelector().className("android.widget.TextView"), "Password quality"); + passwordQualityItem.waitForExists(TimeUnit.SECONDS.toMillis(6L)); + if (passwordQualityItem.exists()) { + passwordQualityItem.click(); + } + passwordQualityItem = itemList.getChildByText( + new UiSelector().className("android.widget.RelativeLayout"), "Password quality"); + passwordQualityItem.waitForExists(TimeUnit.SECONDS.toMillis(6L)); + if (passwordQualityItem.exists()) { + passwordQualityItem.click(); + } + + // Set the criteria for password to 'Complex' type. + device.findObject(new UiSelector().text("Complex")).clickAndWaitForNewWindow(); + + // Set minimum length to 6. + ApiDemosTestUtil.setPasswordCriteria("Minimum length", "6", device); + + // Set minimum letters to 1. + ApiDemosTestUtil.setPasswordCriteria("Minimum letters", "1", device); + + // Set minimum numerics to 1. + ApiDemosTestUtil.setPasswordCriteria("Minimum numeric", "1", device); + + // Set minimum lower case letters to 1. + ApiDemosTestUtil.setPasswordCriteria("Minimum lower case", "1", device); + + // Set minimum upper case letters to 1. + ApiDemosTestUtil.setPasswordCriteria("Minimum upper case", "1", device); + + // Set minimum special symbols to 1. + ApiDemosTestUtil.setPasswordCriteria("Minimum symbols", "1", device); + + // Set minimum non-letter to 1. + ApiDemosTestUtil.setPasswordCriteria("Minimum non-letter", "1", device); + + //Verify that setting the password meets the "PASSWORD QUALITY" criteria. + ApiDemosTestUtil.verifyPasswordQuality(instrumentation, device, "Security", "NEXT"); + } + + @After + public void restoreState() throws Exception{ + //Deactivate "Device Admin" to restore the state. + SettingsUtil.deactivate(instrumentation, "Sample Device Admin", "Security", "Device admin apps"); + } +} diff --git a/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/AppTest.java b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/AppTest.java new file mode 100644 index 00000000..c893f58d --- /dev/null +++ b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/AppTest.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.devtools.systemimage.uitest.smoke.api33; + +import static org.junit.Assert.assertTrue; + +import android.app.Instrumentation; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiSelector; +import android.util.Log; + +import com.android.devtools.systemimage.uitest.annotations.TestInfo; +import com.android.devtools.systemimage.uitest.common.Res; +import com.android.devtools.systemimage.uitest.framework.SystemImageTestFramework; +import com.android.devtools.systemimage.uitest.utils.AppLauncher; +import com.android.devtools.systemimage.uitest.utils.GoogleAppUtil; +import com.android.devtools.systemimage.uitest.utils.PackageInstallationUtil; +import com.android.devtools.systemimage.uitest.utils.Wait; +import com.android.devtools.systemimage.uitest.watchers.AppWatcher; +import com.android.devtools.systemimage.uitest.watchers.watcher; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; + +import java.util.concurrent.TimeUnit; + +/** + * Test for app interactions. + */ +@RunWith(AndroidJUnit4.class) +public class AppTest { + @Rule + public final SystemImageTestFramework testFramework = new SystemImageTestFramework(); + + @Rule + public Timeout globalTimeout = Timeout.seconds(360); + + /** + * Verifies an app runs on the emulator. + * <p/> + * The test installs, launches, and uninstalls the app. + * <p/> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p/> + * TR ID: C14578823 + * <p/> + * <pre> + * Test Steps: + * 1. Start the emulator. + * 2. Install BasicRenderScript app. + * 3. Open the app. + * Verify: + * App runs on the emulator. Image of a leaf is displayed on the emulator. + * </pre> + * <p/> + */ + @Test + @TestInfo(id = "14578823") + public void installAppAndLaunch() throws Exception { + Instrumentation instrumentation = testFramework.getInstrumentation(); + UiDevice device = UiDevice.getInstance(instrumentation); + String testPackageName = "com.example.android.basicrenderscript"; + String apk = "BasicRenderScript.apk"; + String appName = "BasicRenderScript"; + String result = ""; + + // Install BasicRenderScript, if not already present. + boolean isBasicRenderScriptInstalled = PackageInstallationUtil. + isPackageInstalled_V2(instrumentation, appName); + + + if (!isBasicRenderScriptInstalled) { + device.pressHome(); + result = PackageInstallationUtil.installApk(instrumentation, apk, false); + new AppWatcher(device).checkForCondition(); + isBasicRenderScriptInstalled = PackageInstallationUtil. + isPackageInstalled(instrumentation, testPackageName); + } + + assertTrue("Application " + apk + " is not installed. Result: " + result, + isBasicRenderScriptInstalled); + + AppLauncher.launch(instrumentation, appName); + new AppWatcher(device).checkForCondition(); + boolean hasApplication = testFramework.getDevice().findObject(new UiSelector().text( + "BasicRenderScript")).waitForExists(5L); + + assertTrue("Application " + appName + " did not launch", hasApplication); + } + + /** + * Verify website is bookmarked. + * <p/> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p/> + * TR ID: C14578831 + * <p/> + * <pre> + * 1. Launch emulator. + * 2. Open Chrome. + * 3. Tap on the address bar and enter espn.com + * 4. Open menu (3 vertical dots). + * 5. Tap on "Save to bookmarks" and tap OK. + * 6. Assert message that bookmark is added. + * 7. Open menu (3 vertical dots). + * 8. Tap on "Bookmarks" + * Verify: + * Website is bookmarked. + * </pre> + */ + @Test + @TestInfo(id = "14578831") + public void bookmarkWebSiteInBrowser() throws Exception { + Instrumentation instrumentation = testFramework.getInstrumentation(); + final UiDevice device = UiDevice.getInstance(instrumentation); + + if (testFramework.isGoogleApiImage() || testFramework.isGoogleApiAndPlayImage()) { + GoogleAppUtil.loginGoogleApp(instrumentation, true); + AppLauncher.launch(instrumentation, "Chrome"); + + // Click the search box if it's there. + UiObject searchBox = device.findObject(new UiSelector().resourceId( + Res.CHROME_SEARCH_BOX_RES)); + if (searchBox.waitForExists(TimeUnit.SECONDS.toMillis(3))) { + searchBox.clickAndWaitForNewWindow(); + } + + new watcher(device, Res.APP_WATCHER_PATTERN).checkForCondition(); + + UiObject textField = device.findObject( + new UiSelector().resourceId(Res.CHROME_URL_BAR_RES)); + if (textField.waitForExists(TimeUnit.SECONDS.toMillis(15))) { + textField.click(); + textField.clearTextField(); + // Include a timestamp in the URL so it's not already bookmarked. (On Chrome, the UI + // changes in that case.) + textField.setText("http://espn.com"); + device.pressEnter(); + device.pressMenu(); + } + + UiObject editBookmarkImage = device.findObject(new UiSelector() + .description("Edit bookmark").className("android.widget.ImageButton")); + boolean isBookmarked = new Wait().until(editBookmarkImage::exists); + if (!isBookmarked) { + UiObject setBookmarkImage = device.findObject(new UiSelector() + .description("Bookmark").className("android.widget.ImageButton")); + setBookmarkImage.click(); + new watcher(device, Res.APP_WATCHER_PATTERN).checkForCondition(); + device.pressMenu(); + } + // After bookmarking, the button description changes. + isBookmarked = editBookmarkImage.waitForExists(TimeUnit.SECONDS.toMillis(15)); + assertTrue("Bookmark was not set", isBookmarked); + + UiObject bookmarks = device.findObject(new UiSelector().text("Bookmarks")); + bookmarks.waitForExists(TimeUnit.SECONDS.toMillis(15)); + if (bookmarks.exists()) { + bookmarks.clickAndWaitForNewWindow(); + } + + String TAG = "AppTest"; + Log.d(TAG, "The bookmark is set"); + + UiObject mobileBookmarks = device.findObject(new UiSelector().text("Mobile bookmarks") + .resourceId(Res.CHROME_TITLE_RES)); + mobileBookmarks.waitForExists(TimeUnit.SECONDS.toMillis(15)); + if (mobileBookmarks.exists()) { + mobileBookmarks.clickAndWaitForNewWindow(); + } + + Log.d(TAG, "Searching for bookmark..."); + final UiObject bookmarkedSite = device.findObject(new UiSelector().textContains("ESPN")); + + assertTrue("Cannot find bookmark", + new Wait().until(() -> device.findObject( + new UiSelector().textContains(("kmarks"))).exists() && + bookmarkedSite.exists()) + ); + + bookmarkedSite.dragTo(bookmarkedSite,20); + + final UiObject trashCan = device.findObject(new UiSelector(). + description("Delete bookmarks")); + // Delete the bookmark. + assertTrue("Cannot find trash", + new Wait().until(trashCan::exists) + ); + + trashCan.click(); + } + } +} diff --git a/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/CameraTest.java b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/CameraTest.java new file mode 100644 index 00000000..dc7ca5fe --- /dev/null +++ b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/CameraTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.devtools.systemimage.uitest.smoke.api33; + +import static org.junit.Assert.assertTrue; + +import android.app.Instrumentation; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiSelector; + +import com.android.devtools.systemimage.uitest.annotations.TestInfo; +import com.android.devtools.systemimage.uitest.common.Res; +import com.android.devtools.systemimage.uitest.framework.SystemImageTestFramework; +import com.android.devtools.systemimage.uitest.utils.AppLauncher; +import com.android.devtools.systemimage.uitest.utils.CameraTestUtil; +import com.android.devtools.systemimage.uitest.utils.Wait; +import com.android.devtools.systemimage.uitest.watchers.watcher; + +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; + +/** + * Test on shell utility. + */ +@RunWith(AndroidJUnit4.class) +public class CameraTest { + @Rule + public final SystemImageTestFramework testFramework = new SystemImageTestFramework(); + @Rule + public Timeout globalTimeout = Timeout.seconds(240); + /** + * Tests the photo capture functionality of the camera application. + * <p> + * TT ID: ab5f9585-433b-4261-bd15-5c7136f6127b + * <p> + * <pre> + * Test Steps: + * 1. Start the emulator. + * 2. Open the Camera application. + * 3. Take a photo. + * 4. Delete the photo. + * 5. Get list of files stored in the Gallery. + * 6. Reopen the Camera application. + * 7. Take another photo. + * 8. Get an updated list of files stored in the Gallery. + * 9. Delete the photo. + * 10. Get a final list of files stored in the Gallery. + * Verify: + * 1. Confirm that after taking a photo, the current file list does not match the original file list, + * and contains a file with a .jpg extension. + * 2. Confirm that after deleting the photo, the final file list match the original file list. + */ + @Test + @TestInfo(id = "ab5f9585-433b-4261-bd15-5c7136f6127b") + public void testPhotoCapture() throws Exception { + Instrumentation instrumentation = testFramework.getInstrumentation(); + boolean photoTestSuccess = CameraTestUtil.useCamera(instrumentation, "Images", 3); + Assert.assertTrue("New photo was not deleted from the gallery", photoTestSuccess); + } + /** + * Tests the video capture functionality of the camera application. + * <p> + * TT ID: ab5f9585-433b-4261-bd15-5c7136f6127b + * <p> + * <pre> + * Test Steps: + * 1. Start the emulator. + * 2. Open the Camera application and set to Video. + * 3. Take a video. + * 4. Delete the video. + * 5. Get list of files stored in the Gallery. + * 6. Reopen the Camera application. + * 7. Take another video. + * 8. Get an updated list of files stored in the Gallery. + * 9. Delete the video. + * 10. Get a final list of files stored in the Gallery. + * Verify: + * 1. Confirm that after taking a video, the current file list does not match the original video list, + * and contains a file with a .mp4 extension. + * 2. Confirm that after deleting the video, the final file list match the original video list. + */ + @Test + @TestInfo(id = "ab5f9585-433b-4261-bd15-5c7136f6127b") + public void testVideoCapture() throws Exception { + Instrumentation instrumentation = testFramework.getInstrumentation(); + boolean videoTestSuccess = CameraTestUtil.useCamera(instrumentation, "Videos", 3); + Assert.assertTrue("New video was not deleted from the gallery", videoTestSuccess); + } + /** + * Verifies that the augmented reality application can be installed and launched + * <p> + * TT ID: 61ba18b5-cfba-46a7-a3f2-abfc60e40303 + * <p> + * <pre> + * Test Steps: + * 1. Start the emulator. + * 2. Check if AR application is installed, and install if not found. + * 3. Open the AR application. + * Verify: + * Confirm that the application launches, and the target text is displayed + */ + @Test + @TestInfo(id = "61ba18b5-cfba-46a7-a3f2-abfc60e40303") + public void launchARApp() throws Exception { + Instrumentation instrumentation = testFramework.getInstrumentation(); + final UiDevice device = testFramework.getDevice(); + if (!(testFramework.isGoogleApiImage()) || testFramework.isGoogleApiAndPlayImage()) { + return; + } + String appName = "HelloAR C"; + AppLauncher.launchPath(instrumentation, true, new String[]{appName}); + new watcher(device, Res.CAMERA_ACCESS_PERM_WATCHER_PATTERN).checkForCondition(); + assertTrue("'Searching for surfaces...' text is not visible", + new Wait().until(new Wait.ExpectedCondition() { + @Override + public boolean isTrue() { + return device.findObject(new UiSelector().resourceId( + Res.GOOGLE_AR_SNACKBAR_RES).text("Searching for surfaces...")).exists(); + } + }) + ); + } +} diff --git a/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/GoogleServicesTest.java b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/GoogleServicesTest.java new file mode 100644 index 00000000..1a24c6c0 --- /dev/null +++ b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/GoogleServicesTest.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.devtools.systemimage.uitest.smoke.api33; + +import static org.junit.Assert.assertTrue; + +import android.app.Instrumentation; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiScrollable; +import android.support.test.uiautomator.UiSelector; + +import com.android.devtools.systemimage.uitest.annotations.TestInfo; +import com.android.devtools.systemimage.uitest.common.Res; +import com.android.devtools.systemimage.uitest.framework.SystemImageTestFramework; +import com.android.devtools.systemimage.uitest.utils.AppLauncher; +import com.android.devtools.systemimage.uitest.utils.AppManager; +import com.android.devtools.systemimage.uitest.utils.GoogleAppUtil; +import com.android.devtools.systemimage.uitest.watchers.watcher; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Test to verify that Google services are available on Google API images + */ + +@RunWith(AndroidJUnit4.class) +public class GoogleServicesTest { + private static final String WIDGET_TEXT_VIEW_CLASS = "android.widget.TextView"; + + @Rule + public final SystemImageTestFramework testFramework = new SystemImageTestFramework(); + + /** + * Verifies that Google services are available on Google API images + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TR ID: C14578827 + * <p> + * <pre> + * Test Steps: + * 1. Start an emulator AVD targeting Google Add On image. + * 2. Open Settings > Apps. + * 3. From the Overflow menu, select "Show system". + * 4. Scroll through the list. + * Verify: + * Google Play Services, Google Services Framework and Maps + * applications are present. + * </pre> + */ + @Test + @TestInfo(id = "14578827") + public void verifyGoogleApps() throws Exception{ + Instrumentation instrumentation = testFramework.getInstrumentation(); + + if (!testFramework.isGoogleApiImage() || !testFramework.isGoogleApiAndPlayImage()) { + return; + } + + AppManager.openAppList_v3(instrumentation); + AppManager.openSystemAppList_v2(instrumentation); + + UiScrollable appList= + new UiScrollable(new UiSelector().resourceIdMatches(Res.SETTINGS_LIST_CONTAINER_RES)); + appList.setAsVerticalList(); + + assertTrue("Cannot find Gmail", appList.getChildByText( + new UiSelector().className(WIDGET_TEXT_VIEW_CLASS), + "Gmail").exists()); + assertTrue("Cannot find Google", appList.getChildByText( + new UiSelector().className(WIDGET_TEXT_VIEW_CLASS), + "Google").exists()); + assertTrue("Cannot find Google Play services", appList.getChildByText( + new UiSelector().className(WIDGET_TEXT_VIEW_CLASS), + "Google Play services").exists()); + assertTrue("Cannot find Google Play Store", appList.getChildByText( + new UiSelector().className(WIDGET_TEXT_VIEW_CLASS), + "Google Play Store").exists()); + assertTrue("Cannot find Maps", appList.getChildByText( + new UiSelector().className(WIDGET_TEXT_VIEW_CLASS), + "Maps").exists()); + } + + /** + * Verify the contents of the Location Settings page + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TR ID: C14578827 + * <p> + * <pre> + * Test Steps: + * 1. Start an emulator AVD targeting Google Add On image + * 2. Open Settings > Location + * Verify: + * Location enable toggle button. + * </pre> + */ + @Test + @TestInfo(id = "14578827") + public void verifyLocationSettings() throws Exception { + Instrumentation instrumentation = testFramework.getInstrumentation(); + UiDevice device = UiDevice.getInstance(instrumentation); + + // Open settings + AppLauncher.launch(instrumentation, "Settings"); + new watcher(device, Res.ADD_GOOGLE_ACC_WATCHER_PATTERN).checkForCondition(); + + //Dismiss Set Up Wizard. + UiObject cancelWizard = device.findObject( + new UiSelector().resourceIdMatches(Res.CANCEL_SETUP_WIZARD_RES)); + + if (cancelWizard.waitForExists(5L)) { + cancelWizard.clickAndWaitForNewWindow(); + } + + //Defer until later today. + UiObject deferUntilLater = device.findObject( + new UiSelector().resourceIdMatches(Res.DEFERRED_SNOOZE_ITEM_RES).index(0)); + + if (deferUntilLater.waitForExists(5L)) { + deferUntilLater.clickAndWaitForNewWindow(); + } + + // Find and click "Location" in Settings + UiScrollable itemList = + new UiScrollable( + new UiSelector().resourceIdMatches(Res.SETTINGS_LIST_CONTAINER_RES) + ); + + if (itemList.waitForExists(3L)) { + itemList.setAsVerticalList(); + } + + String securityLabel = "Location"; + UiObject security = itemList.getChildByText(new UiSelector().className("android.widget.TextView"), + securityLabel); + + if (security.waitForExists(3L)) { + security.clickAndWaitForNewWindow(); + } + + assertTrue("Cannot find location toggle button", + device.findObject(new UiSelector().resourceIdMatches(Res.ANDROID_SWITCH_TEXT_RES) + .text("Use location")).waitForExists(5L)); + } + + /** + * Logs the user into Google Chrome app. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TR ID: d7f5673a-a3d0-4f50-856a-dfa10ce5c21c + * <p> + * <pre> + * Test Steps: + * 1. Start an emulator with API 24+ Google APIs support. + * 2. Launch Chrome. + * 3. Log out of Chrome, if logged in already. + * 4. Log into Chrome using the test account. + * 5. Open the Chrome menu > Settings. + * 6. Find logged user name. + * 7. Log user out of Chrome. + * Verify: + * 1. Logging into Chrome was successful. + * 2. Logging out of Chrome was successful. + * </pre> + */ + @Test + @TestInfo(id = "d7f5673a-a3d0-4f50-856a-dfa10ce5c21c") + public void loginGoogleChrome() throws Exception { + Instrumentation instrumentation = testFramework.getInstrumentation(); + + GoogleAppUtil.logoutGoogleChrome(instrumentation); + + boolean logInSuccess = GoogleAppUtil.loginGoogleApp(instrumentation, true); + assertTrue("Google log in was unsuccessful", logInSuccess); + + boolean logOutSuccess = GoogleAppUtil.logoutGoogleChrome(instrumentation); + assertTrue("Google log out was unsuccessful", logOutSuccess); + } +} diff --git a/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/MapsTest.java b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/MapsTest.java new file mode 100644 index 00000000..31ff374b --- /dev/null +++ b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/MapsTest.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.devtools.systemimage.uitest.smoke.api33; + +import static org.junit.Assert.assertTrue; + +import android.app.Instrumentation; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiSelector; +import android.view.KeyEvent; +import android.widget.EditText; +import android.widget.TextView; + +import com.android.devtools.systemimage.uitest.annotations.TestInfo; +import com.android.devtools.systemimage.uitest.common.Res; +import com.android.devtools.systemimage.uitest.framework.SystemImageTestFramework; +import com.android.devtools.systemimage.uitest.utils.AppLauncher; +import com.android.devtools.systemimage.uitest.utils.Wait; +import com.android.devtools.systemimage.uitest.watchers.watcher; + +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.concurrent.TimeUnit; + +/** + * Sanity test for Maps App + */ + +@RunWith(AndroidJUnit4.class) +public class MapsTest { + private static final String QUERY_STRING = "San Francisco"; + + @Rule + public final SystemImageTestFramework testFramework = new SystemImageTestFramework(); + + /** + * Verify the functionality of navigation overview in Google Maps app. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TT ID: 4578f63f-7d2e-4e5e-a4e0-0ce2ae67982e + * <p> + * <pre> + * Test Steps: + * 1. Launch emulator avd. + * 2. Open Maps app. + * 3. Accept terms and condition. + * 4. Tap on search bar. + * 5. Enter search query, "San Francisco", select it from the auto fill results. + * 6. "San Francisco" location card opens. + * 7. Select "San Francisco". + * 8. Tap on the Drive icon. + * Verify: + * 1. Map points to San Francisco location. + * 2. Navigation overview is displayed. + * </pre> + */ + @Test + @TestInfo(id = "4578f63f-7d2e-4e5e-a4e0-0ce2ae67982e") + public void testMapsApp() throws Exception { + Instrumentation instrumentation = testFramework.getInstrumentation(); + UiDevice mDevice = testFramework.getDevice(); + + if (testFramework.isGoogleApiImage() || testFramework.isGoogleApiAndPlayImage()) { + AppLauncher.launch(instrumentation, "Maps"); + + new watcher(mDevice, Res.MAPS_WATCHER_PATTERN).checkForCondition(); + + final UiObject searchUiObject = mDevice.findObject(new UiSelector(). + resourceIdMatches(Res.SEARCH_TEXT_BOX)); + assertTrue("Failed to find search text box", new Wait(5L).until(new Wait.ExpectedCondition() { + @Override + public boolean isTrue() { + return searchUiObject.exists(); + } + })); + + searchUiObject.clickAndWaitForNewWindow(); + UiObject searchEditText = searchUiObject.getChild( + new UiSelector().className(EditText.class.getName())); + searchEditText.setText(QUERY_STRING); + mDevice.pressKeyCode(KeyEvent.KEYCODE_ENTER); + + // Verify the Query String is present after completing search. + final UiObject searchTextView = + searchUiObject.getChild(new UiSelector().className(TextView.class.getName())); + + boolean hasSearchText = new Wait(TimeUnit.MILLISECONDS.convert(10L, TimeUnit.SECONDS)). + until(() -> searchTextView.waitForExists(10L)); + + if (hasSearchText) { + Assert.assertTrue("Search string " + QUERY_STRING + " not found.", + searchTextView.getText().contains(QUERY_STRING)); + } + + // Verify the directions/route link exists and clicking on it opens the directions page + // verify query string is pre filled in the destination("to") field. + UiObject directions; + boolean isSuccess = mDevice.findObject(new UiSelector().descriptionMatches(".*Directions.*|.*Route.*")) + .waitForExists(TimeUnit.MILLISECONDS.convert(3L, TimeUnit.SECONDS)); + + if (isSuccess) { + directions = mDevice.findObject(new UiSelector().descriptionMatches(".*Directions.*|.*Route.*")); + } else { + directions = mDevice.findObject(new UiSelector().text("DIRECTIONS")); + } + Assert.assertTrue(directions.exists()); + directions.clickAndWaitForNewWindow(); + + UiObject destination = mDevice.findObject(new UiSelector().textContains(QUERY_STRING)); + new watcher(mDevice, Res.MAPS_WATCHER_PATTERN).checkForCondition(); + + Assert.assertTrue(destination.exists()); + + for (int i = 0; i < 5; i++) { + mDevice.pressBack(); + } + } + } +} diff --git a/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/NetworkIOTest.java b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/NetworkIOTest.java new file mode 100644 index 00000000..b11a8fa4 --- /dev/null +++ b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/NetworkIOTest.java @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.devtools.systemimage.uitest.smoke.api33; + +import android.app.Instrumentation; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiObjectNotFoundException; +import android.support.test.uiautomator.UiScrollable; +import android.support.test.uiautomator.UiSelector; + +import com.android.devtools.systemimage.uitest.annotations.TestInfo; +import com.android.devtools.systemimage.uitest.common.Res; +import com.android.devtools.systemimage.uitest.framework.SystemImageTestFramework; +import com.android.devtools.systemimage.uitest.utils.AppLauncher; +import com.android.devtools.systemimage.uitest.utils.NetworkIOTestUtil; +import com.android.devtools.systemimage.uitest.utils.NetworkUtil; +import com.android.devtools.systemimage.uitest.utils.Wait; + +import junit.framework.Assert; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; + +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * Test class for network connection on emulator. + */ +@RunWith(AndroidJUnit4.class) +public class NetworkIOTest { + @Rule + public final SystemImageTestFramework testFramework = new SystemImageTestFramework(); + + @Rule + public Timeout globalTimeout = Timeout.seconds(1000); + + /** + * Verifies test browser successfully loads a web page. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TR ID: C14578825 + * <p> + * <pre> + * Test Steps: + * 1. Start the emulator. + * 2. Launch browser app. + * 3. Navigate to a website. + * Verify: + * Icons indicating working network connection displayed in status bar. + * Browser successfully loads the web page. + * </pre> + */ + @Test + @TestInfo(id = "14578825") + public void testBrowserLoadsSite() throws Exception { + Instrumentation instrumentation = testFramework.getInstrumentation(); + UiDevice device = testFramework.getDevice(); + + // Check network connectivity. + if (NetworkUtil.hasCellularNetworkConnection(instrumentation)) { + if (testFramework.isGoogleApiImage() || testFramework.isGoogleApiAndPlayImage()) { + device.openNotification(); + UiObject internetTile = device.findObject(new UiSelector().resourceId( + Res.NOTIFICATIONS_TILE_LABEL).text("Internet")); + assertTrue("Could not connect to the network.", + new Wait().until(internetTile::exists)); + internetTile.click(); + UiObject connectWifiSummary = device.findObject(new UiSelector().resourceId( + Res.ANDROID_SUMMARY_RES).text("Connected")); + assertTrue("Could not connect to the network.", + new Wait().until(connectWifiSummary::exists)); + device.pressHome(); + + AppLauncher.launch(instrumentation, "Chrome"); + // If this is the first launch, dismiss the "Welcome to Chrome" screen. + UiObject acceptButton = device.findObject(new UiSelector().resourceId( + Res.CHROME_TERMS_ACCEPT_BUTTON_RES)); + if (acceptButton.exists()) { + acceptButton.clickAndWaitForNewWindow(); + } + + // Dismiss the "Sign in to Chrome" screen if it's there. + UiObject noThanksButton = device.findObject(new UiSelector().resourceIdMatches( + Res.CHROME_NO_THANKS_BUTTON_RES)); + if (noThanksButton.waitForExists(TimeUnit.SECONDS.toMillis(3))) { + noThanksButton.clickAndWaitForNewWindow(); + } + + UiObject searchBox = device.findObject(new UiSelector().resourceId( + Res.CHROME_SEARCH_BOX_RES)); + if (searchBox.exists()) { + searchBox.clickAndWaitForNewWindow(); + } + + final UiObject textField = device.findObject(new UiSelector().resourceId( + Res.CHROME_URL_BAR_RES)); + Assert.assertTrue("Chrome URL bar not found", + new Wait().until(textField::exists)); + + textField.click(); + textField.clearTextField(); + textField.setText("google.com"); + device.pressEnter(); + + // Verify if the load bar is there at first. Then verify if the loading bar + // finishes within the default timeout on Wait(). + final UiObject progress = + device.findObject(new UiSelector().resourceId(Res.CHROME_PROGRESS_BAR_RES)); + boolean isSuccess = + new Wait().until(() -> !progress.exists()); + assertTrue("Failed to dismiss the loading bar.", isSuccess); + } + } + } + + /** + * Verifies cellular data can be enabled and disabled. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TR ID: C14581152 + * <p> + * <pre> + * Test Steps: + * 1. Start the emulator. + * 2. Open Settings > Wireless and Networks > Data Usage + * 3. Check if 'Data warning & limit' is enabled, toggle Cellular data switch on if not. + * 4. Toggle Cellular data switch off. + * 5. Toggle Cellular data switch on. + * Verify: + * 1. Cellular data is turned off. + * 1. Cellular data is turned on. + * </pre> + * <p> + */ + @Test + @TestInfo(id = "14581152") + public void toggleCellularDataMode() throws Exception { + final Instrumentation instrumentation = testFramework.getInstrumentation(); + UiDevice device = UiDevice.getInstance(instrumentation); + + String[] path = new String[]{"Settings", "Network & internet", "SIMs"}; + AppLauncher.launchPath(instrumentation, true, path); + UiScrollable scrollable = new UiScrollable(new UiSelector().scrollable(true)); + final UiObject mobileData = device.findObject(new UiSelector().text("Mobile data")); + final UiObject dataWarning = device.findObject(new UiSelector().text("Data warning & limit")); + + assertTrue("Scrollable view not found", new Wait().until(scrollable::exists)); + try { + scrollable.scrollIntoView(mobileData); + } catch (UiObjectNotFoundException e) { + fail("Mobile data switch not found initially."); + } + + try { + scrollable.scrollIntoView(dataWarning); + if (!new Wait().until(dataWarning::isEnabled)) { + scrollable.scrollIntoView(mobileData); + mobileData.click(); + assertTrue("Data warning label cannot be enabled at the beginning.", + new Wait().until(dataWarning::isEnabled)); + } + } catch (UiObjectNotFoundException e) { + fail("Enabled data warning label not found at the end."); + } + + // Disable Cellular data. + try { + scrollable.scrollIntoView(mobileData); + mobileData.click(); + scrollable.scrollIntoView(dataWarning); + assertFalse("Data warning label cannot be disabled.", + new Wait().until(dataWarning::isEnabled)); + TimeUnit.SECONDS.sleep(3); // Require a sleep to avoid flakiness on buildbot. + } catch (UiObjectNotFoundException e) { + fail("Disabled data warning label not found."); + } + + // Enable Cellular data. + try { + scrollable.scrollIntoView(mobileData); + mobileData.click(); + scrollable.scrollIntoView(dataWarning); + assertTrue("Data warning label cannot be enabled at the end", + new Wait().until(dataWarning::isEnabled)); + TimeUnit.SECONDS.sleep(3); // Require a sleep to avoid flakiness on buildbot. + } catch (UiObjectNotFoundException e) { + fail("Disabled data warning label not found at the end."); + } + + } + + /** + * Verifies enabling airplane mode + * <pre> + * Test Steps: + * 1. Start the emulator. + * 2. Open Settings + * 3. Locate Airplane mode toggle switch. + * 4. Toggle Airplane mode on. + * Verify: + * Airplane mode icon is present and enabled in notification tray + * 5. Toggle Airplane mode off. + * </pre> + * <p> + */ + @Test + @TestInfo(id = "14581152") + public void enableAirplaneMode() throws Exception { + final Instrumentation instrumentation = testFramework.getInstrumentation(); + UiDevice device = UiDevice.getInstance(instrumentation); + + String[] path = new String[]{"Settings", "Network & internet"}; + AppLauncher.launchPath(instrumentation, true, path); + + UiObject airplaneModeIcon = NetworkUtil.getAirplaneModeIcon_v3(device); + + // Test requires "Airplane mode" switch widget to start in the off state. + if (NetworkUtil.isAirplaneModeEnabled_v3(device, airplaneModeIcon)) { + AppLauncher.launchPath(instrumentation, true, path); + NetworkIOTestUtil.toggleAirplaneMode(device); + } + assertFalse("Airplane mode is not disabled.", + NetworkUtil.isAirplaneModeEnabled_v3(device, airplaneModeIcon)); + + AppLauncher.launchPath(instrumentation, true, path); + NetworkIOTestUtil.toggleAirplaneMode(device); + assertTrue("Airplane mode is not enabled.", + NetworkUtil.isAirplaneModeEnabled_v3(device, airplaneModeIcon)); + + // Disable airplane mode. + AppLauncher.launchPath(instrumentation, true, path); + NetworkIOTestUtil.toggleAirplaneMode(device); + } + + /** + * Verifies repeatedly enabling and disabling airplane mode + * <pre> + * Test Steps: + * 1. Start the emulator. + * 2. Open Settings + * 3. Locate Airplane mode toggle switch. + * 4. Toggle Airplane mode on. + * Verify: + * Airplane mode icon is present and enabled in notification tray + * 5. Toggle Airplane mode off. + * 6 Repeat steps 3-6 four more times. + * </pre> + * <p> + */ + @Test + @TestInfo(id = "14581152") + public void stressTestAirplaneMode() throws Exception { + final Instrumentation instrumentation = testFramework.getInstrumentation(); + UiDevice device = UiDevice.getInstance(instrumentation); + int stressCount = 4; + + String[] path = new String[]{"Settings", "Network & internet"}; + AppLauncher.launchPath(instrumentation, true, path); + + UiObject airplaneModeIcon = NetworkUtil.getAirplaneModeIcon_v3(device); + + // Test requires "Airplane mode" switch widget to start in the off state. + if (NetworkUtil.isAirplaneModeEnabled_v3(device, airplaneModeIcon)) { + AppLauncher.launchPath(instrumentation, true, path); + NetworkIOTestUtil.toggleAirplaneMode(device); + } + assertFalse("Airplane mode is not disabled.", + NetworkUtil.isAirplaneModeEnabled_v2(device, airplaneModeIcon)); + + for (int i = 0; i < stressCount; i++) { + AppLauncher.launchPath(instrumentation, true, path); + NetworkIOTestUtil.toggleAirplaneMode(device); + assertTrue("Airplane mode is not enabled.", + NetworkUtil.isAirplaneModeEnabled_v3(device, airplaneModeIcon)); + + // Disable airplane mode. + AppLauncher.launchPath(instrumentation, true, path); + NetworkIOTestUtil.toggleAirplaneMode(device); + + assertFalse("Airplane mode is not disabled.", + NetworkUtil.isAirplaneModeEnabled_v3(device, airplaneModeIcon)); + } + } + + /** + * Verifies setting Preferred Network Type + * <pre> + * Test Steps: + * 1. Start the emulator. + * 2. Open Settings > Network & internet > SIMs > Preferred Network Type + * 3. Enable LTE Data mode, if not enabled. + * 4. Enable 3G Data mode. + * 5. Enable 2G Data mode. + * 6. Re-enable LTE Data mode. + * Verify: + * 1. LTE is set as preferred network type. + * 2. 3G is set as preferred network type. + * 3. 2G is set as preferred network type. + * </pre> + * <p> + */ + @Test + @TestInfo(id = "14581152") + public void togglePreferredNetworkType() throws Exception { + final Instrumentation instrumentation = testFramework.getInstrumentation(); + UiDevice device = UiDevice.getInstance(instrumentation); + + String[] path = new String[]{"Settings", "Network & internet", "SIMs", "Preferred network type"}; + AppLauncher.launchPath(instrumentation, true, path); + + UiObject dataSwitchLTE = device.findObject(new UiSelector().text("LTE (recommended)")); + UiObject dataSwitch3G = device.findObject(new UiSelector().text("3G")); + UiObject dataSwitch2G = device.findObject(new UiSelector().text("2G")); + + if (dataSwitchLTE.waitForExists(5L)) { + if (!dataSwitchLTE.isChecked()) { + dataSwitchLTE.clickAndWaitForNewWindow(5L); + } else { + device.pressBack(); + } + } + assertTrue("LTE data mode is not enabled.", new Wait().until(dataSwitchLTE::exists)); + AppLauncher.launchPath(instrumentation, true, path); + + if (dataSwitch3G.waitForExists(5L)) { + if (!dataSwitch3G.isChecked()) { + dataSwitch3G.clickAndWaitForNewWindow(5L); + } else { + device.pressBack(); + } + } + assertTrue("3G data mode is not enabled.", new Wait().until(dataSwitch3G::exists)); + AppLauncher.launchPath(instrumentation, true, path); + + if (dataSwitch2G.waitForExists(5L)) { + if (!dataSwitch2G.isChecked()) { + dataSwitch2G.clickAndWaitForNewWindow(5L); + } + else { + device.pressBack(); + } + } + assertTrue("2G data mode is not enabled.", new Wait().until(dataSwitch2G::exists)); + AppLauncher.launchPath(instrumentation, true, path); + + if (dataSwitchLTE.waitForExists(5L)) { + if (!dataSwitchLTE.isChecked()) { + dataSwitchLTE.clickAndWaitForNewWindow(5L); + } else { + device.pressBack(); + } + } + assertTrue("LTE data mode is not re-enabled.", new Wait().until(dataSwitchLTE::exists)); + } +} diff --git a/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/PlayStoreTest.java b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/PlayStoreTest.java new file mode 100644 index 00000000..0a2df0d2 --- /dev/null +++ b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/PlayStoreTest.java @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.devtools.systemimage.uitest.smoke.api33; + +import android.app.Instrumentation; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiSelector; + +import com.android.devtools.systemimage.uitest.annotations.TestInfo; +import com.android.devtools.systemimage.uitest.common.Res; +import com.android.devtools.systemimage.uitest.framework.SystemImageTestFramework; +import com.android.devtools.systemimage.uitest.utils.AppLauncher; +import com.android.devtools.systemimage.uitest.utils.PlayStoreUtil; +import com.android.devtools.systemimage.uitest.utils.Wait; +import com.android.devtools.systemimage.uitest.watchers.GoogleAppConfirmationWatcher; +import com.android.devtools.systemimage.uitest.watchers.watcher; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; + +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Test to verify that Google services are available on Google API images + */ +@RunWith(AndroidJUnit4.class) +public class PlayStoreTest { + @Rule + public final SystemImageTestFramework testFramework = new SystemImageTestFramework(); + @Rule + public Timeout globalTimeout = Timeout.seconds(600); + private final String testApplication = "The Weather Channel"; + @Before + public void verifyPlayStore() throws Exception { + if (testFramework.isGoogleApiAndPlayImage()) { + Instrumentation instrumentation = testFramework.getInstrumentation(); + boolean playStoreInstalled = PlayStoreUtil.isPlayStoreInstalled_v2(instrumentation); + boolean loggedInToPlayStore = playStoreInstalled && + PlayStoreUtil.loginGooglePlay(instrumentation); + assertTrue("PlayStore login failed.", loggedInToPlayStore); + } + } + /** + * Verify apps can be searched through Play Store search bar. + * <p> + * TT ID: 50027a89-8043-44d7-b7ed-33c631903910 + * <p> + * <pre> + * Test Steps: + * 1. Start an emulator and launch home screen. + * 2. Open Apps. + * 3. Confirm that Play Store is present, then launch. + * 4. Search for an app name on the main Play Store screen. + * Verify: + * 1. Confirm that app name displays the search string. + * </pre> + */ + @Test + @TestInfo(id = "50027a89-8043-44d7-b7ed-33c631903910") + public void testPlaySearch() throws Exception { + if (testFramework.isGoogleApiAndPlayImage()) { + Instrumentation instrumentation = testFramework.getInstrumentation(); + final UiDevice device = UiDevice.getInstance(instrumentation); + assertTrue("Application not found in search.", + PlayStoreUtil.hasTestApp(instrumentation, testApplication)); + PlayStoreUtil.resetPlayStore(instrumentation); + device.pressHome(); + } + } + /** + * Verify that Google Play can install and uninstall a free app on the device. + * <p> + * TT ID: cb0ccd97-f045-42fa-8293-a32e94e838aa + * <p> + * <pre> + * Test Steps: + * 1. Start an emulator and launch home screen. + * 2. Open Apps drawer. + * 3. Confirm that Play Store is present, then launch. + * 4. Search for free app in store. + * 5. If app is available for install, begin installation. + * 6. Uninstall the app. + * Verify: + * 1a. If Install button was displayed, allow installation to complete then + * confirm that the Open button to launch the app is present. + * 1b. If Install button was not displayed, confirm that the Open button to + * launch the app is present. + * 2. Confirm that the app was subsequently uninstalled. + * </pre> + */ + @Test + @TestInfo(id = "cb0ccd97-f045-42fa-8293-a32e94e838aa") + public void testAppInstallation() throws Exception { + if (testFramework.isGoogleApiAndPlayImage()) { + Instrumentation instrumentation = testFramework.getInstrumentation(); + final UiDevice device = UiDevice.getInstance(instrumentation); + PlayStoreUtil.selectApplication(instrumentation, testApplication); + new GoogleAppConfirmationWatcher(device).checkForCondition(); + boolean isApplicationInstalled = PlayStoreUtil.installApplication(instrumentation); + assertTrue("Unable to install the application from Google Play", + isApplicationInstalled); + AppLauncher.launch(instrumentation, "Play Store"); + assertTrue("Unable to uninstall the application from Google Play", + PlayStoreUtil.uninstallApplication(instrumentation)); + PlayStoreUtil.resetPlayStore(instrumentation); + device.pressHome(); + } + } + /** + * Verify that Google Play can install and launch an app, then uninstall the app on the device. + * <p> + * TT ID: 924a0428-4e07-4794-b6a7-2c9d407204aa + * <p> + * <pre> + * Test Steps: + * 1. Start an emulator and launch home screen. + * 2. Open Apps. + * 3. Confirm that Play Store is present, then launch. + * 5. Search for free app in store. + * 6. If app is available for install, begin installation. + * 7. Launch the application. + * 8. Close and uninstall the app. + * Verify: + * 1a. If Install button was displayed, allow installation to complete then + * confirm that the Open button to launch the app is present. + * 1b. If Install button was not displayed, confirm that the Open button to + * launch the app is present. + * 2. Confirm that application launch was successful. + * 3. Confirm that the app was subsequently uninstalled. + * </pre> + */ + @Test + @TestInfo(id = "924a0428-4e07-4794-b6a7-2c9d407204aa") + public void testAppInstallationAndLaunch() throws Exception { + if (testFramework.isGoogleApiAndPlayImage()) { + Instrumentation instrumentation = testFramework.getInstrumentation(); + final UiDevice device = UiDevice.getInstance(instrumentation); + PlayStoreUtil.selectApplication(instrumentation, testApplication); + new GoogleAppConfirmationWatcher(device).checkForCondition(); + boolean isApplicationInstalled = PlayStoreUtil.installApplication(instrumentation); + assertTrue("Unable to install the application from Google Play", + isApplicationInstalled); + + UiObject openButton = device.findObject(new UiSelector() + .className("android.view.View") + .packageName("com.android.vending") + .description("Open")); + openButton.clickAndWaitForNewWindow(); + assertTrue("App could not be opened", + new Wait(TimeUnit.MILLISECONDS.convert(20L, TimeUnit.SECONDS)) + .until(() -> device.findObject(new UiSelector() + .packageName("com.weather.Weather")).exists())); + + AppLauncher.launch(instrumentation, "Play Store"); + assertTrue("Unable to uninstall the application from Google Play", + PlayStoreUtil.uninstallApplication(instrumentation)); + PlayStoreUtil.resetPlayStore(instrumentation); + device.pressHome(); + } + } + /** + * Verify that Google Play can reach the payment method prompt during paid app installation + * <p> + * TT ID: bd9460a8-7b07-4cfc-901f-a99564533e51 + * <p> + * <pre> + * Test Steps: + * 1. Start an emulator and launch home screen. + * 2. Open Apps. + * 3. Confirm that Play Store is present, then launch. + * 4. Search for pay app in store. + * Verify: + * 1. Confirm that user is presented with a Pay Button with a $. + * </pre> + */ + @Test + @TestInfo(id = "bd9460a8-7b07-4cfc-901f-a99564533e51") + public void testPayAppVerification() throws Exception { + if (testFramework.isGoogleApiAndPlayImage()) { + Instrumentation instrumentation = testFramework.getInstrumentation(); + final UiDevice device = UiDevice.getInstance(instrumentation); + final String payApplication = "Bouncer"; + PlayStoreUtil.selectApplication(instrumentation, payApplication); + new GoogleAppConfirmationWatcher(device).checkForCondition(); + assertTrue("Target application is not a pay app", + device.findObject(new UiSelector() + .className("android.view.View") + .packageName(Res.GOOGLE_PLAY_VENDING_RES) + .descriptionContains("$")).waitForExists(10L)); + PlayStoreUtil.resetPlayStore(instrumentation); + device.pressHome(); + } + } + /** + * Verify that Google Play search can be limited through parental controls + * <p> + * TT ID: fe78dba5-a0f2-4acf-bcbb-10b1c15d3484 + * <p> + * <pre> + * Test Steps: + * 1. Start an emulator and launch home screen. + * 2. Open Apps. + * 3. Confirm that Play Store is present, then launch. + * 4. Search for adult app in Play Store, successfully. + * 5. Open Play Store settings. + * 6. Turn on Parental Controls. + * 7. Select restrictions for Apps and Games. + * 8. Set and confirm a content PIN. + * 9. Set controls to Everyone 10+. + * 10. Search for adult app and family app in Play Store, finding only family app. + * 11. Turn off Parental Controls. + * Verify: + * 1. Confirm that search returns adult version of app without parental controls set. + * 2. Confirm that search does not return adult version of app with parental controls set, + * but does return family version of app. + * </pre> + */ + @Test + @TestInfo(id = "fe78dba5-a0f2-4acf-bcbb-10b1c15d3484") + public void testParentalControls() throws Exception { + if (testFramework.isGoogleApiAndPlayImage()) { + final Instrumentation instrumentation = testFramework.getInstrumentation(); + final UiDevice device = UiDevice.getInstance(instrumentation); + final String restrictedApplication = "Reddit"; + assertTrue("Adult application is found in search.", + PlayStoreUtil.hasTestApp(instrumentation, restrictedApplication)); + device.pressBack(); + + new watcher(device, Res.GOOGLE_APP_CONF_WATCHER_PATTERN).checkForCondition(); + + PlayStoreUtil.setRestrictions(instrumentation, "Apps", "Everyone 10+"); + assertFalse("Adult application is not found in restricted search.", + PlayStoreUtil.hasTestApp(instrumentation, restrictedApplication)); + + device.pressBack(); + + assertTrue("Family application is found in restricted search.", + PlayStoreUtil.hasTestApp(instrumentation, testApplication)); + + device.pressBack(); + PlayStoreUtil.toggleParentalControls(device, false); + device.pressHome(); + } + } +} diff --git a/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/SettingsTest.java b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/SettingsTest.java new file mode 100644 index 00000000..9ad20484 --- /dev/null +++ b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/SettingsTest.java @@ -0,0 +1,854 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.devtools.systemimage.uitest.smoke.api33; + +import android.app.Instrumentation; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiScrollable; +import android.support.test.uiautomator.UiSelector; +import android.util.Log; +import android.widget.TextView; + +import com.android.devtools.systemimage.uitest.annotations.TestInfo; +import com.android.devtools.systemimage.uitest.common.Res; +import com.android.devtools.systemimage.uitest.framework.SystemImageTestFramework; +import com.android.devtools.systemimage.uitest.utils.ApiDemosInstaller; +import com.android.devtools.systemimage.uitest.utils.AppLauncher; +import com.android.devtools.systemimage.uitest.utils.AppManager; +import com.android.devtools.systemimage.uitest.utils.DeveloperOptionsManager; +import com.android.devtools.systemimage.uitest.utils.SettingsUtil; +import com.android.devtools.systemimage.uitest.utils.Wait; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Test class for Android Settings page on Google API images. + */ +@RunWith(AndroidJUnit4.class) +public class SettingsTest { + @Rule + public final SystemImageTestFramework testFramework = new SystemImageTestFramework(); + + private final Instrumentation instrumentation = testFramework.getInstrumentation(); + private final UiDevice device = UiDevice.getInstance(instrumentation); + + private final static String TAG = "SettingsTest"; + + // Tests under this class takes up to 240 seconds depending on the performance of the bot the + // tests run on. + @Rule + public Timeout globalTimeout = Timeout.seconds(360); + + @Before + public void activateDeviceAdmin() throws Exception { + ApiDemosInstaller.installApp("Security", "Device admin apps", false); + } + + /** + * Verifies Location page opens on Google API images. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TT ID: 97d93bb7-63d2-4e89-9d18-0f232bbd51ab + * <p> + * <pre> + * 1. Start the emulator. + * 2. Open Settings > Google > Location + * Verify: + * Location settings page opens. + * </pre> + */ + @Test + @TestInfo(id = "97d93bb7-63d2-4e89-9d18-0f232bbd51ab") + public void testLocationSettingsPageOpen() throws Exception { + if (!testFramework.isGoogleApiAndPlayImage() && !testFramework.isGoogleApiImage()) { + return; + } + + AppLauncher.launch(instrumentation, "Settings"); + UiScrollable itemList = + new UiScrollable( + new UiSelector().resourceIdMatches(Res.SETTINGS_LIST_CONTAINER_RES) + ); + itemList.setAsVerticalList(); + + UiObject locationSetting = device.findObject( + new UiSelector() + .className("android.widget.TextView") + .text("Location")); + + assertTrue("Location not found in Settings List", + itemList.scrollIntoView(locationSetting)); + locationSetting.clickAndWaitForNewWindow(); + + boolean recentAccessText = new Wait().until( + () -> device.findObject(new UiSelector() + .text("Recent access")).exists()); + + if (!recentAccessText) { + device.findObject(new UiSelector().text("Use location")).clickAndWaitForNewWindow(); + } + + UiObject seeAll = device.findObject(new UiSelector() + .text("See all")); + + if (new Wait().until(seeAll::exists)) { + seeAll.clickAndWaitForNewWindow(); + } + + boolean recentAccessDesc = new Wait().until( + () -> device.findObject(new UiSelector() + .description("Recent access")).exists()); + assertTrue("Failed to find Location title.", recentAccessDesc); + } + + /** + * Verifies that the phone cannot dial out if phone privileges have been disabled. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TT ID: 4f09278e-d1e3-47bb-a22c-70f236ac9a48 + * <p> + * <pre> + * 1. Start the emulator. + * 2. Open Settings > Apps + * 3. Click on the gear icon and select App permissions. + * 4. Click on "Phone" + * 5. Disable Phone permissions. + * 6. Click on DENY button. + * 7. Return to the main screen. + * 8. Launch the phone app. + * 9. Click on the dialer icon. + * 10. Type in a number. + * 11. Click on Call icon. + * Verify: + * Dialog stating "This application cannot make outgoing calls without the Phone permission." + * </pre> + * <p> + * + */ + @Test + @TestInfo(id = "4f09278e-d1e3-47bb-a22c-70f236ac9a48") + @Ignore("Phone access cannot be revoked on API 30") + public void testPhonePermissions() throws Exception { + final String app = "Phone"; + + SettingsUtil.setAppPermissions_v3(instrumentation, app, app, false, + "Deny anyway", "Apps & notifications", "Permission manager"); + device.pressHome(); + + AppLauncher.launch(instrumentation, app); + + device.findObject(new UiSelector().resourceIdMatches(Res.DIALER_PHONE_RES)). + clickAndWaitForNewWindow(); + device.findObject(new UiSelector().resourceIdMatches(Res.DIALER_DIGITS_RES)).setText("555"); + device.findObject(new UiSelector().resourceIdMatches(Res.DIALER_PAD_RES)).click(); + + assertTrue("Did not prompt for lack of Phone permission.", + new Wait().until(() -> !(device.findObject( + new UiSelector().resourceIdMatches(Res.DIALER_IN_CALL_RES)). + exists())) + ); + + SettingsUtil.setAppPermissions_v3(instrumentation, app, app, true, + "Deny anyway", "Apps & notifications", "Permission manager"); + device.pressHome(); + } + + /** + * Verifies that access must be confirmed if Maps location permissions are disabled. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TT ID: 4f09278e-d1e3-47bb-a22c-70f236ac9a48 + * <p> + * <pre> + * 1. Start the Emulator. + * 2. Open Settings > Apps + * 3. Click on the gear icon and select App permissions. + * 4. Click on Location from App permissions screen. + * 5. Disable Maps. + * 6. Launch Maps app. + * 7. Click on the locator icon. + * Verify: + * Dialog asking "Allow Maps to access this device's location?" + * </pre> + * <p> + */ + @Test + @TestInfo(id = "4f09278e-d1e3-47bb-a22c-70f236ac9a48") + public void testMapPermissions() throws Exception { + final String appType = "Location"; + final String appName = "Maps"; + + if (!testFramework.isGoogleApiAndPlayImage() && !testFramework.isGoogleApiImage()) { + return; + } + + SettingsUtil.setAppPermissions_v3(instrumentation, appType, appName, false, + "Deny anyway", "Apps", "Permission manager"); + device.pressHome(); + + AppLauncher.launch(instrumentation, appName); + final UiObject acceptAndContinueButton; + acceptAndContinueButton = device.findObject(new UiSelector(). + textMatches("(?i)accept\\s&\\scontinue")); + if (acceptAndContinueButton.exists()) + acceptAndContinueButton.clickAndWaitForNewWindow(); + final UiObject skipButton; + skipButton = device.findObject(new UiSelector().textMatches("(?i)skip")); + if (skipButton.exists()) + skipButton.clickAndWaitForNewWindow(); + final UiObject gotItButton; + gotItButton = device.findObject(new UiSelector().textMatches("(?i)got\\sit")); + if (gotItButton.exists()) + gotItButton.clickAndWaitForNewWindow(); + + final UiObject myLocation; + myLocation = device.findObject(new UiSelector().resourceId(Res.ANDROID_MY_LOCATION)); + if (myLocation.exists()) + myLocation.clickAndWaitForNewWindow(); + + assertTrue("Did not prompt for lack of Maps permission.", + new Wait().until(() -> device.findObject(new UiSelector() + .resourceId(Res.ANDROID_PERMISSIONS_BUTTON)).exists()) + ); + + SettingsUtil.setAppPermissions_v3(instrumentation, appName, appName, true, + "Deny anyway", "Apps", "Permission manager"); + device.pressHome(); + } + + /** + * Verifies the App permissions screen loads. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TT ID: 4f09278e-d1e3-47bb-a22c-70f236ac9a48 + * <p> + * <pre> + * 1. Start the emulator. + * 2. Open Settings > Apps + * 3. Click on the gear icon. + * 4. Click on App permissions. + * Verify: + * App permissions page loads. Able to identify various apps on the page. + * </pre> + * <p> + */ + @Test + @TestInfo(id = "4f09278e-d1e3-47bb-a22c-70f236ac9a48") + public void displayConfigureAppPermissions() throws Exception { + + assertTrue(SettingsUtil.getAppPermissions_v2(instrumentation, "Calendar", "Apps", "Permission manager").exists() + && SettingsUtil.getAppPermissions_v2(instrumentation, "Camera", "Apps", "Permission manager").exists() + && SettingsUtil.getAppPermissions_v2(instrumentation, "Phone", "Apps", "Permission manager").exists()); + } + + /** + * Verifies Developer options is displayed under the System section on the Systems page. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TT ID: 4578f63f-7d2e-4e5e-a4e0-0ce2ae67982e + * <p> + * <pre> + * 1. Start the emulator. + * 2. Open Settings > About emulated device + * 3. Click on the Build number option 7 times. + * 4. Toast message indicating developer options is enabled. (Can't confirm due to b/26511336) + * 5. Navigate to Settings page. + * Verify: + * Developer options displayed under Systems section on the Settings page. + * </pre> + */ + @Test + @TestInfo(id = "4578f63f-7d2e-4e5e-a4e0-0ce2ae67982e") + public void developerOptionsEnabled() throws Exception { + DeveloperOptionsManager.enableDeveloperOptions_v3(testFramework); + assertTrue("Failed to enable Developer options.", + AppLauncher.launchPath( + instrumentation, true, "Settings", "System", "Developer options")); + } + + /** + * Verifies set date and set time fields are editable. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TT ID: f83bf063-2a8c-4d1b-808b-20fd76933135 + * <p> + * <pre> + * 1. Start the emulator. + * 2. Open Settings > Date and time + * 3. Automatic date & time option is enabled. + * 4. Disable Automatic date & time option. + * 5. Set date and Set time options are enabled. + * 6. Click on Set date option and Set time option. + * Verify: + * Calendar frame and Clock frame appears respectively. + * </pre> + */ + @Test + @TestInfo(id = "f83bf063-2a8c-4d1b-808b-20fd76933135") + public void enableSetDateAndSetTime() throws Exception { + try { + AppLauncher.launchPath( + instrumentation, true, "Settings", "System", "Date & time"); + + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + + final UiObject timeButton = device.findObject(new UiSelector().text("Set time automatically")); + + // Test requires "Automatic date & time" widget to start in the enabled state. + if (device.findObject(new UiSelector().text("Date")).isEnabled()) { + timeButton.click(); + } + assertTrue("Failed to disable set date.", + new Wait().until(() -> !device.findObject(new UiSelector().text("Date")).isEnabled()) + ); + assertTrue("Failed to disable set time.", + new Wait().until(() -> !device.findObject(new UiSelector().text("Time")).isEnabled()) + ); + timeButton.click(); + assertTrue("Failed to enable set date.", + new Wait().until(() -> device.findObject(new UiSelector().text("Date")).isEnabled()) + ); + assertTrue("Failed to enable set time.", + new Wait().until(() -> device.findObject(new UiSelector().text("Time")).isEnabled()) + ); + device.findObject(new UiSelector().text("Date")).clickAndWaitForNewWindow(); + + assertTrue(device.findObject( + new UiSelector().resourceId(Res.ANDROID_DATE_PICKER_HEADER_RES)).exists()); + device.findObject(new UiSelector().textContains("Cancel")).click(); + device.findObject(new UiSelector().text("Time")).click(); + assertTrue(device.findObject( + new UiSelector().resourceId(Res.ANDROID_TIME_HEADER_RES)).exists()); + + device.findObject(new UiSelector().textContains("Cancel")).click(); + } + + /** + * Verifies Time Zone option can be enabled. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TT ID: f83bf063-2a8c-4d1b-808b-20fd76933135 + * <p> + * <pre> + * 1. Start the emulator. + * 2. Open Settings > Date & Time + * 3. Verify automatic time zone option is enabled. + * 4. Disable automatic time zone. + * 5. Verify Select time zone is enabled. + * 6. Enable time zone. + * Verify: + * Select time zone text and timezone offset text can be seen. + * </pre> + */ + @Test + @TestInfo(id = "f83bf063-2a8c-4d1b-808b-20fd76933135") + public void enableTimeZone() throws Exception { + try { + AppLauncher.launchPath( + instrumentation, true, "Settings", "System", "Date & time"); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + + final UiObject autoTimeZoneButton = device.findObject(new UiSelector().text("Set time zone automatically")); + final UiObject timeZoneButton = device.findObject(new UiSelector().textContains("GMT")); + + // Test requires "Automatic date & time" widget to start in the enabled state. + if (timeZoneButton.isEnabled()) { + autoTimeZoneButton.click(); + } + assertTrue("Failed to disable select time zone", + new Wait().until(() -> !timeZoneButton.isEnabled()) + ); + // Disable automatic time zone option. + autoTimeZoneButton.click(); + assertTrue("Failed to enable select time zone", + new Wait().until(timeZoneButton::isEnabled) + ); + timeZoneButton.clickAndWaitForNewWindow(); + + assertTrue("Failed to load Select time zone screen.", + new Wait().until(() -> device.findObject( + new UiSelector().description("Select time zone")).exists()) + ); + + UiObject timeZoneLabel = device.findObject(new UiSelector().textMatches("(Time zone|Select UTC offset)"). + resourceId(Res.ANDROID_TITLE_RES).packageName("com.android.settings")); + if (timeZoneLabel.waitForExists(3L)) { + timeZoneLabel.clickAndWaitForNewWindow(); + } + + String timezoneOffset = "GMT-08:00"; + assertTrue("Target time zone label not found", + device.findObject(new UiSelector().textContains(timezoneOffset)).waitForExists(3L)); + } + + /** + * Verifies 24-hour format is enabled. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TT ID: f83bf063-2a8c-4d1b-808b-20fd76933135 + * <p> + * <pre> + * 1. Start the emulator. + * 2. Open Settings > Date & Time + * 3. Verify 24-hour format option is disabled. + * 4. Verify example time on screen shows 1:00 PM. + * 5. Enable 24-hour format. + * Verify: + * Example time on screen shows 13:00. + * </pre> + */ + @Ignore("24 hour format option has been removed from Settings.") + @Test + @TestInfo(id = "f83bf063-2a8c-4d1b-808b-20fd76933135") + public void enableTwentyFourHourFormat() throws Exception { + try { + AppLauncher.launchPath( + instrumentation, true, "Settings", "System", "Date & time"); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + + boolean autoTwentyFourWasEnabled = false; + boolean useTwentyFourWasEnabled = false; + UiObject useTwentyFourLabel = device.findObject(new UiSelector().text("Use 24-hour format")); + UiObject autoTwentyFourLabel = device.findObject(new UiSelector().text("Use locale default")); + final UiObject thirteenHundredLabel = device.findObject(new UiSelector().text("13:00")); + + // Initialize automatic format option to disabled state. + if (autoTwentyFourLabel.waitForExists(3L) && !useTwentyFourLabel.isEnabled()) { + autoTwentyFourWasEnabled = true; + autoTwentyFourLabel.click(); + } + + // Initialize 24-hour format option to disabled state. + if (thirteenHundredLabel.exists()) { + useTwentyFourWasEnabled = true; + useTwentyFourLabel.click(); + } + assertTrue("Failed to find Use 24-hour format label.", + new Wait().until(() -> device.findObject( + new UiSelector().text("Use 24-hour format")).exists()) + ); + assertTrue("Failed to find 1:00 PM label.", + new Wait().until(() -> device.findObject(new UiSelector().text("1:00 PM")).exists()) + ); + // Enable 24-hour format. + useTwentyFourLabel.click(); + assertTrue("Failed to find 13:00 label.", + new Wait().until(thirteenHundredLabel::exists) + ); + + if (autoTwentyFourWasEnabled && useTwentyFourLabel.isEnabled()) { + autoTwentyFourLabel.click(); + } + + // Clean up by disabling 24-hour format option. + if (!useTwentyFourWasEnabled) { + useTwentyFourLabel.click(); + } + } + + /** + * Verify that activating and deactivating Device Administrators setting works. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TR ID: C144630613 + * <p> + * <pre> + * Test Steps: + * 1. Start an emulator AVD. + * 2. Goto Settings —> Security —> Device Administration. + * 3. Select Sample Device Admin. + * 4. Goto to setting and deactivate policy. + * Verify: + * 1. (Verify #1) that the "Sample Device Admin" policy is deactivated. + * 2. (Verify #2) that the "Sample Device Admin" policy is activated. + * 3. (Verify #3) that the "Sample Device Admin" policy is deactivated. + * </pre> + */ + @Test + @TestInfo(id = "T144630613") + public void activateDeactivatePolicy() throws Exception { + try { + SettingsUtil.launchDeviceAdminApps(instrumentation, "Security", "Device admin apps"); + + if (SettingsUtil.checkStatusOfPolicy(device, instrumentation, "android.widget.Switch", Res.ANDROID_SETTING_LIST_RES)) { + SettingsUtil.deactivate(instrumentation, "Sample Device Admin", "Security", "Device admin apps"); + } + assertFalse(SettingsUtil.checkStatusOfPolicy(device, instrumentation, "android.widget.Switch", Res.ANDROID_SETTING_LIST_RES)); + + // Activate "Sample Device Admin" policy + SettingsUtil.activate(instrumentation, "Sample Device Admin", "Security", "Device admin apps"); + assertTrue(SettingsUtil.checkStatusOfPolicy(device, instrumentation, "android.widget.Switch", Res.ANDROID_SETTING_LIST_RES)); + + // Deactivate "Sample Device Admin" policy + SettingsUtil.deactivate(instrumentation, "Sample Device Admin", "Security", "Device admin apps"); + assertFalse(SettingsUtil.checkStatusOfPolicy(device, instrumentation, "android.widget.Switch", Res.ANDROID_SETTING_LIST_RES)); + } catch(Exception e) { + Log.e(TAG,"activateDeactivatePolicy: required APK is missing"); + Log.e(TAG,"error: " + e.getMessage()); + } + } + + /** + * Verify test Camera App is disabled in emulator when disabled in Device Admin. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TT ID: 4db4a825-b584-4c68-a04d-c6a933b14e24 + * <p> + * <pre> + * Test Steps: + * 1. Start an emulator AVD. + * 2. Goto Settings —> Security —> Device Administration + * 3. Select Sample Device Admin. + * 4. Goto app API Demos —> App —> Device Admin —> General + * 5. Select Enable All Device Cameras. + * 6. Repeat steps 2-4. + * 7. Select Disable All Device Cameras. + * 8. Goto Home screen —> Click on Camera Application + * 9. Repeat steps 2-4. + * 10. Select Enable All Device Cameras. + * Verify: + * 1. (Verify #1) camera app is enabled + * 2. (Verify #2) camera app is disabled + * 3. (Verify #3) camera app is enabled + * </pre> + */ + @Test + @TestInfo(id = "4db4a825-b584-4c68-a04d-c6a933b14e24") + @Ignore("Disabling camera permissions does not deactivate camera app on API 30") + public void testCameraAppDisabled() throws Exception { + SettingsUtil.enableSampleDeviceAdmin_v2(instrumentation, device, "Security"); + + if (SettingsUtil.verifyCameraAppDisabled(instrumentation)) { + SettingsUtil.setCameraEnabled(true, instrumentation, device); + } + + Assert.assertFalse(SettingsUtil.verifyCameraAppDisabled(instrumentation)); + + SettingsUtil.setCameraEnabled(false, instrumentation, device); + Assert.assertTrue(SettingsUtil.verifyCameraAppDisabled(instrumentation)); + + SettingsUtil.setCameraEnabled(true, instrumentation, device); + Assert.assertFalse(SettingsUtil.verifyCameraAppDisabled(instrumentation)); + } + + /** + * To verify that "Reset app preferences" restores permission restrictions. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TT ID: d49facce-9be7-47e0-afde-2052d3c57a25 + * <p> + * <pre> + * Test Steps: + * 1. Launch an emulator avd with wipe data. + * 2. Open Settings > Apps. + * 3. Open the menu (3 vertical dots) and tap on "Show System". + * 4. Tap on any app, say Maps and select "Permissions". + * 5. Enable all available permissions for the app. + * 6. Press back button. + * 7. Open the menu > Reset app preferences > Reset apps. + * Verify: + * 1. App settings for Maps are reset to default (Verify that Permissions and notification + * settings for Maps are cleared). + * </pre> + */ + @Ignore("Test is canceled on crash during app permission reset.") + @Test + @TestInfo(id = "d49facce-9be7-47e0-afde-2052d3c57a25") + public void modifyAndResetAppPermissions() throws Exception { + String appName = "Maps"; + String contactsText = "Contacts"; + String locationText = "Location"; + String microphoneText = "Microphone"; + String storageText = "Files and media"; + + // Variables to store the state of permissions. + boolean contactsSwitchState; + boolean locationSwitchState; + boolean microphoneSwitchState; + boolean storageSwitchState; + + AppManager.openAppList_v3(instrumentation); + + // Find and click "Maps" in apps list. + UiScrollable itemList = + new UiScrollable( + new UiSelector().resourceIdMatches(Res.SETTINGS_LIST_CONTAINER_RES) + ); + itemList.setAsVerticalList(); + + itemList.scrollIntoView(new UiSelector().text(appName)); + itemList.getChildByText(new UiSelector().className(TextView.class.getName()), appName) + .clickAndWaitForNewWindow(); + + //Get application info list. + UiScrollable appInfoList = + new UiScrollable( + new UiSelector().resourceIdMatches(Res.SETTINGS_LIST_CONTAINER_RES) + ); + + //Choose permissions to edit them. + appInfoList.getChildByText(new UiSelector(). + className(TextView.class.getName()),"Permissions").clickAndWaitForNewWindow(); + + UiScrollable permissionList = new UiScrollable(new UiSelector().resourceId(Res.PERMISSION_RECYCLER_VIEW)); + + //Get switch widgets UiObjects and + //Store current permissions state of switch widgets. + UiObject contactSwitch = + permissionList.getChildByText(new UiSelector().className("android.widget.TextView"), contactsText); + contactSwitch.click(); + UiObject contactsAllowSwitch = device.findObject(new UiSelector().resourceIdMatches(Res.ALLOW_PERMISSION_BUTTON)); + contactsSwitchState = contactsAllowSwitch.isChecked(); + contactsAllowSwitch.clickAndWaitForNewWindow(1000); + assertEquals(contactsSwitchState, !contactsAllowSwitch.isChecked()); + device.pressBack(); + + UiObject locationSwitch = + permissionList.getChildByText(new UiSelector().className("android.widget.TextView"), locationText); + locationSwitch.click(); + UiObject locationAllowSwitch = device.findObject(new UiSelector().resourceIdMatches(Res.ALLOW_PERMISSION_BUTTON)); + locationSwitchState = locationAllowSwitch.isChecked(); + locationAllowSwitch.clickAndWaitForNewWindow(1000); + assertEquals(locationSwitchState, !locationAllowSwitch.isChecked()); + device.pressBack(); + + UiObject microphoneSwitch = + permissionList.getChildByText(new UiSelector().className("android.widget.TextView"), microphoneText); + microphoneSwitch.clickAndWaitForNewWindow(1000); + UiObject microphoneAllowSwitch = device.findObject(new UiSelector().resourceId(Res.ALLOW_FOREGROUND_ONLY_PERMISSION_BUTTON)); + microphoneSwitchState = microphoneAllowSwitch.isChecked(); + microphoneAllowSwitch.clickAndWaitForNewWindow(1000); + assertEquals(microphoneSwitchState, !microphoneAllowSwitch.isChecked()); + device.pressBack(); + + UiObject storageSwitch = + permissionList.getChildByText(new UiSelector().className("android.widget.TextView"), storageText); + storageSwitch.click(); + UiObject storageAllowSwitch = device.findObject(new UiSelector().resourceId(Res.ALLOW_FOREGROUND_ONLY_PERMISSION_BUTTON)); + storageSwitchState = storageAllowSwitch.isChecked(); + storageAllowSwitch.clickAndWaitForNewWindow(1000); + assertEquals(storageSwitchState, !storageAllowSwitch.isChecked()); + device.pressBack(); + + + //Go back two times to go to system apps page to reset permissions. + device.pressBack(); + device.pressBack(); + + //Reset app preferences from overflow menu. + device.pressMenu(); + device.findObject( + new UiSelector().textContains("Reset app preferences")).clickAndWaitForNewWindow(); + device.findObject(new UiSelector().textContains("Reset Apps")).clickAndWaitForNewWindow(); + + //Open Maps info. + itemList.scrollIntoView(new UiSelector().text(appName)); + itemList.getChildByText(new UiSelector().className(TextView.class.getName()), appName) + .clickAndWaitForNewWindow(); + + //Open permission and verify Contacts,Location,Phone and Storage. + //Verify that all the permission for the app are reset. + appInfoList.getChildByText(new UiSelector(). + className(TextView.class.getName()),"Permissions").clickAndWaitForNewWindow(); + + permissionList = new UiScrollable(new UiSelector().resourceId(Res.PERMISSION_RECYCLER_VIEW)); + + contactSwitch = permissionList.getChildByText(new UiSelector().className("android.widget.TextView"), contactsText); + contactSwitch.clickAndWaitForNewWindow(1000); + contactsAllowSwitch = device.findObject(new UiSelector().resourceIdMatches(Res.ALLOW_PERMISSION_BUTTON)); + assertEquals(contactsSwitchState, contactsAllowSwitch.isChecked()); + device.pressBack(); + + locationSwitch = permissionList.getChildByText(new UiSelector().className("android.widget.TextView"), locationText); + locationSwitch.clickAndWaitForNewWindow(1000); + locationAllowSwitch = device.findObject(new UiSelector().resourceIdMatches(Res.ALLOW_PERMISSION_BUTTON)); + assertEquals(locationSwitchState, locationAllowSwitch.isChecked()); + device.pressBack(); + + microphoneSwitch = permissionList.getChildByText(new UiSelector().className("android.widget.TextView"), microphoneText); + microphoneSwitch.clickAndWaitForNewWindow(1000); + microphoneAllowSwitch = device.findObject(new UiSelector().resourceId(Res.ALLOW_FOREGROUND_ONLY_PERMISSION_BUTTON)); + assertEquals(microphoneSwitchState, microphoneAllowSwitch.isChecked()); + device.pressBack(); + + storageSwitch = permissionList.getChildByText(new UiSelector().className("android.widget.TextView"), storageText); + storageSwitch.clickAndWaitForNewWindow(1000); + storageAllowSwitch = device.findObject(new UiSelector().resourceId(Res.ALLOW_FOREGROUND_ONLY_PERMISSION_BUTTON)); + assertEquals(storageSwitchState, storageAllowSwitch.isChecked()); + device.pressBack(); + } + + /** + * To verify that revoking USB debugging can be invoked from Developer Options. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * <pre> + * Test Steps: + * 1. Launch an emulator avd. + * 2. If Developer Options are disabled, enable Developer Options. + * 3. Launch Developers Options. + * 4. Scroll to USB Debugging switch. + * Verify: + * 1. Developer Options have been enabled. + * 2. USB Debugging option is available. + * </pre> + */ + @Test + public void revokeDebugAuth() throws Exception { + if (!AppLauncher.launchPath( + instrumentation, true, "Settings", "System", "Developer options")) { + DeveloperOptionsManager.enableDeveloperOptions_v3(testFramework); + Assert.assertTrue("Could not enable developer options", + AppLauncher.launchPath( + instrumentation, true, "Settings", "System", "Developer options")); + } + + + UiScrollable itemList = + new UiScrollable( + new UiSelector().resourceIdMatches(Res.SETTINGS_LIST_CONTAINER_RES) + ); + itemList.setAsVerticalList(); + + UiObject usbDebugging = device.findObject(new UiSelector().text("USB debugging")); + assertTrue("USB debugging controls not found", itemList.scrollIntoView(usbDebugging)); + } + + /** + * To verify that a list of connected devices can be viewed. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * <pre> + * Test Steps: + * 1. Launch an emulator avd. + * 2. Click on Settings. + * 3. Click on Connected Devices. + * Verify: + * 1. 'Settings keeps stopping' error was not thrown. + * 2. List of connected devices is displayed. + * </pre> + */ + @Test + public void listConnectedDevices() throws Exception { + try { + AppLauncher.launchPath( + instrumentation, true, "Settings", "Connected devices"); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + + UiObject seeAll = device.findObject(new UiSelector() + .text("See all")); + + if (new Wait().until(seeAll::exists)) { + seeAll.clickAndWaitForNewWindow(); + } + + UiObject savedDevices = device.findObject(new UiSelector() + .description("Saved devices") + .resourceId(Res.SETTINGS_COLLAPSING_TOOLBAR_RES)); + + boolean hasSavedDevices = new Wait().until(savedDevices::exists); + + UiObject androidErrorClose = device.findObject( + new UiSelector().resourceId(Res.ANDROID_ERROR_CLOSE_RES)); + assertFalse("Settings Keeps Stopping error when revoking usb debugging", androidErrorClose.waitForExists(5L)); + + UiObject actionBar = device.findObject( + new UiSelector().resourceId(Res.SETTINGS_ACTION_BAR_RES).className("android.view.ViewGroup")); + UiObject connectedDevices = device.findObject( + new UiSelector().text("Previously connected devices").className("android.widget.TextView")); + Assert.assertTrue("Connected devices were not listed", + hasSavedDevices || + (actionBar.waitForExists(5L) && connectedDevices.waitForExists(5L))); + } + + /** + * To verify that files can be copied to and deleted from the device. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * <pre> + * Test Steps: + * 1. Launch an emulator avd. + * 2. Click on Settings. + * 3. Click on Storage > Internal shared storage > Files. + * 4. Remove test file from internal storage folder if it already exists. + * 5. Copy test file into internal storage folder. + * 6. Delete copied test file from internal storage folder. + * 7. Repeat for additional test files. + * Verify: + * 1. Test file does not already exist in the Download folder. + * 2. Test file is copied into the Download folder. + * 3. Test file is deleted from the Download folder. + * </pre> + */ + @Ignore("Cannot access external storage without a runtime permissions implementation") + @Test + public void filesDeleted() throws Exception { + String[] testFileNames = {"test_text_01.txt", "test_text_02.txt", "test_text_03.txt"}; + + for (String name : testFileNames) { + AppLauncher.launchPath(instrumentation, true, "Settings", "Storage", "Internal shared storage", "Files"); + + if (SettingsUtil.hasTestFile(instrumentation, name)) { + SettingsUtil.deleteTestFile_v2(instrumentation, name, Res.OPTION_MENU_SEARCH_RES); + } + Assert.assertFalse("Test file " + name + " already exists", + SettingsUtil.hasTestFile(instrumentation, name)); + + SettingsUtil.copyTestFile(instrumentation, name); + Assert.assertTrue("Test file " + name + " could not be copied", + SettingsUtil.hasTestFile(instrumentation, name)); + + SettingsUtil.deleteTestFile_v2(instrumentation, name, Res.OPTION_MENU_SEARCH_RES); + Assert.assertFalse("Test file " + name + " could not be deleted", + SettingsUtil.hasTestFile(instrumentation, name)); + } + } +} diff --git a/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/ShellUtilTest.java b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/ShellUtilTest.java new file mode 100644 index 00000000..57b6527b --- /dev/null +++ b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/ShellUtilTest.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.devtools.systemimage.uitest.smoke.api33; + +import android.app.Instrumentation; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiSelector; +import android.util.Log; + +import com.android.devtools.systemimage.uitest.annotations.TestInfo; +import com.android.devtools.systemimage.uitest.framework.SystemImageTestFramework; +import com.android.devtools.systemimage.uitest.utils.AppLauncher; +import com.android.devtools.systemimage.uitest.utils.DeveloperOptionsManager; +import com.android.devtools.systemimage.uitest.utils.ShellUtil; +import com.android.devtools.systemimage.uitest.utils.Wait; + +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.TimeUnit; + + +/** + * Test on shell utility. + */ +@RunWith(AndroidJUnit4.class) +public class ShellUtilTest { + private final String TAG = "ShellUtilTest"; + + @Rule + public final SystemImageTestFramework testFramework = new SystemImageTestFramework(); + + @Rule + public Timeout globalTimeout = Timeout.seconds(240); + + /** + * Tests the integrity of Shell utilities. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TR ID: C14578821 + * <p> + * <pre> + * Test Steps: + * 1. Start the emulator. + * 2. From the cmd line, run "adb shell ls /system/bin" + * Verify: + * Shell utilities are listed in SDK emulator image. + * </pre> + */ + @Test + @TestInfo(id = "14578821") + public void testShellUtilIntegrity() throws Exception { + Instrumentation instrumentation = testFramework.getInstrumentation(); + + String cmd = "ls /system/bin"; + ShellUtil.ShellResult result = ShellUtil.invokeCommand(cmd); + // Check if the cmd is executed correctly. + Assert.assertEquals(result.stderr, 0, result.stderr.length()); + + // Verify the integrity of the shell utilities. + InputStream inputStream = instrumentation.getTargetContext().getAssets().open("util.txt"); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); + String line; + StringBuilder util = new StringBuilder(); + while ((line = reader.readLine()) != null) { + util.append(line).append("\n"); + } + Assert.assertThat("Failure: The shell util is incomplete.", result.stderr, + Matchers.isEmptyOrNullString()); + } + + /** + * Tests take bug report in Developer Options. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TR ID: C14581588 + * <p> + * <pre> + * Test Steps: + * 1. Start the emulator. + * 2. Open Settings > Developer Options. + * 3. Tap on "Take Bug Report" + * 4. Click on REPORT button. + * Verify: + * Verify that a bug report is taken by checking for the png and zip file in the bugreport + * directory. + * </pre> + */ + @Test + @TestInfo(id = "14581588") + public void createBugReport() throws Exception { + Instrumentation instrumentation = testFramework.getInstrumentation(); + final UiDevice device = UiDevice.getInstance(instrumentation); + final String BUG_REPORT_DIR = "/bugreports"; + + ShellUtil.deleteBugReportFiles(BUG_REPORT_DIR, testFramework); + + if (!DeveloperOptionsManager.isDeveloperOptionsEnabled_v2(testFramework)) { + DeveloperOptionsManager.enableDeveloperOptions_v3(testFramework); + } + + AppLauncher.launchPath(instrumentation, true, "Settings", "System", "Developer options"); + // Remove bug report files even if the test fails. + try { + device.findObject( + new UiSelector().text("Bug report")).clickAndWaitForNewWindow(); + UiObject fullReportButton = device.findObject(new UiSelector().textMatches("(?i)full report(?-i)")); + if (fullReportButton.exists()) { + fullReportButton.clickAndWaitForNewWindow(); + } + UiObject reportButton = device.findObject(new UiSelector().textMatches("(?i)report(?-i)")); + if (reportButton.exists()) { + reportButton.click(); + } + boolean gotPngAndZip = new Wait( + TimeUnit.MILLISECONDS.convert(30L, TimeUnit.SECONDS)).until( + () -> { + String result = device.executeShellCommand("ls " + BUG_REPORT_DIR); + Log.d(TAG, "ls result " + result); + boolean success = + result.matches("(?s).*bugreport.*\\.png.*") + && result.matches("(?s).*bugreport.*\\.zip.*"); + + return success; + }); + Assert.assertTrue("Missing bug report files for png and zip.", gotPngAndZip); + } finally { + ShellUtil.deleteBugReportFiles(BUG_REPORT_DIR, testFramework); + } + } +} diff --git a/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/VpnTest.java b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/VpnTest.java new file mode 100644 index 00000000..579cbaf0 --- /dev/null +++ b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/VpnTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.devtools.systemimage.uitest.smoke.api33; + +import android.app.Instrumentation; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiSelector; + +import com.android.devtools.systemimage.uitest.annotations.TestInfo; +import com.android.devtools.systemimage.uitest.common.Res; +import com.android.devtools.systemimage.uitest.framework.SystemImageTestFramework; +import com.android.devtools.systemimage.uitest.utils.AppLauncher; +import com.android.devtools.systemimage.uitest.utils.PackageInstallationUtil; +import com.android.devtools.systemimage.uitest.utils.VpnTestUtil; +import com.android.devtools.systemimage.uitest.watchers.VpnPopupWatcher; + +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertTrue; + +/** + * Test on VPN app. + */ +@RunWith(AndroidJUnit4.class) +public class VpnTest { + @Rule + public final SystemImageTestFramework testFramework = new SystemImageTestFramework(); + + @Rule + public Timeout globalTimeout = Timeout.seconds(360); + + /** + * Tests if VPN works as expected. + * <p> + * This is run to qualify releases. Please involve the test team in substantial changes. + * <p> + * TR ID: C14578822 + * <p> + * <pre> + * Test Steps: + * 1. Start the emulator. + * 2. Install FredVPN app. + * 3. Open the app. + * 4. Tap on Connect. + * Verify: + * The VPN app runs on the emulator. A VPN lock icon displays on the status bar. + * </pre> + * <p/> + */ + @Test + @TestInfo(id = "14578822") + public void testVpn() throws Exception { + Instrumentation instrumentation = testFramework.getInstrumentation(); + UiDevice device = testFramework.getDevice(); + String apk = "FredVPN.apk"; + String result = PackageInstallationUtil.installApk(instrumentation, apk, true); + + assertTrue("Application " + apk + " is not installed. Result: " + result, + result.isEmpty()); + + // Check if VPN is on. If true, skip. + if (!VpnTestUtil.verifyVpnStatus_v2(device)) { + AppLauncher.launch(instrumentation, "TestVPN"); + UiObject olderVersionWarning = device.findObject( + new UiSelector().textMatches("(?i)ok(?-i)")); + if (olderVersionWarning.waitForExists(5000)) { + olderVersionWarning.clickAndWaitForNewWindow(); + } + device.findObject(new UiSelector().resourceId(Res.START_VPN_BUTTON_RES)) + .clickAndWaitForNewWindow(); + new VpnPopupWatcher(device).checkForCondition(); + Assert.assertTrue("Failed to find the VPN lock icon after starting VPN!", + VpnTestUtil.verifyVpnStatus_v2(device)); + } + } +} diff --git a/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/YouTubeTest.java b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/YouTubeTest.java new file mode 100644 index 00000000..9981c22a --- /dev/null +++ b/system_image_uitests/app/src/androidTest/java/com/android/devtools/systemimage/uitest/smoke/api33/YouTubeTest.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.devtools.systemimage.uitest.smoke.api33; + +import android.app.Instrumentation; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiSelector; + +import com.android.devtools.systemimage.uitest.annotations.TestInfo; +import com.android.devtools.systemimage.uitest.common.Res; +import com.android.devtools.systemimage.uitest.framework.SystemImageTestFramework; +import com.android.devtools.systemimage.uitest.utils.GoogleAppUtil; +import com.android.devtools.systemimage.uitest.utils.YouTubeUtil; + +import org.junit.FixMethodOrder; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; + +import static junit.framework.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Test to verify that YouTube is installed and working correctly on Google API images + */ + +@RunWith(AndroidJUnit4.class) +/* + *Added this annotation so that YouTube version is checked first before login happens. + *This is done because if login happens first, it will update the app and version check + *test will always pass. + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class YouTubeTest { + + @Rule + public final SystemImageTestFramework testFramework = new SystemImageTestFramework(); + + @Rule + public Timeout globalTimeout = Timeout.seconds(7200); + + /** + * Verify YouTube has the latest version or not. + * <p> + * TT ID: XXXX + * <p> + * <pre> + * Test Steps: + * 1. Start an emulator and launch home screen. + * 2. Open Apps. + * 3. Launch YouTube app. + * Verify: + * 1. Verify that there is no YouTube update screen. + * </pre> + */ + @Test + @TestInfo(id = "XXXX") + public void checkYouTubeVersion() throws Exception{ + Instrumentation instrumentation = testFramework.getInstrumentation(); + UiDevice device = UiDevice.getInstance(instrumentation); + + YouTubeUtil.launchYouTube(instrumentation); + UiObject updateLaterButton = device.findObject(new UiSelector().resourceId(Res.YOUTUBE_UPDATE_LATER_BUTTON_RES)); + assertFalse("Device has older version of YouTube installed", updateLaterButton.waitForExists(5L)); + } + + /** + * Verify YouTube login and logout are working correctly. + * <p> + * TT ID: XXXX + * <p> + * <pre> + * Test Steps: + * 1. Start an emulator and launch home screen + * 2. Sign out of YouTube if already logged in + * 3. Launch Chrome app and sign in to Chrome + * 4. Launch YouTube and check for user account + * 5. Sign out of You Tube + * Verify: + * 1. Verify that Chrome login synced with YouTube login + * 2. Verify that Google Account Services logout removed YouTube user + * </pre> + */ + @Test + @TestInfo(id = "XXXX") + public void loginYouTube() throws Exception { + Instrumentation instrumentation = testFramework.getInstrumentation(); + UiDevice device = UiDevice.getInstance(instrumentation); + + if (YouTubeUtil.isTestUserLoggedIn(instrumentation)) { + YouTubeUtil.logoutYouTubeAccount(instrumentation); + + assertFalse("YouTube log out was unsuccessful", + YouTubeUtil.isTestUserLoggedIn(instrumentation)); + } + + UiObject doneButton = device.findObject( + new UiSelector().packageName("com.google.android.youtube") + .className("android.widget.ImageButton") + .description("Close")); + + if (doneButton.waitForExists(5000L)) { + doneButton.clickAndWaitForNewWindow(); + } + + assertTrue("Google log in was unsuccessful", + GoogleAppUtil.loginGoogleApp(instrumentation, true)); + + assertTrue("YouTube log in was unsuccessful", + YouTubeUtil.isTestUserLoggedIn(instrumentation)); + + YouTubeUtil.logoutYouTubeAccount(instrumentation); + assertFalse("YouTube log out was unsuccessful", + YouTubeUtil.isTestUserLoggedIn(instrumentation)); + } +} |