Fix SettingsUITests flakiness

Bug: 290684887
Test: atest SettingsUITests
Change-Id: I8f85c9c50eb3426b740c7ef3bf8996d6655bca0a
This commit is contained in:
Chaohui Wang
2023-09-12 11:39:40 +08:00
parent 860fce72ec
commit 5bf2981d08
13 changed files with 112 additions and 125 deletions

View File

@@ -19,6 +19,7 @@ package com.android.settings.ui
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import com.android.settings.ui.testutils.SettingsTestUtils.assertHasTexts
import com.android.settings.ui.testutils.SettingsTestUtils.startMainActivityFromHomeScreen
@@ -30,11 +31,11 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@SmallTest
class AboutPhoneSettingsTests {
private lateinit var device: UiDevice
private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@Before
fun setUp() {
device = startMainActivityFromHomeScreen(Settings.ACTION_DEVICE_INFO_SETTINGS)
device.startMainActivityFromHomeScreen(Settings.ACTION_DEVICE_INFO_SETTINGS)
}
@Test

View File

@@ -16,50 +16,40 @@
package com.android.settings.ui
import android.os.RemoteException
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import com.android.settings.ui.testutils.SettingsTestUtils.assertObject
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
private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@Before
fun setUp() {
device = startMainActivityFromHomeScreen(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS)
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.clickObject(By.text("Disable app")) // Click on "Disable App" on dialog.
device.assertObject(By.text("Enable"))
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.assertObject(By.text("Disabled apps"))
device.setOrientationNatural()
device.assertObject(By.text("Disabled apps"))
device.clickObject(By.text("Calculator"))
device.clickObject(By.text("Enable"))
}

View File

@@ -17,25 +17,25 @@
package com.android.settings.ui
import android.provider.Settings
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import com.android.settings.ui.testutils.SettingsTestUtils.assertHasTexts
import com.android.settings.ui.testutils.SettingsTestUtils.assertObject
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
private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@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()
device.startMainActivityFromHomeScreen(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS)
device.assertObject(By.text("All apps"))
}
@Test
@@ -51,8 +51,7 @@ class AppsSettingsTests {
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()
device.assertObject(By.text("Disable"))
}
private companion object {

View File

@@ -18,6 +18,7 @@ package com.android.settings.ui
import android.content.Intent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import com.android.settings.ui.testutils.SettingsTestUtils.assertHasTexts
import com.android.settings.ui.testutils.SettingsTestUtils.startMainActivityFromHomeScreen
@@ -27,11 +28,11 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class BatterySettingsTest {
private lateinit var device: UiDevice
private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@Before
fun setUp() {
device = startMainActivityFromHomeScreen(Intent.ACTION_POWER_USAGE_SUMMARY)
device.startMainActivityFromHomeScreen(Intent.ACTION_POWER_USAGE_SUMMARY)
}
@Test

View File

@@ -18,26 +18,26 @@ package com.android.settings.ui
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import com.android.settings.ui.testutils.SettingsTestUtils.assertObject
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 DataSaverSettingsTest {
private lateinit var device: UiDevice
private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@Before
fun setUp() {
device = startMainActivityFromHomeScreen(Settings.ACTION_DATA_SAVER_SETTINGS)
device.startMainActivityFromHomeScreen(Settings.ACTION_DATA_SAVER_SETTINGS)
}
@Test
fun hasSwitchBar() {
assertThat(device.waitObject(By.text("Use Data Saver"))).isNotNull()
device.assertObject(By.text("Use Data Saver"))
}
}

View File

@@ -16,9 +16,11 @@
package com.android.settings.ui
import android.os.SystemClock
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import com.android.settings.ui.testutils.SettingsTestUtils.assertHasTexts
import com.android.settings.ui.testutils.SettingsTestUtils.startMainActivityFromHomeScreen
@@ -29,11 +31,13 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@SmallTest
class DevelopmentSettingsTest {
private lateinit var device: UiDevice
private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@Before
fun setUp() {
device = startMainActivityFromHomeScreen(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)
device.executeShellCommand("settings put global development_settings_enabled 1")
SystemClock.sleep(1000)
device.startMainActivityFromHomeScreen(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)
}
@Test

View File

@@ -18,6 +18,7 @@ package com.android.settings.ui
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import com.android.settings.ui.testutils.SettingsTestUtils.assertHasTexts
import com.android.settings.ui.testutils.SettingsTestUtils.startMainActivityFromHomeScreen
@@ -27,11 +28,11 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class HomepageDisplayTests {
private lateinit var device: UiDevice
private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@Before
fun setUp() {
device = startMainActivityFromHomeScreen(Settings.ACTION_SETTINGS)
device.startMainActivityFromHomeScreen(Settings.ACTION_SETTINGS)
}
@Test

View File

@@ -18,6 +18,7 @@ package com.android.settings.ui
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import com.android.settings.ui.testutils.SettingsTestUtils.assertHasTexts
import com.android.settings.ui.testutils.SettingsTestUtils.startMainActivityFromHomeScreen
@@ -27,11 +28,11 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class SecuritySettingsTest {
private lateinit var device: UiDevice
private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@Before
fun setUp() {
device = startMainActivityFromHomeScreen(Settings.ACTION_SECURITY_SETTINGS)
device.startMainActivityFromHomeScreen(Settings.ACTION_SECURITY_SETTINGS)
}
@Test

View File

@@ -18,6 +18,7 @@ package com.android.settings.ui
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import com.android.settings.ui.testutils.SettingsTestUtils.assertHasTexts
import com.android.settings.ui.testutils.SettingsTestUtils.startMainActivityFromHomeScreen
@@ -27,11 +28,11 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class StorageSettingsTest {
private lateinit var device: UiDevice
private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@Before
fun setUp() {
device = startMainActivityFromHomeScreen(Settings.ACTION_INTERNAL_STORAGE_SETTINGS)
device.startMainActivityFromHomeScreen(Settings.ACTION_INTERNAL_STORAGE_SETTINGS)
}
@Test

View File

@@ -18,6 +18,7 @@ package com.android.settings.ui
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import com.android.settings.ui.testutils.SettingsTestUtils.assertHasTexts
import com.android.settings.ui.testutils.SettingsTestUtils.startMainActivityFromHomeScreen
@@ -27,11 +28,11 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class SyncSettingsTest {
private lateinit var device: UiDevice
private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@Before
fun setUp() {
device = startMainActivityFromHomeScreen(Settings.ACTION_SYNC_SETTINGS)
device.startMainActivityFromHomeScreen(Settings.ACTION_SYNC_SETTINGS)
}
@Test

View File

@@ -0,0 +1,49 @@
/*
* 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.inputmethods
import android.content.Intent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE
import com.android.settings.ui.testutils.SettingsTestUtils.assertObject
import com.android.settings.ui.testutils.SettingsTestUtils.startMainActivityFromHomeScreen
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class SpellCheckerSettingsTest {
private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@Before
fun setUp() {
device.startMainActivityFromHomeScreen(Intent().apply {
setClassName(
SETTINGS_PACKAGE,
"com.android.settings.Settings\$SpellCheckersSettingsActivity",
)
})
}
@Test
fun hasSwitchBar() {
device.assertObject(By.text("Use spell checker"))
}
}

View File

@@ -1,60 +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.inputmethods;
import static com.android.settings.ui.testutils.SettingsTestUtils.TIMEOUT;
import static com.google.common.truth.Truth.assertThat;
import android.app.Instrumentation;
import android.content.Intent;
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 SpellCheckerSettingsUITest {
private Instrumentation mInstrumentation;
private Intent mIntent;
private UiDevice mUiDevice;
@Before
public void setUp() {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mUiDevice = UiDevice.getInstance(mInstrumentation);
mIntent = new Intent().setClassName("com.android.settings",
"com.android.settings.Settings$SpellCheckersSettingsActivity")
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
@Test
public void launchSettings_hasSwitchBar() {
mInstrumentation.getContext().startActivity(mIntent);
final UiObject2 switchBar =
mUiDevice.wait(Until.findObject(By.text("Use spell checker")), TIMEOUT);
assertThat(switchBar).isNotNull();
}
}

View File

@@ -20,14 +20,12 @@ 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 com.google.common.truth.Truth.assertWithMessage
object SettingsTestUtils {
@@ -37,37 +35,38 @@ object SettingsTestUtils {
fun UiDevice.waitObject(bySelector: BySelector): UiObject2? =
wait(Until.findObject(bySelector), TIMEOUT)
fun UiDevice.clickObject(bySelector: BySelector) = checkNotNull(waitObject(bySelector)).click()
fun UiDevice.assertObject(bySelector: BySelector): UiObject2 =
checkNotNull(waitObject(bySelector)) { "$bySelector not found" }
fun startMainActivityFromHomeScreen(action: String): UiDevice {
// Initialize UiDevice instance
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.pressKeyCodes(intArrayOf(KeyEvent.KEYCODE_MENU, KeyEvent.KEYCODE_MENU)) // unlock
fun UiDevice.clickObject(bySelector: BySelector) = assertObject(bySelector).click()
fun UiDevice.startMainActivityFromHomeScreen(action: String) {
startMainActivityFromHomeScreen(Intent(action))
}
fun UiDevice.startMainActivityFromHomeScreen(intent: Intent) {
pressKeyCodes(intArrayOf(KeyEvent.KEYCODE_MENU, KeyEvent.KEYCODE_MENU)) // unlock
// Start from the home screen
device.pressHome()
pressHome()
// Wait for launcher
val launcherPackage: String = device.launcherPackageName
assertThat(launcherPackage).isNotNull()
device.waitObject(By.pkg(launcherPackage).depth(0))
waitObject(By.pkg(launcherPackageName).depth(0))
// Launch the app
val context = ApplicationProvider.getApplicationContext<Context>()
val intent = Intent(action).apply {
ApplicationProvider.getApplicationContext<Context>().startActivity(Intent(intent).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
waitObject(By.pkg(SETTINGS_PACKAGE).depth(0))
}
fun UiDevice.assertHasTexts(texts: List<String>) {
val scrollableObj = findObject(By.scrollable(true))
val scrollableObj =
findObject(By.res(SETTINGS_PACKAGE, "main_content"))
?: findObject(By.scrollable(true))
for (text in texts) {
val selector = By.text(text)
assertWithMessage("Missing text: $text").that(