Testing searchview in android - Instrumentation testing - android

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)))

Related

Android Espresso : How to perform an action when the view is displayed on the screen?

I want to add instrumental tests to my Android app.
There is a login screen that perform a load to a certain data first and when succeed it display to the user the auth. forms (username+password).
I want to perform an action to the EditText widgets like typeText like below:
#Test
fun agnetlogin() {
onView(withId(R.id.edt_login)).perform(typeText(loginToBeTyped), closeSoftKeyboard())
onView(withId(R.id.edt_password)).perform(typeText(passwordToBeTyped), closeSoftKeyboard())
onView(withId(R.id.btn_sign_in)).perform(click())
}
but I get the error that the views doesn't exit in hierarchy and it's normal because the visibilities is set to gone when data is charging.
#J.M.J, the good practice to check whether the view is displayed in the view or not. It also avoids errors, you can check for whether the view is displayed or not as below example.
onView(withId(R.id.my_view))
.perform(click())
.check(matches(isDisplayed()));
or if you know that the view is already presented, you can check with a specific name like
onView(withId(R.id.my_view))
.check(matches(withText("Hello Espresso!")))
.perform(click())
.check(matches(isDisplayed()));
You could add an Idlingrecource manager which will wait until your input fields are loaded before performing actions on them:
https://medium.com/azimolabs/wait-for-it-idlingresource-and-conditionwatcher-602055f32356
A quick and dirty solution might be to put a sleep (e.g. for 5 seconds) in front of your code:
Thread.sleep(5000);
onView(withId(R.id.my_view))
.perform(click())
.check(matches(isDisplayed()));

Android Espresso onData strange behavior

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...

How to launch suggestions immediately in Android searchable before the user has even started typing

I'm doing some research on ContentProviders and Searchable configurations. I've set up a class that extends a Content Provider with a database that provides suggestions from a database as the user types. This uses the Search Manager paradigm (not a SearchView).
Up to this point, everything works great.
What I'd like to do and am having problems with is to display some suggestions before the user starts typing, after he launches the search. Setting the property 'android:searchSuggestThreshold="0" ' in the searchable.xml only works if the user actually taps into the search textbox after launching it - I would like to display suggestions immediately after the search has been launched (i.e. not wait for the user to do anything else).
Any ideas?
Edit: An example of what I'm talking about is the search functionality in the Google Play Store app - right when a user taps the Magnifying glass for search, a list of recent suggestions immediately pops up.
Well after spending many hours on this I have finally found a way to achieve what I needed. Here's the answer so perhaps fewer other developers suffer:
The SearchView for the search mode has a text changed listener, and only when the text changes does it fire off a request for suggestions. Obviously, for the initial state nothing has changed so it doesn't request suggestions through the query() function.
In order to "trick" the SearchView into thinking the text has changed, you can do the following:
#Override
public boolean onSearchRequested()
{
final SearchManager searchManager = (SearchManager) getSystemService( SEARCH_SERVICE );
searchManager.startSearch( " ", true, getComponentName(), null, false );
return super.onSearchRequested();
}

"Resetting" Robotium searchText

I have a unique situation here. I am testing an app using Robotium and I am doing this under "black box" conditions. In my test, I have a tab titled 'all' and it is at the top of the screen, and I want to test that when it is clicked, all the available items are listed. What happens though, is instead of clicking the 'all' tab, the app titled "Advanced Call Manager" is being clicked. I assume that this is because 'all' is part of 'call' and due to the the way Robotium works, it clicks on 'all' even though it is part of 'call'. After you look at my code, you might understand what my issue is.
So my question is:
Is there a way to "reset" Robotium so that when it does its search for text, it starts at the top of the page? Here is my code:
solo.waitForText("all");
bw.write("Verify presence of 'all' filter on " + BUSINESS + "-COMMUNICATION page\",\"");
if(solo.searchText("all")==false){
bw.write("FAILED \",\" \'all\' filter not found \"\n\"");
}else if(solo.searchText("all")==true){
bw.write("PASSED \",\" \'all\' filter present\"\n\"");
bw.write("Verify functionality of 'all' filter\",\"");
solo.clickOnText("all");
solo.sleep(5000);
solo.takeScreenshot();
bw.write("Screenshot taken\",\"" +"See photo: "+ photoFormat.format(new Date()).toString()+"\"\n\"");
}
Any help would be appreciated!
The string passed to solo.clickOnText() is actually a RegEx. So I think you can solve your problem by passing a RegEx that matches 'all' but not 'call'.
ViewGroup class will be helpful in this case as you are using tabs in your code.Now find the view using getChildAt() method.
ViewGroup tabs = (ViewGroup) solo.getView(android.R.id.tabs);
View viewYouWantToDoStuffWith = tabs.getChildAt(x); //change x to the index you want.
Now you can perform the click event on tab like below.
solo.clickOnView(viewYouWantToDoStuffWith);

Android: Prevent text field pop-up when entering text in a SearchView

Hello Android developers,
I've got a problem with the Android SearchView widget. What I'm trying to do is to attach a "live" text filter to my ListView (text input automatically refreshes filter results). It works actually fine and it was no huge effort to get it working on my ListActivity with these lines:
private SearchView listFilter;
this.listFilter = (SearchView) findViewById(R.id.listFilter);
this.listFilter.setOnQueryTextListener(this);
this.listFilter.setSubmitButtonEnabled(false);
this.getListView().setOnItemClickListener(this);
this.getListView().setTextFilterEnabled(true);
// from OnQueryTextListener
public boolean onQueryTextChange(String newText) {
if (newText.isEmpty()) {
this.getListView().clearTextFilter();
} else {
this.getListView().setFilterText(newText);
}
return true;
}
And here the xml widget declaration
<SearchView
android:id="#+id/listFilter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:iconifiedByDefault="false"
android:queryHint="enter text to filter" />
Now what my problem is that every time I enter text into the SearchView, a strange text field pops up instantly showing the same text as I just entered which is kind of useless since I can see my input in the SearchView itself and it partly blocks the sight on my list entries, which is just annoying.
Is there any way to prevent that text field from popping up on typing into the SearchView? I couldn't find any property neither on the xml defined widget options nor on the java class reference.
I know there is another way to provide the filter functionality by using EditText and TextWatcher, but then I have to handle the filtering all by myself and couldn't profit from the SearchView handling it for me.
Any suggestions are appreciated.
Best regards
Felix
i found out how to get rid of that ugly popup window. The trick is to work with filter directly.The code below assumes you have implemented filterable in your customAdapter.
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)) {
m_listView.clearTextFilter();
} else {
ContactsAdapter ca = (ContactsAdapter)lv.getAdapter();
ca.getFilter().filter(newText);
//following line was causing the ugly popup window.
//m_listView.setFilterText(newText);
}
return true;
}

Categories

Resources