Daniel
Daniel

Reputation: 303

Suppress keyboard after setting text with Android uiautomator

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

Answers (6)

Inês
Inês

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

FIG-GHD742
FIG-GHD742

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

cant_login
cant_login

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

user3787216
user3787216

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

sumio
sumio

Reputation: 394

Try DummyIME and run the uiautomator tool with -e disable_ime true option. DummyIME resides in Android git repository.

  1. Clone source code of DummyIME:

    git clone https://android.googlesource.com/platform/frameworks/testing
    
  2. 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
    
  3. 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

Anders
Anders

Reputation: 429

Normally clicking the Back-key will dismiss the keyboard.

getUiDevice().pressBack();

Upvotes: 2

Related Questions