Skip to content

fix(uiautomator2): hideKeyboard confirms the keyboard hidden with two reads - #193

Merged
omnarayan merged 2 commits into
devicelab-dev:mainfrom
Lykhoyda:fm/maestro-runner-hidekeyboard-race
Oct 3, 2026
Merged

omnarayan merged 2 commits into
devicelab-dev:mainfrom
Lykhoyda:fm/maestro-runner-hidekeyboard-race

Conversation

@Lykhoyda

@Lykhoyda Lykhoyda commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Problem

On the UIAutomator2 driver, hideKeyboard decides whether the keyboard is up from a single dumpsys window InputMethod read. While the keyboard is still coming up, that read can report it not shown, and Appium's hide_keyboard can answer HTTP 404 ("keyboard not present") at the same moment. The step then returns success without pressing BACK, and the keyboard stays over the next tap target.

Evidence

In repeated QA runs of a flow that types into a field and then hides the keyboard, 1 run in 10 on 1.1.28 left the keyboard up after hideKeyboard, so the next tap landed on the keyboard. The decision code is identical in 1.1.27.

Fix

  • keyboardConfirmedHidden treats the keyboard as hidden only when two reads 300 ms apart both say it is not shown.
  • hideKeyboard uses it on the early-return path, and waitKeyboardHidden uses it after Appium's call. A read taken mid-transition can no longer skip the BACK fallback.
  • BACK is still sent only while a read shows the keyboard up, so a keyboard that is genuinely down never gets a blind BACK and its back-navigation.

Cost: each hideKeyboard step spends an extra 300 ms on the confirming read, including when the keyboard was already down.

The 300 ms window narrows the race but cannot close it: a keyboard still not reported shown 300 ms later passes as hidden. A failing dumpsys also still reads as hidden, which predates this change.

Tests

pkg/driver/uiautomator2/keyboard_hide_test.go drives hideKeyboard with a scripted sequence of dumpsys reads and Appium responses:

Case Result
Hidden then visible read (mid-transition), Appium answers 404 Sends BACK
Hidden on both reads No Appium call, no BACK, at least two reads
Visible, then hidden after hide_keyboard No BACK (existing test)
Appium answers 404 while the keyboard is visible Sends BACK

Without the fix, the transition case returns "Keyboard not visible" with no BACK, and the stable-hidden case makes only one read. The 404-while-visible case passes on old code too: it guards the BACK path rather than reproducing the bug.

make fmt-check, go vet ./... and go test -race ./... pass, except three tests that need a connected device or a free machine (pkg/device TestAndroidDevice_StartUIAutomator2, and two pkg/emulator tests that passed on rerun). Neither package imports the UIAutomator2 driver.

… reads

A dumpsys read taken while the keyboard is still coming up can report it not
shown, and Appium's hide_keyboard can answer 404 at the same moment, so the step
returned without pressing BACK and the keyboard stayed over the next target.
Treat the keyboard as hidden only when two reads 300 ms apart agree, both before
and after Appium's call. BACK is still sent only while the keyboard is shown.
@codecov

codecov Bot commented Oct 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@omnarayan

Copy link
Copy Markdown
Contributor

Thanks @Lykhoyda! Confirming the keyboard is hidden with two reads makes hideKeyboard deal properly with the keyboard animation race. The red check on this PR was a lint failure already on main, which #200 just fixed. I've updated the branch and resolved the CHANGELOG entry next to the others. Merging, and it'll be in the next release.

@omnarayan
omnarayan merged commit a7c6a27 into devicelab-dev:main Oct 3, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants