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