Reputation: 303
Using uiautomator for Android I am able to set text in a text field but not able to then close the keyboard. With some phones when in lanscape mode the keyboard takes up the whole screen and 'Done' must be tapped to get out of that view. If I can suppress the keyboard then I can run uiautomator in both landscape and portrait without issue.
new UiObject(new UiSelector().text("Enter Text")).click();
new UiObject(new UiSelector().className("android.widget.EditText").instance(0)).setText("sample text");
// This is where I need to suppress the keyboard to view the app instead of just the keyboard itself.
new UiObject(new UiSelector().text("Submit")).click();
Thanks in advance.
Upvotes: 8
Views: 7368
Reputation: 982
This is quite an old question but with UiAutomator 2.0 it is possible to correctly and completely answer the question and thus here it is.
The optimal would be:
if (isKeyboardOpened()) {
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).pressBack();
}
But so far the problem was how to implement isKeyboardOpened().
As UiAutomator 2.0 is based on instrumentation, and thus we have access to UiAutomation, we can verify if there are any input windows present on the screen:
boolean isKeyboardOpened() {
UiAutomation automation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
for (AccessibilityWindowInfo window : automation.getWindows()) {
if (window.getType() == AccessibilityWindowInfo.TYPE_INPUT_METHOD) {
return true;
}
}
return false;
}
Somewhere in initialization code, make sure you execute this code, otherwise .getWindow()
will always return an empty list:
UiAutomation automation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
AccessibilityServiceInfo info = automation.getServiceInfo();
info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
automation.setServiceInfo(info);
Upvotes: 10
Reputation: 2486
Final after lot of work I found follow way to do this.
The problem is call getUIDevice().pressBack()
can break the test if no soft keyboard was display.
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isAcceptingText()) {
getUIDevice().pressBack();
}
That will only press back if keyboard was displayed.
Upvotes: 0
Reputation: 41
Seems very wrong, but it gets the job done.
public static final int KEYBOARD_WAIT_TIME = 111;
Espresso.closeSoftKeyboard();
sleep(AutomatedTestConfig.KEYBOARD_WAIT_TIME);
Upvotes: 4
Reputation: 321
I used your code, just added \n on the end of inserted text. That simulate 'enter', but keyboard is still appeared, so you need pressBack() to dismiss keyb.
new UiObject(new UiSelector()
.className("android.widget.EditText")
.instance(0))
.setText("sample text\n");
getUiDevice().pressBack();
There is more elegant solution:
new UiObject(new UiSelector()
.className("android.widget.EditText")
.instance(0))
.setText("sample text");
getUiDevice().pressEnter();
Upvotes: 2
Reputation: 394
Try DummyIME
and run the uiautomator
tool with -e disable_ime true
option.
DummyIME
resides in Android git repository.
Clone source code of DummyIME
:
git clone https://android.googlesource.com/platform/frameworks/testing
Build and install DummyIME
(You may change android-18
):
cd testing/uiautomator/utils/DummyIME
android update project -p . -t android-18
ant clean debug install
Run your tests using the uiautomator framework with -e disable_ime true
option.
adb shell uiautomator runtest <JARS> -e disable_ime true -c <CLASSES>
Note that you must restore settings of the default IME in your tested device
because it is automatically changed into DummyIME
after running the test.
Upvotes: -1
Reputation: 429
Normally clicking the Back-key will dismiss the keyboard.
getUiDevice().pressBack();
Upvotes: 2