Harden Android accessibility, localization and startup (#105)
Implement independent hardening and regression coverage. Keep #105 open for final feature and environment coverage after #106–#110; document the completion boundary and resume order.
This commit is contained in:
1 parent
43f660ace3
commit
6669b77f4e
55 files changed
+24445
-296
No files matched your search
@@ -0,0 +1 @@
|
||||
<manifest />
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package de.rfc1437.ironstorage.performance
|
||||
|
||||
import android.os.Build
|
||||
import androidx.benchmark.macro.junit4.BaselineProfileRule
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.Until
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
class BaselineProfile {
|
||||
@get:Rule val profile = BaselineProfileRule()
|
||||
|
||||
@Before fun preserveInstalledApplicationData() {
|
||||
// Older non-rooted images can reinstall the app while resetting compilation.
|
||||
check(Build.VERSION.SDK_INT >= 34)
|
||||
}
|
||||
|
||||
@Test fun startupAndPreferences() = profile.collect(
|
||||
packageName = "de.rfc1437.ironstorage"
|
||||
) {
|
||||
pressHome()
|
||||
startActivityAndWait()
|
||||
val preferences = device.wait(Until.findObject(By.text("Preferences")), 10000)
|
||||
assertNotNull("Preferences navigation must be available", preferences)
|
||||
preferences.click()
|
||||
assertNotNull(
|
||||
"Searchable settings must finish loading",
|
||||
device.wait(Until.findObject(By.text("Search settings")), 10000)
|
||||
)
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package de.rfc1437.ironstorage.performance
|
||||
|
||||
import androidx.benchmark.macro.CompilationMode
|
||||
import androidx.benchmark.macro.ExperimentalMacrobenchmarkApi
|
||||
import androidx.benchmark.macro.StartupMode
|
||||
import androidx.benchmark.macro.StartupTimingMetric
|
||||
import androidx.benchmark.macro.junit4.MacrobenchmarkRule
|
||||
import androidx.test.uiautomator.By
|
||||
import androidx.test.uiautomator.Until
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
@OptIn(ExperimentalMacrobenchmarkApi::class)
|
||||
class StartupBenchmark {
|
||||
@get:Rule val benchmark = MacrobenchmarkRule()
|
||||
|
||||
@Test fun coldStart() = startup(StartupMode.COLD)
|
||||
|
||||
@Test fun warmStart() = startup(StartupMode.WARM)
|
||||
|
||||
private fun startup(mode: StartupMode) = benchmark.measureRepeated(
|
||||
packageName = "de.rfc1437.ironstorage",
|
||||
metrics = listOf(StartupTimingMetric()),
|
||||
compilationMode = CompilationMode.Ignore(),
|
||||
startupMode = mode,
|
||||
iterations = 5,
|
||||
setupBlock = { pressHome() }
|
||||
) {
|
||||
startActivityAndWait()
|
||||
assertNotNull(
|
||||
"Native shell must finish loading",
|
||||
device.wait(Until.findObject(By.text("Home")), 10000)
|
||||
)
|
||||
device.waitForIdle()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user