mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 11:07:10 +00:00
test(sidecar): pin the tree-guarded keyboard dismissal
This commit is contained in:
1 parent
b4cd9d5cd1
commit
1e350f7fd3
1 file changed
+120
@@ -240,8 +240,128 @@ class InputTextTest {
|
||||
}
|
||||
assertEquals(listOf("dumpsys input_method"), commands)
|
||||
}
|
||||
|
||||
// Typing is not the only thing that raises the keyboard: tapping a field
|
||||
// raises it too, and nothing was closing that one. The snapshot the picker
|
||||
// chooses from is missing every app node the keyboard covers, so the step
|
||||
// spends its budget choosing between the few targets left. Closing it
|
||||
// before the tree is read is what gives the step its targets back.
|
||||
@Test fun aKeyboardInTheTreeIsClosedBeforeTheTreeIsReturned() {
|
||||
var backs = 0
|
||||
val reads = mutableListOf<String>()
|
||||
val settled = treeWithoutKeyboard(
|
||||
IME_TREE,
|
||||
IME_PACKAGE,
|
||||
dismiss = { backs++ },
|
||||
reread = { APP_TREE.also { reads.add(it) } },
|
||||
sleep = {},
|
||||
)
|
||||
assertEquals(APP_TREE, settled)
|
||||
assertEquals(1, backs, "one BACK closes the keyboard")
|
||||
assertEquals(1, reads.size, "the tree is re-read once it is gone")
|
||||
}
|
||||
|
||||
// The guard has to be the tree itself. BACK with no keyboard open
|
||||
// navigates out of the screen, so a snapshot that pressed it on every read
|
||||
// would walk the fuzzer backwards out of the app a step at a time.
|
||||
@Test fun aTreeWithNoKeyboardIsReturnedUntouched() {
|
||||
var backs = 0
|
||||
var reads = 0
|
||||
val settled = treeWithoutKeyboard(
|
||||
APP_TREE,
|
||||
IME_PACKAGE,
|
||||
dismiss = { backs++ },
|
||||
reread = {
|
||||
reads++
|
||||
APP_TREE
|
||||
},
|
||||
sleep = {},
|
||||
)
|
||||
assertEquals(APP_TREE, settled)
|
||||
assertEquals(0, backs, "no keyboard in the tree means no BACK")
|
||||
assertEquals(0, reads, "and no second hierarchy read to pay for")
|
||||
}
|
||||
|
||||
// An unknown IME package is the honest "cannot tell", and the safe way to
|
||||
// be wrong is to leave the keyboard up rather than press BACK blind.
|
||||
@Test fun anUnknownImePackageSendsNoBack() {
|
||||
var backs = 0
|
||||
assertEquals(
|
||||
IME_TREE,
|
||||
treeWithoutKeyboard(
|
||||
IME_TREE,
|
||||
null,
|
||||
dismiss = { backs++ },
|
||||
reread = { APP_TREE },
|
||||
sleep = {},
|
||||
),
|
||||
)
|
||||
assertEquals(0, backs)
|
||||
}
|
||||
|
||||
// A keyboard the app puts straight back gets ONE back press, not one per
|
||||
// re-read. The flag behind the older dismissal lags a BACK by up to 0.6s,
|
||||
// and a burst of them inside that window is how a dismissal turns into
|
||||
// navigation.
|
||||
@Test fun aKeyboardThatStaysUpIsNotBackPressedRepeatedly() {
|
||||
var backs = 0
|
||||
var reads = 0
|
||||
val settled = treeWithoutKeyboard(
|
||||
IME_TREE,
|
||||
IME_PACKAGE,
|
||||
dismiss = { backs++ },
|
||||
reread = {
|
||||
reads++
|
||||
IME_TREE
|
||||
},
|
||||
sleep = {},
|
||||
)
|
||||
assertEquals(IME_TREE, settled, "the caller still gets a tree")
|
||||
assertEquals(1, backs)
|
||||
assertTrue(
|
||||
reads in 1..KEYBOARD_DISMISS_READS,
|
||||
"bounded re-reads, got $reads",
|
||||
)
|
||||
}
|
||||
|
||||
@Test fun imePackageOfReadsTheComponentAndRejectsNonsense() {
|
||||
assertEquals(
|
||||
"com.google.android.inputmethod.latin",
|
||||
imePackageOf(
|
||||
"com.google.android.inputmethod.latin/.LatinIME\n",
|
||||
),
|
||||
)
|
||||
assertEquals(null, imePackageOf("null"))
|
||||
assertEquals(null, imePackageOf(""))
|
||||
assertEquals(null, imePackageOf(" \n"))
|
||||
}
|
||||
|
||||
@Test fun treeShowsImeMatchesTheImesOwnViewIdsOnly() {
|
||||
assertTrue(treeShowsIme(IME_TREE, IME_PACKAGE))
|
||||
assertTrue(!treeShowsIme(APP_TREE, IME_PACKAGE))
|
||||
}
|
||||
}
|
||||
|
||||
private const val IME_PACKAGE = "com.google.android.inputmethod.latin"
|
||||
|
||||
private val APP_TREE =
|
||||
"""
|
||||
{"attributes":{"resource-id":"AddAccountScreen"},"children":[
|
||||
{"attributes":{"resource-id":"AccountNameField"},"children":[]},
|
||||
{"attributes":{"resource-id":"AddAccountSubmit"},"children":[]}]}
|
||||
""".trimIndent()
|
||||
|
||||
// The submit control is gone: an open keyboard does not merely cover the node,
|
||||
// it takes it out of the tree the picker enumerates.
|
||||
private val IME_TREE =
|
||||
"""
|
||||
{"attributes":{"resource-id":"AddAccountScreen"},"children":[
|
||||
{"attributes":{"resource-id":"AccountNameField"},"children":[]},
|
||||
{"attributes":{
|
||||
"resource-id":"com.google.android.inputmethod.latin:id/keyboard_holder"
|
||||
},"children":[]}]}
|
||||
""".trimIndent()
|
||||
|
||||
private val IME_OPEN_DUMPSYS =
|
||||
"""
|
||||
mCurMethodId=com.google.android.inputmethod.latin/.LatinIME
|
||||
|
||||
Reference in new issue
Block a user