Bug 1882777 - Request permission to reset locale in UI tests

fenix/125.0
oana.horvath 3 months ago committed by mergify[bot]
parent 216c8cfdb2
commit affd8204e5

@ -356,64 +356,60 @@ object AppAndSystemHelper {
/**
* Changes the default language of the entire device, not just the app.
* Runs on Debug variant as we don't want to adjust Release permission manifests
* Runs the test in its testBlock.
* Cleans up and sets the default locale after it's done.
* As a safety measure, always add the resetSystemLocaleToEnUS() method in the tearDown method of your Class.
*/
fun runWithSystemLocaleChanged(locale: Locale, testRule: ActivityTestRule<HomeActivity>, testBlock: () -> Unit) {
val defaultLocale = Locale.getDefault()
try {
setSystemLocale(locale)
testBlock()
ThreadUtils.runOnUiThread { testRule.activity.recreate() }
} catch (e: Exception) {
e.printStackTrace()
} finally {
setSystemLocale(defaultLocale)
}
}
/**
* Changes the default language of the entire device, not just the app.
* We can only use this if we're running on a debug build, otherwise it will change the permission manifests in release builds.
*/
fun setSystemLocale(locale: Locale) {
if (Config.channel.isDebug) {
/* Sets permission to change device language */
Log.i(
TAG,
"setSystemLocale: Requesting permission to change system locale to $locale.",
)
PermissionRequester().apply {
addPermissions(
Manifest.permission.CHANGE_CONFIGURATION,
)
requestPermissions()
}
val defaultLocale = Locale.getDefault()
try {
setSystemLocale(locale)
testBlock()
ThreadUtils.runOnUiThread { testRule.activity.recreate() }
} catch (e: Exception) {
e.printStackTrace()
} finally {
setSystemLocale(defaultLocale)
}
}
}
/**
* Resets the default language of the entire device back to EN-US.
* In case of a test instrumentation crash, the finally statement in the
* runWithSystemLocaleChanged(locale: Locale) method, will not be reached.
* Add this method inside the tearDown method of your test class, where the above method is used.
* Note: If set inside the ActivityTestRule's afterActivityFinished() method, this also won't work,
* as the methods inside it are not always executed: https://github.com/android/android-test/issues/498
*/
fun resetSystemLocaleToEnUS() {
if (Locale.getDefault() != Locale.US) {
Log.i(TAG, "Resetting system locale to EN US")
setSystemLocale(Locale.US)
Log.i(
TAG,
"setSystemLocale: Received permission to change system locale to $locale.",
)
val activityManagerNative = Class.forName("android.app.ActivityManagerNative")
val am = activityManagerNative.getMethod("getDefault", *arrayOfNulls(0))
.invoke(activityManagerNative, *arrayOfNulls(0))
val config =
InstrumentationRegistry.getInstrumentation().context.resources.configuration
config.javaClass.getDeclaredField("locale")[config] = locale
config.javaClass.getDeclaredField("userSetLocale").setBoolean(config, true)
am.javaClass.getMethod(
"updateConfiguration",
Configuration::class.java,
).invoke(am, config)
}
}
/**
* Changes the default language of the entire device, not just the app.
*/
fun setSystemLocale(locale: Locale) {
val activityManagerNative = Class.forName("android.app.ActivityManagerNative")
val am = activityManagerNative.getMethod("getDefault", *arrayOfNulls(0))
.invoke(activityManagerNative, *arrayOfNulls(0))
val config = InstrumentationRegistry.getInstrumentation().context.resources.configuration
config.javaClass.getDeclaredField("locale")[config] = locale
config.javaClass.getDeclaredField("userSetLocale").setBoolean(config, true)
am.javaClass.getMethod(
"updateConfiguration",
Configuration::class.java,
).invoke(am, config)
Log.i(
TAG,
"setSystemLocale: Changed system locale to $locale.",
)
}
fun putAppToBackground() {

@ -11,8 +11,8 @@ import org.junit.After
import org.junit.Before
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.TestHelper.appContext
import org.mozilla.fenix.ui.robots.notificationShade
import java.util.Locale
/**
* Standard Test setup and tear down methods to run before each test.
@ -26,19 +26,12 @@ open class TestSetup {
@Before
open fun setUp() {
Log.i(TAG, "TestSetup: Starting the @Before setup")
// Initializing this as part of class construction, below the rule would throw a NPE.
// So we are initializing this here instead of in all related tests.
Log.i(TAG, "TestSetup: Trying to initialize the browserStore instance")
browserStore = appContext.components.core.store
Log.i(TAG, "TestSetup: Initialized the browserStore instance")
// Clear pre-existing notifications.
notificationShade {
cancelAllShownNotifications()
}
runBlocking {
// Reset locale to EN-US if needed.
AppAndSystemHelper.resetSystemLocaleToEnUS()
// Because of https://bugzilla.mozilla.org/show_bug.cgi?id=1812183, some items might not be updated.
if (Locale.getDefault() != Locale.US) {
AppAndSystemHelper.setSystemLocale(Locale.US)
}
// Check and clear the downloads folder, in case the tearDown method is not executed.
// This will only work in case of a RetryTestRule execution.
AppAndSystemHelper.clearDownloadsFolder()
@ -52,6 +45,16 @@ open class TestSetup {
AppAndSystemHelper.deletePermissionsStorage()
}
// Initializing this as part of class construction, below the rule would throw a NPE.
// So we are initializing this here instead of in all related tests.
Log.i(TAG, "TestSetup: Trying to initialize the browserStore instance")
browserStore = TestHelper.appContext.components.core.store
Log.i(TAG, "TestSetup: Initialized the browserStore instance")
// Clear pre-existing notifications.
notificationShade {
cancelAllShownNotifications()
}
mockWebServer = MockWebServer().apply {
dispatcher = AndroidAssetDispatcher()
}
@ -68,7 +71,16 @@ open class TestSetup {
@After
open fun tearDown() {
Log.i(TAG, "TestSetup: Starting the @After tearDown methods.")
// Check and clear the downloads folder.
AppAndSystemHelper.clearDownloadsFolder()
runBlocking {
// Check and clear the downloads folder.
AppAndSystemHelper.clearDownloadsFolder()
// Reset locale to EN-US if needed.
// This method is only here temporarily, to set the language before a new activity is started.
// TODO: When https://bugzilla.mozilla.org/show_bug.cgi?id=1812183 is fixed, it should be removed.
if (Locale.getDefault() != Locale.US) {
AppAndSystemHelper.setSystemLocale(Locale.US)
}
}
}
}

Loading…
Cancel
Save