From 1caab182a7f328de6d31331dea565a8d8f6dbd75 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Fri, 8 Sep 2023 15:20:44 +0800 Subject: [PATCH] Fix some SettingsUITests Bug: 290381395 Test: atest AppsSettingsTests Test: atest AppsSettingsRetainFilterTests Test: atest AboutPhoneSettingsTests Change-Id: I4c22afabbfc6ef5ed0e5fdcf86370ea0aaae5c74 --- .../settings/ui/AboutPhoneSettingsTests.java | 155 ------------------ .../settings/ui/AboutPhoneSettingsTests.kt | 101 ++++++++++++ .../ui/AppsSettingsRetainFilterTests.java | 123 -------------- .../ui/AppsSettingsRetainFilterTests.kt | 66 ++++++++ .../settings/ui/AppsSettingsTests.java | 132 --------------- .../android/settings/ui/AppsSettingsTests.kt | 76 +++++++++ .../ui/testutils/SettingsTestUtils.java | 61 ------- .../ui/testutils/SettingsTestUtils.kt | 83 ++++++++++ 8 files changed, 326 insertions(+), 471 deletions(-) delete mode 100644 tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.kt delete mode 100644 tests/uitests/src/com/android/settings/ui/AppsSettingsRetainFilterTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/AppsSettingsRetainFilterTests.kt delete mode 100644 tests/uitests/src/com/android/settings/ui/AppsSettingsTests.java create mode 100644 tests/uitests/src/com/android/settings/ui/AppsSettingsTests.kt delete mode 100644 tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.java create mode 100644 tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.kt diff --git a/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java b/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java deleted file mode 100644 index 225b41558f6..00000000000 --- a/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2018 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.settings.ui; - -import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE; -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; - -import android.app.Instrumentation; -import android.content.Intent; -import android.os.RemoteException; -import android.provider.Settings; -import android.text.TextUtils; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.Direction; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; - -/** Verifies basic functionality of the About Phone screen */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class AboutPhoneSettingsTests { - private static final int TIMEOUT = 2000; - - // TODO: retrieve using name/ids from com.android.settings package - private static final String[] sResourceTexts = { - "Phone number", - "Legal information", - "Regulatory labels" - }; - - private UiDevice mDevice; - private Instrumentation mInstrumentation; - - @Before - public void setUp() throws Exception { - mInstrumentation = InstrumentationRegistry.getInstrumentation(); - mDevice = UiDevice.getInstance(mInstrumentation); - try { - mDevice.setOrientationNatural(); - } catch (RemoteException e) { - throw new RuntimeException("Failed to freeze device orientaion", e); - } - - // make sure we are in a clean state before starting the test - mDevice.pressHome(); - Thread.sleep(TIMEOUT * 2); - launchAboutPhoneSettings(Settings.ACTION_DEVICE_INFO_SETTINGS); - // TODO: make sure we are always at the top of the app - // currently this will fail if the user has navigated into submenus - UiObject2 view = - mDevice.wait( - Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")), TIMEOUT); - assertThat(view).isNotNull(); - view.scroll(Direction.UP, 1.0f); - } - - @After - public void tearDown() throws Exception { - // Adding an extra pressBack so we exit About Phone Settings - // and finish the test cleanly - mDevice.pressBack(); - mDevice.pressHome(); // finish settings activity - mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating - } - - @Test - public void testAllMenuEntriesExist() { - searchForItemsAndTakeAction(mDevice, sResourceTexts); - } - - private void launchAboutPhoneSettings(String aboutSetting) { - Intent aboutIntent = new Intent(aboutSetting); - aboutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - InstrumentationRegistry.getTargetContext().startActivity(aboutIntent); - } - - /** - * Removes items found in the view and optionally takes some action. - */ - private void removeItemsAndTakeAction(UiDevice device, ArrayList itemsLeftToFind) { - for (Iterator iterator = itemsLeftToFind.iterator(); iterator.hasNext(); ) { - String itemText = iterator.next(); - UiObject2 item = device.wait(Until.findObject(By.text(itemText)), TIMEOUT); - if (item != null) { - iterator.remove(); - } - } - } - - /** - * Searches for UI elements in the current view and optionally takes some action. - * - *

Will scroll down the screen until it has found all elements or reached the bottom. - * This allows elements to be found and acted on even if they change order. - */ - private void searchForItemsAndTakeAction(UiDevice device, String[] itemsToFind) { - - ArrayList itemsLeftToFind = new ArrayList<>(Arrays.asList(itemsToFind)); - assertWithMessage("There must be at least one item to search for on the screen!") - .that(itemsLeftToFind) - .isNotEmpty(); - - boolean canScrollDown = true; - while (canScrollDown && !itemsLeftToFind.isEmpty()) { - removeItemsAndTakeAction(device, itemsLeftToFind); - - // when we've finished searching the current view, scroll down - UiObject2 view = - device.wait( - Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")), - TIMEOUT * 2); - if (view != null) { - canScrollDown = view.scroll(Direction.DOWN, 1.0f); - } else { - canScrollDown = false; - } - } - // check the last items once we have reached the bottom of the view - removeItemsAndTakeAction(device, itemsLeftToFind); - - assertWithMessage("The following items were not found on the screen: " - + TextUtils.join(", ", itemsLeftToFind)) - .that(itemsLeftToFind) - .isEmpty(); - } -} diff --git a/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.kt b/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.kt new file mode 100644 index 00000000000..235ba063df5 --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/AboutPhoneSettingsTests.kt @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2023 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.settings.ui + +import android.provider.Settings +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import androidx.test.uiautomator.By +import androidx.test.uiautomator.Direction +import androidx.test.uiautomator.UiDevice +import com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE +import com.android.settings.ui.testutils.SettingsTestUtils.startMainActivityFromHomeScreen +import com.android.settings.ui.testutils.SettingsTestUtils.waitObject +import com.google.common.truth.Truth.assertWithMessage +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +/** Verifies basic functionality of the About Phone screen */ +@RunWith(AndroidJUnit4::class) +@SmallTest +class AboutPhoneSettingsTests { + private lateinit var device: UiDevice + + @Before + fun setUp() { + device = startMainActivityFromHomeScreen(Settings.ACTION_DEVICE_INFO_SETTINGS) + } + + @Test + fun testAllMenuEntriesExist() { + searchForItemsAndTakeAction(device) + } + + /** + * Removes items found in the view and optionally takes some action. + */ + private fun removeItemsAndTakeAction(device: UiDevice, itemsLeftToFind: MutableList) { + val iterator = itemsLeftToFind.iterator() + while (iterator.hasNext()) { + val itemText = iterator.next() + val item = device.waitObject(By.text(itemText)) + if (item != null) { + iterator.remove() + } + } + } + + /** + * Searches for UI elements in the current view and optionally takes some action. + * + * + * Will scroll down the screen until it has found all elements or reached the bottom. + * This allows elements to be found and acted on even if they change order. + */ + private fun searchForItemsAndTakeAction(device: UiDevice) { + val itemsLeftToFind = resourceTexts.toMutableList() + assertWithMessage("There must be at least one item to search for on the screen!") + .that(itemsLeftToFind) + .isNotEmpty() + var canScrollDown = true + while (canScrollDown && itemsLeftToFind.isNotEmpty()) { + removeItemsAndTakeAction(device, itemsLeftToFind) + + // when we've finished searching the current view, scroll down + val view = device.waitObject(By.res("$SETTINGS_PACKAGE:id/main_content")) + canScrollDown = view?.scroll(Direction.DOWN, 1.0f) ?: false + } + // check the last items once we have reached the bottom of the view + removeItemsAndTakeAction(device, itemsLeftToFind) + assertWithMessage( + "The following items were not found on the screen: " + + itemsLeftToFind.joinToString(", ") + ) + .that(itemsLeftToFind) + .isEmpty() + } + + companion object { + // TODO: retrieve using name/ids from com.android.settings package + private val resourceTexts = listOf( + "Device name", + "Legal information", + "Regulatory labels" + ) + } +} diff --git a/tests/uitests/src/com/android/settings/ui/AppsSettingsRetainFilterTests.java b/tests/uitests/src/com/android/settings/ui/AppsSettingsRetainFilterTests.java deleted file mode 100644 index b830b3037a2..00000000000 --- a/tests/uitests/src/com/android/settings/ui/AppsSettingsRetainFilterTests.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2018 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.settings.ui; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.Intent; -import android.os.RemoteException; -import android.provider.Settings; -import android.system.helpers.ActivityHelper; - -import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -public class AppsSettingsRetainFilterTests { - private static final int TIMEOUT = 2000; - private UiDevice mDevice; - private ActivityHelper mActivityHelper = null; - - @Before - public void setUp() throws Exception { - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - mActivityHelper = ActivityHelper.getInstance(); - - try { - mDevice.setOrientationNatural(); - } catch (RemoteException e) { - throw new RuntimeException("failed to freeze device orientation", e); - } - - mDevice.pressHome(); - mDevice.waitForIdle(TIMEOUT); - } - - @Test - public void testDisablingSystemAppAndRotateDevice() throws Exception { - launchAppsSettings(); - - UiObject2 calculator = mDevice.wait( - Until.findObject(By.text("Calculator")), TIMEOUT); - assertThat(calculator).isNotNull(); - calculator.click(); - mDevice.waitForIdle(TIMEOUT); - - UiObject2 disableButton = mDevice.wait( - Until.findObject(By.text("DISABLE")), TIMEOUT); - assertThat(disableButton).isNotNull(); - disableButton.click(); - mDevice.waitForIdle(TIMEOUT); - - // Click on "Disable App" on dialog. - UiObject2 dialogDisableButton = mDevice.wait( - Until.findObject(By.text("DISABLE APP")), TIMEOUT); - assertThat(dialogDisableButton).isNotNull(); - dialogDisableButton.click(); - mDevice.waitForIdle(TIMEOUT); - - UiObject2 enableButton = mDevice.wait( - Until.findObject(By.text("ENABLE")), TIMEOUT); - assertThat(enableButton).isNotNull(); - - mDevice.pressBack(); - mDevice.waitForIdle(TIMEOUT); - - UiObject2 spinnerHeader = mDevice.wait( - Until.findObject(By.text("All apps")), TIMEOUT); - assertThat(spinnerHeader).isNotNull(); - spinnerHeader.click(); - - UiObject2 optionDisabledApps = mDevice.wait( - Until.findObject(By.text("Disabled apps")), TIMEOUT); - assertThat(optionDisabledApps).isNotNull(); - optionDisabledApps.click(); - mDevice.waitForIdle(TIMEOUT); - - try { - mDevice.setOrientationLeft(); - mDevice.waitForIdle(TIMEOUT); - } catch (RemoteException e) { - throw new RuntimeException("Failed to freeze device orientation", e); - } - - try { - mDevice.unfreezeRotation(); - mDevice.waitForIdle(TIMEOUT); - } catch (RemoteException e) { - throw new RuntimeException("Failed to un-freeze device orientation", e); - } - - UiObject2 spinnerDisabledApps = mDevice.wait( - Until.findObject(By.text("Disabled apps")), TIMEOUT); - assertThat(spinnerDisabledApps).isNotNull(); - } - - private void launchAppsSettings() throws Exception { - Intent appsSettingsIntent = new - Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS); - mActivityHelper.launchIntent(appsSettingsIntent); - } -} diff --git a/tests/uitests/src/com/android/settings/ui/AppsSettingsRetainFilterTests.kt b/tests/uitests/src/com/android/settings/ui/AppsSettingsRetainFilterTests.kt new file mode 100644 index 00000000000..23d5384734e --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/AppsSettingsRetainFilterTests.kt @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2023 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.settings.ui + +import android.os.RemoteException +import android.provider.Settings +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import com.android.settings.ui.testutils.SettingsTestUtils.clickObject +import com.android.settings.ui.testutils.SettingsTestUtils.startMainActivityFromHomeScreen +import com.android.settings.ui.testutils.SettingsTestUtils.waitObject +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class AppsSettingsRetainFilterTests { + private lateinit var device: UiDevice + + @Before + fun setUp() { + device = startMainActivityFromHomeScreen(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS) + } + + @Test + fun testDisablingSystemAppAndRotateDevice() { + device.clickObject(By.text("Calculator")) + device.clickObject(By.text("Disable")) + + // Click on "Disable App" on dialog. + device.clickObject(By.text("Disable app")) + assertThat(device.waitObject(By.text("Enable"))).isNotNull() + device.pressBack() + device.clickObject(By.text("All apps")) + device.clickObject(By.text("Disabled apps")) + try { + device.setOrientationLeft() + } catch (e: RemoteException) { + throw RuntimeException("Failed to freeze device orientation", e) + } + try { + device.unfreezeRotation() + } catch (e: RemoteException) { + throw RuntimeException("Failed to un-freeze device orientation", e) + } + assertThat(device.waitObject(By.text("Disabled apps"))).isNotNull() + device.clickObject(By.text("Calculator")) + device.clickObject(By.text("Enable")) + } +} diff --git a/tests/uitests/src/com/android/settings/ui/AppsSettingsTests.java b/tests/uitests/src/com/android/settings/ui/AppsSettingsTests.java deleted file mode 100644 index 777ade64f2c..00000000000 --- a/tests/uitests/src/com/android/settings/ui/AppsSettingsTests.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2018 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.settings.ui; - -import android.content.Intent; -import android.os.RemoteException; -import android.provider.Settings; -import android.system.helpers.ActivityHelper; -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.MediumTest; -import android.util.Log; - -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.Direction; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; - -/** Verifies basic functionality of the About Phone screen */ -public class AppsSettingsTests extends InstrumentationTestCase { - private static final boolean LOCAL_LOGV = false; - private static final String SETTINGS_PACKAGE = "com.android.settings"; - private static final String TAG = "AboutPhoneSettingsTest"; - private static final int TIMEOUT = 2000; - private ActivityHelper mActivityHelper = null; - - private UiDevice mDevice; - - private static final String[] sResourceTexts = { - "Storage", - "Data usage", - "Permissions", - "App notifications", - "Open by default", - "Battery", - "Memory" - }; - - @Override - public void setUp() throws Exception { - if (LOCAL_LOGV) { - Log.d(TAG, "-------"); - } - super.setUp(); - mDevice = UiDevice.getInstance(getInstrumentation()); - mActivityHelper = ActivityHelper.getInstance(); - try { - mDevice.setOrientationNatural(); - } catch (RemoteException e) { - throw new RuntimeException("Failed to freeze device orientaion", e); - } - - // make sure we are in a clean state before starting the test - mDevice.pressHome(); - Thread.sleep(TIMEOUT * 2); - launchAppsSettings(); - UiObject2 view = - mDevice.wait( - Until.findObject(By.text("All apps")), TIMEOUT); - assertNotNull("Could not find Settings > Apps screen", view); - } - - @Override - protected void tearDown() throws Exception { - mDevice.pressBack(); - mDevice.pressHome(); // finish settings activity - mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating - super.tearDown(); - } - - @MediumTest - public void testAppSettingsListForCalculator() { - UiObject2 calculator = mDevice.wait( - Until.findObject(By.text("Calculator")), TIMEOUT); - calculator.click(); - for (String setting : sResourceTexts) { - UiObject2 appSetting = - mDevice.wait( - Until.findObject(By.text(setting)), TIMEOUT); - assertNotNull("Missing setting for Calculator: " + setting, appSetting); - appSetting.scroll(Direction.DOWN, 10.0f); - } - } - - @MediumTest - public void testDisablingAndEnablingSystemApp() throws Exception { - launchAppsSettings(); - UiObject2 calculator = mDevice.wait( - Until.findObject(By.text("Calculator")), TIMEOUT); - calculator.click(); - mDevice.waitForIdle(TIMEOUT); - UiObject2 appInfoList = mDevice.wait( - Until.findObject(By.res(SETTINGS_PACKAGE, "list")), TIMEOUT); - appInfoList.scroll(Direction.DOWN, 100.0f); - UiObject2 disableButton = mDevice.wait( - Until.findObject(By.text("DISABLE")), TIMEOUT); - disableButton.click(); - mDevice.waitForIdle(TIMEOUT); - // Click on "Disable App" on dialog. - mDevice.wait( - Until.findObject(By.text("DISABLE APP")), TIMEOUT).click(); - mDevice.waitForIdle(TIMEOUT); - UiObject2 enableButton = mDevice.wait( - Until.findObject(By.text("ENABLE")), TIMEOUT); - assertNotNull("App not disabled successfully", enableButton); - enableButton.click(); - mDevice.waitForIdle(TIMEOUT); - disableButton = mDevice.wait( - Until.findObject(By.text("DISABLE")), TIMEOUT); - assertNotNull("App not enabled successfully", disableButton); - } - - private void launchAppsSettings() throws Exception { - Intent appsSettingsIntent = new - Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS); - mActivityHelper.launchIntent(appsSettingsIntent); - } -} diff --git a/tests/uitests/src/com/android/settings/ui/AppsSettingsTests.kt b/tests/uitests/src/com/android/settings/ui/AppsSettingsTests.kt new file mode 100644 index 00000000000..b8829a50c8b --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/AppsSettingsTests.kt @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2023 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.settings.ui + +import android.provider.Settings +import androidx.test.uiautomator.By +import androidx.test.uiautomator.Direction +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.Until +import com.android.settings.ui.testutils.SettingsTestUtils.clickObject +import com.android.settings.ui.testutils.SettingsTestUtils.startMainActivityFromHomeScreen +import com.android.settings.ui.testutils.SettingsTestUtils.waitObject +import com.google.common.truth.Truth.assertWithMessage +import org.junit.Before +import org.junit.Test + +/** Verifies basic functionality of the About Phone screen */ +class AppsSettingsTests { + private lateinit var device: UiDevice + + @Before + fun setUp() { + device = startMainActivityFromHomeScreen(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS) + val title = device.waitObject(By.text("All apps")) + assertWithMessage("Could not find Settings > Apps screen").that(title).isNotNull() + } + + @Test + fun testAppSettingsListForCalculator() { + device.clickObject(By.text("Calculator")) + val scrollableObj = device.findObject(By.scrollable(true)) + for (setting in resourceTexts) { + scrollableObj.scrollUntil(Direction.DOWN, Until.findObject(By.text(setting))) + val appSetting = device.waitObject(By.text(setting)) + assertWithMessage("Missing setting for Calculator: $setting") + .that(appSetting).isNotNull() + } + } + + @Test + fun testDisablingAndEnablingSystemApp() { + device.clickObject(By.text("Calculator")) + device.clickObject(By.text("Disable")) + device.clickObject(By.text("Disable app")) // Click on "Disable app" on dialog. + device.clickObject(By.text("Enable")) + val disableButton = device.waitObject(By.text("Disable")) + assertWithMessage("App not enabled successfully").that(disableButton).isNotNull() + } + + companion object { + private val resourceTexts = arrayOf( + "Notifications", + "Permissions", + "Storage & cache", + "Mobile data & Wi‑Fi", + "Screen time", + "App battery usage", + "Language", + "Open by default" + ) + } +} diff --git a/tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.java b/tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.java deleted file mode 100644 index eb8e33c1c2c..00000000000 --- a/tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2018 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.settings.ui.testutils; - -import static org.junit.Assert.assertNotNull; - -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.Direction; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; - -public class SettingsTestUtils { - - public static final String SETTINGS_PACKAGE = "com.android.settings"; - public static final int TIMEOUT = 2000; - - private void scrollToTop(UiDevice device) throws Exception { - int count = 5; - UiObject2 view = null; - while (count >= 0) { - view = device.wait( - Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")), - TIMEOUT); - view.scroll(Direction.UP, 1.0f); - count--; - } - } - - public static void assertTitleMatch(UiDevice device, String title) { - int maxAttempt = 5; - UiObject2 item = null; - UiObject2 view = null; - while (maxAttempt-- > 0) { - item = device.wait(Until.findObject(By.res("android:id/title").text(title)), TIMEOUT); - if (item == null) { - view = device.wait( - Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")), - TIMEOUT); - view.scroll(Direction.DOWN, 1.0f); - } else { - return; - } - } - assertNotNull(String.format("%s in Setting has not been loaded correctly", title), item); - } -} diff --git a/tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.kt b/tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.kt new file mode 100644 index 00000000000..2aa63b448b1 --- /dev/null +++ b/tests/uitests/src/com/android/settings/ui/testutils/SettingsTestUtils.kt @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2023 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.settings.ui.testutils + +import android.content.Context +import android.content.Intent +import android.view.KeyEvent +import androidx.test.core.app.ApplicationProvider +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.By +import androidx.test.uiautomator.BySelector +import androidx.test.uiautomator.Direction +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.UiObject2 +import androidx.test.uiautomator.Until +import com.google.common.truth.Truth.assertThat +import org.junit.Assert.fail + +object SettingsTestUtils { + const val SETTINGS_PACKAGE = "com.android.settings" + const val TIMEOUT = 2000L + + fun UiDevice.waitObject(bySelector: BySelector): UiObject2? = + wait(Until.findObject(bySelector), TIMEOUT) + + fun UiDevice.clickObject(bySelector: BySelector) = checkNotNull(waitObject(bySelector)).click() + + fun startMainActivityFromHomeScreen(action: String): UiDevice { + // Initialize UiDevice instance + val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + device.pressKeyCodes(intArrayOf(KeyEvent.KEYCODE_MENU, KeyEvent.KEYCODE_MENU)) // unlock + + // Start from the home screen + device.pressHome() + + // Wait for launcher + val launcherPackage: String = device.launcherPackageName + assertThat(launcherPackage).isNotNull() + device.waitObject(By.pkg(launcherPackage).depth(0)) + + // Launch the app + val context = ApplicationProvider.getApplicationContext() + val intent = Intent(action).apply { + addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + context.startActivity(intent) + + // Wait for the app to appear + device.waitObject(By.pkg(SETTINGS_PACKAGE).depth(0)) + + return device + } + + @JvmStatic + fun assertTitleMatch(device: UiDevice, title: String) { + var maxAttempt = 5 + while (maxAttempt-- > 0 && + device.wait( + Until.findObject(By.res("android:id/title").text(title)), + TIMEOUT + ) == null + ) { + device.waitObject(By.res(SETTINGS_PACKAGE, "main_content")) + ?.scroll(Direction.DOWN, 1.0f) + } + fail("$title in Setting has not been loaded correctly") + } +}