Testing AutoCompleteTextView with Espresso - android

I am using Espresso to test an app with several AutoCompleteTextViews. For one particular test, the autocomplete popup appears, but I want to just ignore it and move to the next TextView. How can I do this? My ideas are to either simulate a "Back" press or simulate a tap in the popup.
Update:
I am attempting the following to click on the autocomplete popup:
onView(withId(R.id.brand_text))
.perform(scrollTo(), typeText(card.getBrand()));
onData(allOf(is(instanceOf(String.class)), is(card.getBrand())))
.inRoot(isPlatformPopup())
.perform(click());
onView(withId(R.id.brand_text))
.check(matches(withText(card.getBrand())));
Now the problem is that in some cases, the text entered doesn't have any autocomplete matches so no popup appears. How do I conditionally perform the click depending on whether or not a view is matched?

My solution was to add a UiDevice object from UI Automator to my test:
UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
Then I call UiDevice.pressEnter() to advance to the next TextView.
device.pressEnter();
The problem encountered is that this doesn't work as expected out of the box. I also added a View.OnKeyListener to each AutoCompleteTextView to handle the Enter key event. For now I add a listener to each view and explicitly state which view requests focus on an Enter key event.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// ...
brandText.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_ENTER) {
yearText.requestFocus();
return true;
}
return false;
}
});
//...
}
This isn't ideal. Eventually I plan to generalize this, possibly with a custom component which inherits from AutoCompleteTextView which handles the Enter key as I expect. It will send focus to the "next" view.

Related

android soft keyboard backspace button not working

I want to take control of soft keyboard appering. So I have override EditText class and method onCheckIsTextEditor.
#Override
public boolean onCheckIsTextEditor() {
return MenuActivity.expanded;
}
And after it everything works fine except delete/backspace button. When I press it nothing change. Also when I set onClickListener to my editText i can see that every click except delete fire this listener.
public void setOnBackSpaceListener(){
this.setOnKeyListener((view, i, keyEvent) -> {
Log.d("AAA -> ", String.valueOf(keyEvent.getKeyCode()));
return false;
});
}
So it's look like android think there was no click and I don't know why?
I'm going to make the assumption that you are implementing View.OnKeyListener in your Activity or Fragment. Are you passing your listener to the view you would like to capture the event from?
In this case, it will be:
mEditText.setOnKeyListener(this);

Simulating a click on a Next/Done button in Robolectric

In a given screen i have few controls where the first one is EditText and than RadioGroup and than a Button, at EditText i have used android:imeOptions="actionNext", now for this writing a straightforward Robolectric test case is not a big deal as
we can write
Button someButton = (Button) findViewById(R.id.some_button);
someButton.performClick();
but the question is how to automate and write a test case on clicking Next/Done button of the given softinput KeyBoard. How we can write and perform next/done Button of softinput keyboard click ?
Please guide!!
You've got probably something like this which you want to test:
getView(R.id.etPassword).setOnEditorActionListener(
new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_NEXT) {
checkCredentialsAndStartLoginTask();
}
return false;
}
});
This listener is called when you click on "Next" on the soft keyboard. If you want to test this simply call the onEditorAction with the adequate actionId as parameter on the EditText to simulate this soft keyboard button click. See this sample.
#Test
public void emptyUsernameShouldTriggerToast() throws Exception {
activity = controller.create().start().resume().visible().get();
// enter username and password
ui.etAccount.setText("");
ui.etPassword.setText("Battery");
// test initial state
ui.etPassword.onEditorAction(EditorInfo.IME_ACTION_NEXT);
// test Toast
ShadowHandler.idleMainLooper();
assertThat( ShadowToast.getTextOfLatestToast() ).isEqualTo(("Please enter username and password.") );
}

How to catch key event when soft keyboard is shown programmatically?

I'm trying to write text in Canvas. As I need to show the soft keyboard to write text, I added an EditText to my Activity with 0 width. I also implemented a TextWatcher to get the text entered into the EditText. With this trick, I can show the soft keyboard whenever I like with this code :
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(myEditText, InputMethodManager.SHOW_IMPLICIT);
Like this I'm able to know what the user is writing and to write the text inside my Canvas.
Now... this becomes tricky when the user would like to stop writing (or let say, anchor the text in the canvas definitely). What I thought is that he could press 'Enter'. So I tried to implement some way to catch the key events. Without any success so far.
Here is my actual code. This method is called when I would like to start writing. 'edit' is an EditText.
public void handleUp(final Paint myPaint) {
edit.setFocusable(true);
edit.setFocusableInTouchMode(true);
edit.requestFocus();
edit.addTextChangedListener(new Watcher());
edit.setImeOptions(EditorInfo.IME_ACTION_GO);
edit.setOnEditorActionListener(new OnEditorActionListener() {
public boolean onEditorAction(TextView arg0, int arg1, KeyEvent arg2) {
Log.d("MyApp", "key pressed");
Paint localPaint = new Paint();
mCanvas.drawText(edit.getText().toString(), mX, mY, localPaint);
return false;
}
});
edit.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
Log.d("MyApp", "key pressed");
if (keyCode == KeyEvent.ACTION_DOWN) {
Paint localPaint = new Paint();
mCanvas.drawText(edit.getText().toString(), mX, mY, localPaint);
return true;
}
return false;
}
});
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(edit, InputMethodManager.SHOW_IMPLICIT);
}
When I debug my app I never reach check points that I have put on my Log() and can't see any message in my Logs neither. I have seen many posts on StackOverFlow where this kind of implementation is used by I can't figure out why it fails here.
Thank you
Taken from the documentation:
public void setOnKeyListener (View.OnKeyListener l)
Added in API level 1
Register a callback to be invoked when a hardware key is pressed in this view. Key presses in software input methods will generally not trigger the methods of this listener.
So you should look for another listener.
My best guess would be to use this:
public void setOnEditorActionListener (TextView.OnEditorActionListener l)
Added in API level 3
Set a special listener to be called when an action is performed on the text view. This will be called when the enter key is pressed, or when an action supplied to the IME is selected by the user. Setting this means that the normal hard key event will not insert a newline into the text view, even if it is multi-line; holding down the ALT modifier will, however, allow the user to insert a newline character.
But none of the methods I could see in the documentation mentioned anything about soft key input.
You override the dispatchKeyEvent to get the Enter key
#Override
public boolean dispatchKeyEvent(KeyEvent event)
{
if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)
{
// Do whatever you want
}
return super.dispatchKeyEvent(event);
}
Okay so finally the reason nothing worked was because my EditText had a width of 0. When I put width and height to 1. Setting visibility to View.INVISIBLE doesn't work in this case.
By the way, the three Listener (OnEditorActionListener, OnKeyListener and Overriding dispatchKeyEvent) get the callbacks. But I'll use OnEditorActionListener because it's the only one getting only one callback. The two others get several callbacks which is problematic.

Android: When the on-screen keyboard appears and disappears, are there any listeners that are automatically called?

I was wondering if there is any way to be notified automatically by android when the on-screen keyboard is shown and when it disappears.
For example when we click on a edittext, the ime appears. Will there be any event calls?
And when it disappears when we press back, similarly will there be any even calls?
I found this thread Android: which event fires when on screen keyboard appears? , however no answers have been reached yet.
The purpose is because i need an event to automatically manipulate visibility. I have an activity with an edittext on the top of the screen, below it, a listview and a linearlayout which are sitting on top of each other. To control what the user sees, i manipulate the visibility. By default, the linearlayout is shown initially, however, when the user is entering text, the listview should be shown instead. The listview should disappear when the user has finished typing, which in this case, the on-screen-keyboard will be closed.
I tried acomplishing the change of visibility using onFocusChange, however, even when the on-screen keyboard disappears, the edittext still retains focus and the linearlayout never reappears.
Below is my implementation of the onFocusChange
#Override
public void onFocusChange(View v, boolean hasFocus)
{
if(v.getId()==R.id.search_screen_keyword_textbox)
{
if(hasFocus)
{
filterSection.setVisibility(View.GONE);
autoComSection.setVisibility(View.VISIBLE);
}
else
{
filterSection.setVisibility(View.VISIBLE);
autoComSection.setVisibility(View.GONE);
}
}
else if(v.getId()==R.id.search_screen_location_textbox)
{
if(hasFocus)
{
filterSection.setVisibility(View.GONE);
autoComSection.setVisibility(View.VISIBLE);
}
else
{
filterSection.setVisibility(View.VISIBLE);
autoComSection.setVisibility(View.GONE);
}
}
else
{
filterSection.setVisibility(View.VISIBLE);
autoComSection.setVisibility(View.GONE);
}
}
If anyone has any idea about it do let me know. :D
You can catch the back button when in an edittext, this is what would make the keyboard disappear. Using this method:
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
// Do your thing here
return false;
}
return super.dispatchKeyEvent(event);
}
Search is great: onKeyPreIme or Android API
It seems that this thread has a solution using onConfigurationChanged: How to capture the "virtual keyboard show/hide" event in Android?

How to watch multiple edittext boxes for a softkey enter or done press?

I have 14 edittext boxes that a user can change at will. When the text is changed in one of them, a softpad key press on the 'enter/next/done' key should re-run a calculation using the new text. I've tried onKey listener but it doesn't work on the soft keyboard, on;y the hard keypad. I've tried a textwatcher like onTextChanged but it reacts and runs the calculation when only a single digit is entered, before the user can input a two or more digit number. So... I hear the onEditorActionListener works on soft keypads to watch for the keypress, but I can't get the syntax right. Here's what I have:
In the onCreate method:
myEdittext1.setOnEditorActionListener(this);
...
myEdittext14.setOnEditorActionListener(this);
Then, outside the onCreate method, I have:
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{ if (event.getKeyCode() == KeyEvent.FLAG_EDITOR_ACTION)
{ //do my calcs}
}
return(true);
}
The code gives me the foreced-close business. Any help would be greatly appreciated.
KeyEvent can be null. You need to check for this situation in your listener.
v The view that was clicked.
actionId Identifier of the action. This will be either the identifier you supplied, or EditorInfo.IME_NULL if being called due to the enter key being pressed.
event If triggered by an enter key, this is the event; otherwise, this is null.
onEditorAction is the appropriate way to listen for finish and Done soft keyboard actions.
so here's a working version:
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{ if (event == null || event.getAction()==KeyEvent.ACTION_UP)
{ //do my calcs
return(true);//reset key event for next press
}
}
The enter key returns a 'null' in the event variable, thats why my version at the top of this post crashed.
Nick's code above worked well too, just remember to set the xml property android:imeOptions=actionDone" for all of the edittext boxes.

Categories

Resources