Java – Espresso does not wait for the keyboard to open

Espresso does not wait for the keyboard to open… here is a solution to the problem.

Espresso does not wait for the keyboard to open

I have an Espresso test and my screen contains an EditText and a skip button underneath.
When I start the activity, the keyboard pops up, focusing on the EditText and overlapping the Button.
I now want to write a test for the skip button and assert what happens after that.

The problem is that espresso didn’t wait for the keyboard to turn on.
So what happened is

  • Espresso didn’t wait for keyboard input and pressed “skip”
  • The keyboard slides open
  • Assertion now fails under the keyboard

The code looks like this:

public void givenSkipped_whenConfirmed_thenMainActivityLaunched() {
  Espresso.closeSoftKeyboard();// <- Not working as espresso seems to think it is not open yet
  skipPostcodeEntry.perform(click()); <- Can click this as keyboard is not open yet.

warningText.check(matches(withText(R.string.some_text)));

confirmationButton.perform(click());//<- Fails as this is now overlapped by KB

Assert.DoesSomething()
}

I found that Espresso is not waiting for the keyboard to close But nothing is not waiting for the keyboard to turn on.

Has anyone solved this problem?

Edit:

When you look at the closeSoftKeyboard method, you find a class named CloseKeyboardAction. You can see that it even records when the keyboard is not recognized as open.

 Log.w(TAG, "Attempting to close soft keyboard, while it is not shown."); 

Solution

Unfortunately, at the moment Espresso can’t seem to check if the keyboard is on the screen or not! ( https://groups.google.com/forum/#!topic/android-platform/FyjybyM0wGA )

As a workaround, what we do is check the input field that should have focus and close the keyboard. This prevents Espresso from calling closeSoftKeyboard() before the keyboard appears on the screen

….

@Test
public void testSomething() {
    EspressoExtensions.closeKeyboardOnFocused(fieldThatShouldHaveFocus);
    Continue with normal test
}

Then add EspressoExtensions to your project:

public class EspressoExtensions {
  /**
   * This can be used to close the keyboard on an input field when Android opens the keyboard and
   * selects the first input when launching a screen.
   * <p>
   * This is needed because at the moment Espresso does not wait for the keyboard to open
   */
  public static void closeKeyboardOnFocused(ViewInteraction viewInteraction) {
    viewInteraction.check(matches(hasFocus())).perform(closeSoftKeyboard());
  }
}

Hopefully this will help until Espresso has a way to assert if the keyboard is on the screen or not

Related Problems and Solutions