Android Espresso onData strange behavior - android

I have an Activity with ListView (id: android.R.id.list). The ListView shows information from a custom adapter, and I want to use Espresso to click on a specific view in a specific item: I want to click the view with id R.id.continueButton in the item that shows information from the object testOrder.
My test is:
onData(is(sameAsOrder(testOrder)))
.onChildView(withId(R.id.continueButton))
.inAdapterView(withId(android.R.id.list))
.perform(click());
where sameAsOrder() is:
public static Matcher<Object> sameAsOrder(final Order order) {
assertNotNull(order);
return new BoundedMatcher<Object, Order>(Order.class) {
#Override
public boolean matchesSafely(Order myOrder) {
return myOrder.getId().equals(order.getId());
}
#Override
public void describeTo(Description description) {
description.appendText(" with id '" + order.getId() + "'");
}
};
}
I run the tests on my device, but when I load my Order objects from a online server the click happens on the action bar menu, as if I run the Espresso command
openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());
When using dummy data it clicks on the correct list item. Moreover, when using dummy data on the emulator it also clicks on the action bar menu.
If I remove the menu, the test passes without nothing being clicked (as far as I can tell...)
Does anybody have an ideia why that strange behavior happens?
Thanks!

I got it! The strange behavior has nothing to do with onData(). I am using action bar overlay mode. Due to difference on screen sizes from my device to the emulator, and due to different data being used to fill the list (dummy vs. loaded from server), sometimes the item that I want to click on is getting below the action bar. When Espresso tries to click on it, it clicks on the action bar...

Related

Testing searchview in android - Instrumentation testing

I have a searchview in my action bar, where I can press on search button in action bar, write some text, then click on the search button on softkeyboard and then it should display the list of results in recycler view.
I want to test this to see if the results in recyclerview contains the same word as I searched for (The result is list of movies).
For example, if I search for "love" and the result is all movies with names which contains word "love" in it like "P.S. I love you"
I am trying this:
#Test
public void testSearchToolbar() throws Exception {
Instrumentation inst = new Instrumentation();
onView(withId(R.id.action_search)).perform(click());
onView(withId(android.support.design.R.id.search_src_text)).perform(typeText("Seven Samurai"));
inst.sendKeyDownUpSync(KeyEvent.KEYCODE_SEARCH);
onData(withId(R.id.movie_title)).check(matches(isDisplayed()));
}
I see that the text is getting typed in searchview but beyond that test fails.
Can someone help me with this
In 2022 I do this for my case:
onView(withId(R.id.action_search))
.perform(click())
onView(withId(R.id.searchView))
.check(matches(isDisplayed()))
onView(isAssignableFrom(EditText::class.java))
.perform(typeText(query), pressKey(KeyEvent.KEYCODE_ENTER))
Espresso.onView(ViewMatchers.withId(resId))
.check(ViewAssertions.matches(CustomMatchers().recyclerViewSizeMatch(count)))

How to programmaticallly remove submenu from navigation drawer in Android?

I am developing an Android app. Firstly, let me tell you that I am not professional. What I am doing now is I am adding submenu to menu depending on a condition. But I need to do it very often in my app. But my problem is I added a submenu to the menu as first time.
But second time when I update menu depending on condition, existing submenu is not removed and new submenu is appended to navigation drawer. How can I remove submenu that is programmatically added to menu? Why my code is not removing it?
Here is my code
public void updateAuthUI()
{
isLoggedIn = tempStorage.getBoolean(getResources().getString(R.string.pref_is_logged_in),false);
Menu menu = leftDrawer.getMenu();
menu.removeItem(getResources().getInteger(R.integer.logout_item_id));
menu.removeItem(getResources().getInteger(R.integer.login_item_id));
menu.removeItem(getResources().getInteger(R.integer.register_item_id));
SubMenu authSubMenu = menu.addSubMenu("Auth");
if(isLoggedIn)
{
authSubMenu.add(1,getResources().getInteger(R.integer.logout_item_id),99,"Sign out");
}
else{
authSubMenu.add(1,getResources().getInteger(R.integer.register_item_id),97,"Register");
authSubMenu.add(1,getResources().getInteger(R.integer.login_item_id),98,"Sign in").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
openLoginActivity();
item.setChecked(true);
return true;
}
});
}
}
Here is the screenshot of my problem
As you can see Auth submenu is appended without removing existing one.
Try
authSubMenu.clear();
before your first
authSubMenu.add();
I just used SubMenu.clear() in an Android app where I was using a third-party library, and I needed to clear out an unwanted submenu from the action bar. (I actually wanted to remove the submenu completely, and this was the only way I could find to do it. It seemed to work.)
That's different from your situation, where authSubMenu is a menu you just added via menu.addSubMenu("Auth"), so you would expect it to be empty. But, as you've seen, it apparently isn't empty: rather, addSubMenu("Auth") returns the existing submenu of that title. (I can't find documentation to that effect; I'm just going by the results you've reported.)
If that really is the case, as it appears to be, then authSubMenu.clear() will remove all existing items from the submenu.
As #slymm said in a comment you can remove all menu and submenu items using
navigationView.getMenu().clear();
This can be used to remove submenu (and menu elements) and then recreate them with the new required items

listview.pointToPosition providing INVALID value when should not

I am getting information from my application in production, but when I am trying to reproduce the problem I am not able to do it. What I am looking for is any idea (as I am blocked) of how can I try to reproduce the error.
Basically I am having an activities with a listview, toolbar, edittext and admob advertisement.
My listview is composed of a relativealayout containing a textview and one imageview.
With the adapter I am attaching to the textview an OnLongClickListener that starts a drag operation.
To the Listview itself, I am adding an OnDragListener.
#TargetApi(11)
public class myDragEventListener implements View.OnDragListener {
// This is the method that the system calls when it dispatches a drag event to the
// listener.
public boolean onDrag(View v, DragEvent event) {
// Defines a variable to store the action type for the incoming event
final int action = event.getAction();
// Handles each of the expected events
switch(action) {
case DragEvent.ACTION_DRAG_STARTED:
return true;
case DragEvent.ACTION_DROP:
//We detect which is the item where the drop happened on.
int itemPosition = listShop.pointToPosition((int)event.getX(), (int)event.getY());
// An unknown action type was received.
default:
return true;
}
}
}
So, basically we initiate the drag on the textview from the listview item and the drop ends on the listview itself.
This code works properly, but I received from production reports that sometimes the value of itemPosition to be -1. To avoid an exception I can add a simple check, but I am worried about the user experience.
So, what I would like to avoid is a bad user experience with the application not responding properly, and we know is happening due to reports. The problem is that we are not able to reproduce.
Trying to reproduce this error we tried:
Longclick on textview and drop on imageview. (provides correct itemPosition)
Longclick on textivew and drop outside the listview (drag listener not called)
Longclick on textivew and drop at the edge of listview (works ok).
Does somebody has a suggestion of how this "-1" could be reproduced? Theoretically it should not happen.... is the drop (whatever the drag that has been initiated) activates the OnDragListener, that means that the position where the drop occurs is a position of the listview. How can the DragListener be called in a listview in an incorrect position?
Any idea what could be happening?
Ok, I found the problem. My listview covers almost all the screen, and sometimes is feed with items in the list that are not covering the complete list up to the end. When an item is dragged and dropped in the space where there is no item in the list, provide that value.
The problem is that my testing mobile is very small compared to other devices, and that mobile was always having the screen fully covered by items of the list, so any drag/drop operation was always captured.

master/detail template with action menu - right way to show both

Beginner here, targetting sdk v14 and v17 for my learning...no need for older support.
I am using the master/detail template and trying to get an action menu (for SEARCH) to show up both in phone and tablet view. Actually I can get it to work, but I have to duplicate up my code in both ItemDetailActivity.java and ItemListActivity.java
These are the methods that I have to have in both for SEARCH to work:
public boolean onQueryTextChange(String newText) {
public boolean onQueryTextSubmit (String query) {
public boolean onClose () {
I only want to search the "detail", not the "list".
So my question: is there a way to associate the action bar with only the list fragment? That way I can keep the search functions in 1 file.
Thanks!
I'll go ahead and answer what I (think) I know as I don't want to leave this question open.
From tracing in the debugger, it looks to me like the phone activity and the tablet activity are separate and if you want to hook up an actionmenu, you have to hook it up to both separately.

Getting selected text in a WebView via a contextual action bar

It's known to be difficult to get selected text in a WebView because WebView text selection is actually handled by a private class, WebTextView.
However, with the recently released Android 4.0 Design guidelines, there seems to be a glimmer of hope of achieving this through contextual action bars (CABs). It says:
Use CABs whenever you allow the user to select data via long press. You can control the action content of a CAB in order to insert the actions you would like the user to be able to perform.
Am I misinterpreting this? Is there a way to retrieve selected text from a WebView via a CAB?
After a long click and text selection mode begins, I can currently detect when the ActionMode starts and modify the original copy/paste Menu; however, I can't quite figure out how to actually retrieve the selected text.
You can't do that yet with the current API.
I filed a feature request for this - Issue 24841: WebView should allow applications to supply a custom Contextual Action Bar http://code.google.com/p/android/issues/detail?id=24841
Basically, WebView in 4.0 has hardcoded its own Contextual Action Bar (CAB). That CAB has a reference back to the WebView and with that reference, it can get the selected text. I'm not sure how you were able to detect the ActionMode starting and modify the menu, but if you were able to do all of that, then you are stuck because getSelection() is package-private currently. I filed that as a separate issue and linked it to the previous issue above.
You can use javascript to get the selected text: window.getSelection(), and use WebView's addJavascriptInterface function to return the result.
thanks for your information, I have solved a hard issue..
I just want to add some function into the actionmode.
The following is my code, May be helpful to others.
#Override
public ActionMode onWindowStartingActionMode(Callback callback) {
// TODO Auto-generated method stub
ActionMode mode = super.onWindowStartingActionMode(callback);
mode.getMenuInflater().inflate(R.menu.actions, mode.getMenu());
mode.getMenu().findItem(R.id.action_add).setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
// TODO Auto-generated method stub
Log.i("", "onMenuItemClick add ");
return false;
}
});
return mode;
}

Categories

Resources