Issue
I have an activity and inside this activity I have multiple child views :
public class CategoriesActivity extends AppCompatActivity {
private StaggeredGridLayoutManager categoryGridLayoutManager;
private DrawerLayout mDrawerLayout;
private RecyclerView recyclerView;
private NavigationView navigationView;
private List<Category> categoryList;
private Toolbar toolbar;
private MaterialSearchView searchView;
...
}
I have a toolbar and on this toolbar a menu button and a search button.
The main screen looks like this :
[initial screen] (https://imgur.com/bk0GXyOm.png)
When the search button is clicked, the search view opens on top of the existing list view and it looks like this :
[search screen] (https://imgur.com/XefVGFwm.png)
I am interested to test the functionality of the search, more precisely, to test with Espresso the action of clicking on each of the rows of the search view (e.g. check click on 'Hello', then check click on 'Bonjour', etc).
What I have until now is the following (getting the number of suggestions works):
@RunWith(AndroidJUnit4.class)
public class CategoryActivityInstrumentedTests {
@Rule
public ActivityTestRule<CategoriesActivity> activityActivityTestRule = new ActivityTestRule<CategoriesActivity>(CategoriesActivity.class);
@Before
public void init(){
//activityActivityTestRule.getActivity().getSupportFragmentManager().beginTransaction();
Utils.level = 2;
}
@Test
public void TestSuggestions(){
onView(withId(R.id.action_search)).perform(click());
onView(withId(R.id.search_view)).perform(new MyCustomViewAction());
}
public class MyCustomViewAction implements ViewAction {
int size = 0;
@Override
public Matcher<View> getConstraints(){
return isAssignableFrom(MaterialSearchView.class);
}
@Override
public String getDescription(){
return "whatever, size = " + size;
}
@Override
public void perform(UiController uiController, View view){
MaterialSearchView yourCustomView = (MaterialSearchView) view;
size = yourCustomView.getSuggestionsCount();
System.out.println(size);
yourCustomView.mSuggestionsListView.performItemClick(yourCustomView.mSuggestionsListView.getAdapter().getView(1, null, null), 1, yourCustomView.mSuggestionsListView.getAdapter().getItemId(1));
//getItemAtPosition(0) toString(); // .performClick();
Log.e(Constants.TAG_CategoriesActivity, " size = " + size);
}
}
}
The problem is I cannot get this list (the search view contains a suggestions list) in this activity, and so, I cannot perform a click action on the elements of this view.
When I perform the click inside MyCustomViewAction it works but I get a null pointer exception in my main activity because the viewGroup is not initialized.
This is the code of my search view :
public class MaterialSearchView extends FrameLayout implements Filter.FilterListener {
//Views
private View mSearchLayout;
private View mTintView;
public ListView mSuggestionsListView;
private EditText mSearchSrcTextView;
private ImageButton mBackBtn;
private ImageButton mVoiceBtn;
private ImageButton mEmptyBtn;
private RelativeLayout mSearchTopBar;
...
}
Any ideas ? Thanks!
EDIT
I tried the following calls in my test method TestSuggestions() :
onData(allOf(withText("Bonjour"))) // Find the row in the list
.inAdapterView(withId(R.id.search_view)) // Find the list in the view hierarchy
.perform(click());
I got the following exception :
`I/TestRunner: android.support.test.espresso.PerformException: Error performing 'load adapter data' on view 'with id: com...:id/search_view'.`
Solution
I finally found the solutions (there are at least 2 solutions):
First solution :
@Test
public void TestSuggestions1(){
for (int i=0 ; i<4081; i++) {
onView(withId(R.id.action_search)).perform(click()); // opens the search
Espresso.pressBack(); // performs the go back action to dismiss the keyboard
onData(anything()) // selects the actual item at the desired position (which opens another activity)
.atPosition(i)
.perform(click());
Espresso.pressBack(); // performs the go back action from the newer activity
Log.e("TestSuggestions", " i = " + i);
}
}
I go until 4081 because that's the number of suggestions I have.
Second solution :
@Test
public void TestSuggestions2() {
for (i = 0; i < 4081; i++) {
onView(withId(R.id.action_search)).perform(click()); // opens the search
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
Espresso.pressBack(); // performs the go back action from the newer activity
onView(withId(R.id.search_view)).perform(new MyCustomViewAction()); // selects the actual item at the desired position (which opens another activity)
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
Espresso.pressBack();
}
}
with the following MyCustomViewAction :
public class MyCustomViewAction implements ViewAction {
int size = 0;
@Override
public Matcher<View> getConstraints(){
return isAssignableFrom(MaterialSearchView.class);
}
@Override
public String getDescription(){
return "whatever, size = " + size;
}
@Override
public void perform(UiController uiController, View view){
MaterialSearchView yourCustomView = (MaterialSearchView) view;
size = yourCustomView.getSuggestionsCount();
yourCustomView.mSuggestionsListView.performItemClick(yourCustomView.mSuggestionsListView.getAdapter().getView(i, null, null), i, yourCustomView.mSuggestionsListView.getAdapter().getItemId(i));
Log.e(Constants.TAG_CategoriesActivity, " size = " + size);
}
}
where i is a global variable in my TestClass which starts at 0.
Answered By - R13mus
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.