Skip to content

Commit

Permalink
Fix issue #283 assertDisplayedAtPosition doesn't assert displayed lis… (
Browse files Browse the repository at this point in the history
#354)

* Fix issue #283 assertDisplayedAtPosition doesn't assert displayed list view

I removed the scrollListToPosition from assertDisplayedAtPosition as it is done in assertCustomAssertionAtPosition.

isShowOnScreen checks to see if the view is visible to the user.
getShownViewsById retuns a list of all views that match the viewId and are visible to the user.

* Fix tests

* With text barista (#388)

* Create withCompatText

* Move all withText(String) to withCompatText(String)

* Add tests

* Use custom matchers, no need to creater one

* Fix  tests

* Fix test

Co-authored-by: Rafa Vázquez <[email protected]>
Co-authored-by: Roc Boronat <[email protected]>
Co-authored-by: Bernat Borrás Paronella <[email protected]>
  • Loading branch information
4 people authored Jul 5, 2021
1 parent 1cea3aa commit c2b1810
Show file tree
Hide file tree
Showing 6 changed files with 408 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.adevinta.android.barista.assertion

import android.content.res.Resources
import android.graphics.Rect
import android.view.View
import android.view.ViewGroup
import android.widget.ListView
import androidx.annotation.DrawableRes
import androidx.annotation.IdRes
Expand Down Expand Up @@ -74,18 +77,16 @@ object BaristaListAssertions {

@JvmStatic
fun assertDisplayedAtPosition(@IdRes listId: Int, position: Int, @IdRes targetViewId: Int = NO_VIEW_ID, text: String) {
scrollListToPosition(listId, position)

assertCustomAssertionAtPosition(
listId = listId,
position = position,
targetViewId = targetViewId,
viewAssertion = ViewAssertions.matches(
CoreMatchers.anyOf(
ViewMatchers.withChild(withCompatText(text)),
withCompatText(text)
)
listId = listId,
position = position,
targetViewId = targetViewId,
viewAssertion = ViewAssertions.matches(
CoreMatchers.anyOf(
ViewMatchers.withChild(withCompatText(text)),
withCompatText(text)
)
)
)
}

Expand All @@ -96,46 +97,58 @@ object BaristaListAssertions {

@JvmStatic
fun assertDisplayedAtPosition(@IdRes listId: Int, position: Int, @IdRes targetViewId: Int = NO_VIEW_ID, @StringRes textId: Int) {
scrollListToPosition(listId, position)

assertCustomAssertionAtPosition(
listId = listId,
position = position,
targetViewId = targetViewId,
viewAssertion = ViewAssertions.matches(
CoreMatchers.anyOf(
ViewMatchers.withChild(ViewMatchers.withText(textId)),
ViewMatchers.withText(textId)
)
listId = listId,
position = position,
targetViewId = targetViewId,
viewAssertion = ViewAssertions.matches(
CoreMatchers.anyOf(
ViewMatchers.withChild(ViewMatchers.withText(textId)),
ViewMatchers.withText(textId)
)
)
)
}

@JvmStatic
fun assertDrawableDisplayedAtPosition(@IdRes listId: Int, position: Int, @IdRes targetViewId: Int = NO_VIEW_ID, @DrawableRes drawableRes: Int) {
fun assertDrawableDisplayedAtPosition(
@IdRes listId: Int,
position: Int,
@IdRes targetViewId: Int = NO_VIEW_ID,
@DrawableRes drawableRes: Int
) {
scrollListToPosition(listId, position)

assertCustomAssertionAtPosition(
listId = listId,
position = position,
targetViewId = targetViewId,
viewAssertion = ViewAssertions.matches(
CoreMatchers.anyOf(
ViewMatchers.hasDescendant(DrawableMatcher.withDrawable(drawableRes)),
DrawableMatcher.withDrawable(drawableRes)
)
listId = listId,
position = position,
targetViewId = targetViewId,
viewAssertion = ViewAssertions.matches(
CoreMatchers.anyOf(
ViewMatchers.hasDescendant(DrawableMatcher.withDrawable(drawableRes)),
DrawableMatcher.withDrawable(drawableRes)
)
)
)
}

@JvmStatic
fun assertCustomAssertionAtPosition(@IdRes listId: Int, position: Int, @IdRes targetViewId: Int = NO_VIEW_ID, viewAssertion: ViewAssertion) {
fun assertCustomAssertionAtPosition(
@IdRes listId: Int,
position: Int,
@IdRes targetViewId: Int = NO_VIEW_ID,
viewAssertion: ViewAssertion
) {
scrollListToPosition(listId, position)

Espresso.onView(atPositionOnList(listId = listId,
Espresso.onView(
atPositionOnList(
listId = listId,
position = position,
targetViewId = targetViewId))
.check(viewAssertion)
targetViewId = targetViewId
)
)
.check(viewAssertion)
}

private fun atPositionOnList(@IdRes listId: Int, position: Int, @IdRes targetViewId: Int): Matcher<View> {
Expand All @@ -162,13 +175,18 @@ object BaristaListAssertions {
var childView: View? = null

if (childView == null) {
val listView: ListView? = view.rootView.findViewById(listViewId) as ListView
if (listView != null && listView.id == listViewId) {
val positionOnScreen = position - listView.firstVisiblePosition
val viewAtPosition = listView.getChildAt(positionOnScreen)
val views = getShownViewsById(view.rootView as ViewGroup, listViewId)
if (views != null && views.isNotEmpty()) {
val listView: ListView = views[0] as ListView
if (listView.id == listViewId) {
val positionOnScreen = position - listView.firstVisiblePosition
val viewAtPosition = listView.getChildAt(positionOnScreen)

viewAtPosition?.let {
childView = it
viewAtPosition?.let {
childView = it
}
} else {
return false
}
} else {
return false
Expand All @@ -187,11 +205,16 @@ object BaristaListAssertions {
var childView: View? = null

if (childView == null) {
val recyclerView: RecyclerView? = view.rootView.findViewById(recyclerViewId) as RecyclerView
if (recyclerView != null && recyclerView.id == recyclerViewId) {
val viewHolder = recyclerView.findViewHolderForAdapterPosition(position)
viewHolder?.let { checkedViewHolder ->
childView = checkedViewHolder.itemView
val views = getShownViewsById(view.rootView as ViewGroup, recyclerViewId)
if (views != null && views.isNotEmpty()) {
val recyclerView: RecyclerView = views[0] as RecyclerView
if (recyclerView.id == recyclerViewId) {
val viewHolder = recyclerView.findViewHolderForAdapterPosition(position)
viewHolder?.let { checkedViewHolder ->
childView = checkedViewHolder.itemView
}
} else {
return false
}
} else {
return false
Expand All @@ -205,4 +228,31 @@ object BaristaListAssertions {
view == targetView
}
}

private fun getShownViewsById(root: ViewGroup, viewId: Int): ArrayList<View>? {
val views = ArrayList<View>()
val childCount = root.childCount
for (i in 0 until childCount) {
val child = root.getChildAt(i)
if (child is ViewGroup) {
views.addAll(getShownViewsById(child, viewId)!!)
}
val childId = child.id
if (childId == viewId && isShowOnScreen(child)) {
views.add(child)
}
}
return views
}

private fun isShowOnScreen(view: View): Boolean {
if (!view.isShown) {
return false
}
val actualPosition = Rect().also { view.getGlobalVisibleRect(it) }
val screen = Resources.getSystem().displayMetrics.run {
Rect(0, 0, widthPixels, heightPixels)
}
return actualPosition.intersect(screen)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.adevinta.android.barista.sample;

import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import static com.adevinta.android.barista.assertion.BaristaListAssertions.assertDisplayedAtPosition;
import static com.adevinta.android.barista.interaction.BaristaSleepInteractions.sleep;
import static com.adevinta.android.barista.interaction.BaristaViewPagerInteractions.swipeViewPagerBack;
import static com.adevinta.android.barista.interaction.BaristaViewPagerInteractions.swipeViewPagerForward;

@RunWith(AndroidJUnit4.class)
public class ListViewWithDifferentDataInsideViewPagerTest {

@Rule
public ActivityTestRule<ListViewsWithDifferentDataInsideViewPagerActivity> activityRule =
new ActivityTestRule<>(ListViewsWithDifferentDataInsideViewPagerActivity.class);

@Test
public void checkClickRecyclerViewItem() {
swipeViewPagerForward(R.id.pager);
sleep(500);

assertDisplayedAtPosition(R.id.listview, 1, "Marionberry");

swipeViewPagerBack(R.id.pager);
sleep(500);

assertDisplayedAtPosition(R.id.listview, 0, android.R.id.text1, "Apple");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.adevinta.android.barista.sample;

import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import static com.adevinta.android.barista.assertion.BaristaListAssertions.assertDisplayedAtPosition;
import static com.adevinta.android.barista.interaction.BaristaSleepInteractions.sleep;
import static com.adevinta.android.barista.interaction.BaristaViewPagerInteractions.swipeViewPagerBack;
import static com.adevinta.android.barista.interaction.BaristaViewPagerInteractions.swipeViewPagerForward;

@RunWith(AndroidJUnit4.class)
public class RecyclerViewWithDifferentDataInsideViewPagerTest {

@Rule
public ActivityTestRule<RecyclerViewsWithDifferentDataInsideViewPagerActivity> activityRule =
new ActivityTestRule<>(RecyclerViewsWithDifferentDataInsideViewPagerActivity.class);

@Test
public void checkClickRecyclerViewItem() {
swipeViewPagerForward(R.id.pager);
sleep(500);

assertDisplayedAtPosition(R.id.recycler, 1, "Marionberry");

swipeViewPagerBack(R.id.pager);
sleep(500);

assertDisplayedAtPosition(R.id.recycler, 0, R.id.textview, "Apple");
}
}
2 changes: 2 additions & 0 deletions sample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
android:theme="@style/AppTheme.NoActionBar"
/>
<activity android:name=".RecyclerViewsInsideViewPagerActivity"/>
<activity android:name=".RecyclerViewsWithDifferentDataInsideViewPagerActivity"/>
<activity android:name=".ListViewsWithDifferentDataInsideViewPagerActivity"/>
<activity android:name=".NestedScrollViewActivity"/>
<activity android:name=".CameraActivity">
<intent-filter>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package com.adevinta.android.barista.sample;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

public class ListViewsWithDifferentDataInsideViewPagerActivity extends AppCompatActivity {

private static final int NUM_PAGES = 2;

private static final String[] FRUIT_LIST_ONE = {
"Apple", "Apricot", "Avocado", "Banana", "Bilberry", "Blackberry", "Blackcurrant",
"Blueberry", "Boysenberry", "Currant", "Cherry", "Cherimoya", "Cloudberry", "Coconut",
"Cranberry", "Cucumber", "Custardapple", "Damson", "Date", "Dragonfruit", "Durian",
"Elderberry", "Feijoa", "Fig", "Gojiberry", "Gooseberry", "Grape", "Raisin", "Grapefruit",
"Guava", "Honeyberry", "Huckleberry", "Jabuticaba", "Jackfruit", "Jambul", "Jujube",
"Juniperberry", "Kiwifruit", "Kumquat", "Lemon", "Lime", "Loquat", "Longan", "Lychee"};

private static final String[] FRUIT_LIST_TWO = {"Mango", "Marionberry", "Melon", "Cantaloupe", "Honeydew", "Watermelon", "Miraclefruit",
"Mulberry", "Nectarine", "Nance", "Olive", "Orange", "Bloodorange", "Clementine", "Mandarine",
"Tangerine", "Papaya", "Passionfruit", "Peach", "Pear", "Persimmon", "Physalis", "Plantain",
"Plum", "Prune(driedplum)", "Pineapple", "Plumcot(orPluot)", "Pomegranate", "Pomelo",
"Purplemangosteen", "Quince", "Raspberry", "Salmonberry", "Rambutan", "Redcurrant",
"Salalberry", "Salak", "Satsuma", "Starfruit", "Solanumquitoense", "Strawberry", "Tamarillo",
"Tamarind", "Uglifruit", "Yuzu"};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewpager);

ViewPager mPager = findViewById(R.id.pager);
PagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
}

private static class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}

@Override
public Fragment getItem(int position) {
return new ScreenSlidePageFragment(position);
}

@Override
public int getCount() {
return NUM_PAGES;
}
}

public static class ScreenSlidePageFragment extends Fragment {

private int position;

public ScreenSlidePageFragment(int position) {
this.position = position;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.activity_lists, container, false);

LinearLayout listsContainer = rootView.findViewById(R.id.multi_list_container);

ListView listView = new ListView(requireContext());
if (position == 0) {
listView.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, FRUIT_LIST_ONE));
} else {
listView.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, FRUIT_LIST_TWO));
}
listView.setId(R.id.listview);
listsContainer.addView(listView,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.MATCH_PARENT,
1
));

return rootView;
}
}
}
Loading

0 comments on commit c2b1810

Please sign in to comment.