[reading list] Support different reading lists for back gesture
- Store the most recently used url when CTA is launched from reading
list.
- Use ReadingListBackPressHandler for all RL back gestures (reduces
code duplication).
Bug: 41497486
Change-Id: Ide40fd1bc3821aeeb2f5d4ca991c5d5c52b6644f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5271343
Commit-Queue: Brandon Wylie <wylieb@google.com>
Reviewed-by: Sky Malice <skym@chromium.org>
Reviewed-by: Calder Kitagawa <ckitagawa@chromium.org>
Reviewed-by: Lijin Shen <lazzzis@google.com>
Cr-Commit-Position: refs/heads/main@{#1258668}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 7bb804cf..b46184c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -164,7 +164,6 @@
import org.chromium.chrome.browser.quick_delete.QuickDeleteDelegateImpl;
import org.chromium.chrome.browser.quick_delete.QuickDeleteMetricsDelegate;
import org.chromium.chrome.browser.read_later.ReadingListBackPressHandler;
-import org.chromium.chrome.browser.read_later.ReadingListUtils;
import org.chromium.chrome.browser.reengagement.ReengagementNotificationController;
import org.chromium.chrome.browser.search_engines.SearchEngineChoiceNotification;
import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
@@ -1185,10 +1184,9 @@
TaskTraits.UI_DEFAULT,
mCallbackController.makeCancelable(
this::maybeCreateIncognitoTabSnapshotController));
- if (BackPressManager.isEnabled()) {
- PostTask.postTask(TaskTraits.UI_DEFAULT, this::initializeBackPressHandlers);
- }
-
+ // Always call into this function, even if BackPressManager is disabled to initialize
+ // back press managers which reduce code duplication in this class.
+ PostTask.postTask(TaskTraits.UI_DEFAULT, this::initializeBackPressHandlers);
PostTask.postTask(
TaskTraits.UI_DEFAULT,
mCallbackController.makeCancelable(
@@ -3100,9 +3098,9 @@
if (type == TabLaunchType.FROM_READING_LIST) {
assert !isTablet() : "Not expecting to see FROM_READING_LIST on tablets";
- ReadingListUtils.showReadingList(currentTab.isIncognito());
+ assert mReadingListBackPressHandler != null;
+ mReadingListBackPressHandler.handleBackPress();
BackPressManager.record(BackPressHandler.Type.SHOW_READING_LIST);
- if (webContents != null) webContents.dispatchBeforeUnload(false);
return true;
}
@@ -3176,6 +3174,14 @@
}
private void initializeBackPressHandlers() {
+ // Initialize some back press handlers early to reduce code duplication.
+ mReadingListBackPressHandler =
+ new ReadingListBackPressHandler(getActivityTabProvider(), mBookmarkModelSupplier);
+
+ if (!BackPressManager.isEnabled()) {
+ return;
+ }
+
mBackPressManager.setHasSystemBackArm(true);
if (mReturnToChromeBackPressHandler == null && !isTablet()) {
mIsHandleTabSwitcherShownEnabled =
@@ -3193,9 +3199,7 @@
mReturnToChromeBackPressHandler,
BackPressHandler.Type.TAB_RETURN_TO_CHROME_START_SURFACE);
}
- if (mReadingListBackPressHandler == null && !isTablet()) {
- mReadingListBackPressHandler =
- new ReadingListBackPressHandler(getActivityTabProvider());
+ if (!isTablet()) {
mBackPressManager.addHandler(
mReadingListBackPressHandler, BackPressHandler.Type.SHOW_READING_LIST);
}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUiState.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUiState.java
index 13ff842..7672119 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUiState.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUiState.java
@@ -73,7 +73,7 @@
/**
* @see #createStateFromUrl(Uri, BookmarkModel).
*/
- static BookmarkUiState createStateFromUrl(String url, BookmarkModel bookmarkModel) {
+ public static BookmarkUiState createStateFromUrl(String url, BookmarkModel bookmarkModel) {
if (SHOPPING_FILTER_URL.equals(url)) {
return createShoppingFilterState();
} else {
@@ -130,6 +130,10 @@
mSearchText = queryString;
}
+ public @Nullable BookmarkId getFolder() {
+ return mFolder;
+ }
+
@Override
public int hashCode() {
return 31 * mUrl.hashCode() + mUiMode + Objects.hashCode(mSearchText);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
index 6268222..574dc432 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
@@ -624,7 +624,7 @@
* @return The parent {@link BookmarkId} that the user used the last time or null if the user
* has never selected a parent folder to use.
*/
- static BookmarkId getLastUsedParent() {
+ public static @Nullable BookmarkId getLastUsedParent() {
SharedPreferencesManager preferences = ChromeSharedPreferences.getInstance();
if (!preferences.contains(ChromePreferenceKeys.BOOKMARKS_LAST_USED_PARENT)) return null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadingListBackPressHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadingListBackPressHandler.java
index 05b0b5cb..a7bdb023 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadingListBackPressHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadingListBackPressHandler.java
@@ -7,10 +7,16 @@
import org.chromium.base.lifetime.Destroyable;
import org.chromium.base.supplier.ObservableSupplier;
import org.chromium.base.supplier.ObservableSupplierImpl;
+import org.chromium.base.supplier.OneShotCallback;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.ActivityTabProvider.ActivityTabTabObserver;
+import org.chromium.chrome.browser.bookmarks.BookmarkFeatures;
+import org.chromium.chrome.browser.bookmarks.BookmarkModel;
+import org.chromium.chrome.browser.bookmarks.BookmarkUiState;
+import org.chromium.chrome.browser.bookmarks.BookmarkUtils;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabLaunchType;
+import org.chromium.components.bookmarks.BookmarkId;
import org.chromium.components.browser_ui.widget.gesture.BackPressHandler;
import org.chromium.content_public.browser.WebContents;
@@ -24,22 +30,54 @@
private final ActivityTabProvider mActivityTabProvider;
private final ActivityTabTabObserver mActivityTabTabObserver;
- public ReadingListBackPressHandler(ActivityTabProvider activityTabProvider) {
+ private BookmarkId mLastUsedParent;
+
+ public ReadingListBackPressHandler(
+ ActivityTabProvider activityTabProvider,
+ ObservableSupplier<BookmarkModel> bookmarkModelSupplier) {
mActivityTabProvider = activityTabProvider;
mActivityTabTabObserver =
new ActivityTabTabObserver(mActivityTabProvider, true) {
@Override
protected void onObservingDifferentTab(Tab tab, boolean hint) {
onBackPressStateChanged();
+
+ // If this tab should intercept back press, start the process of tracking
+ // the last url so that it can be reopened.
+ if (shouldInterceptBackPress()) {
+ new OneShotCallback<>(
+ bookmarkModelSupplier,
+ ReadingListBackPressHandler.this::setupLastUsedState);
+ }
}
};
}
+ // After {@link BookmarkModel} is available, load it then query the last used URL and store it
+ // in a {@link BookmarkId} which will be used to handle the back press.
+ private void setupLastUsedState(BookmarkModel bookmarkModel) {
+ bookmarkModel.finishLoadingBookmarkModel(
+ () -> {
+ // Note: there's a slight (but unlikely) chance the the user changed the last
+ // used url prior
+ // to tracking it here.
+ BookmarkUiState lastUsedState =
+ BookmarkUiState.createStateFromUrl(
+ BookmarkUtils.getLastUsedUrl(), bookmarkModel);
+ mLastUsedParent = lastUsedState.getFolder();
+ });
+ }
+
@Override
public @BackPressResult int handleBackPress() {
Tab tab = mActivityTabProvider.get();
int result = shouldInterceptBackPress() ? BackPressResult.SUCCESS : BackPressResult.FAILURE;
- ReadingListUtils.showReadingList(tab.isIncognito());
+ if (BookmarkFeatures.isBookmarksAccountStorageEnabled()) {
+ BookmarkUtils.showBookmarkManager(null, mLastUsedParent, tab.isIncognito());
+ } else {
+ ReadingListUtils.showReadingList(tab.isIncognito());
+ }
+
WebContents webContents = tab.getWebContents();
if (webContents != null) webContents.dispatchBeforeUnload(false);
return result;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/BookmarkTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/BookmarkTest.java
index a789640..2aaeaef3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/BookmarkTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/BookmarkTest.java
@@ -8,6 +8,8 @@
import static androidx.test.espresso.Espresso.pressBack;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.equalTo;
@@ -34,6 +36,7 @@
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
+import androidx.test.espresso.Espresso;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -117,6 +120,7 @@
import org.chromium.components.power_bookmarks.PowerBookmarkMeta;
import org.chromium.components.power_bookmarks.ShoppingSpecifics;
import org.chromium.components.profile_metrics.BrowserProfileType;
+import org.chromium.components.sync.SyncFeatureMap;
import org.chromium.components.sync.SyncService;
import org.chromium.components.sync.SyncService.SyncStateChangedListener;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
@@ -140,7 +144,8 @@
// TODO(1406059): Disabling the shopping CPA should not be a requirement for these tests.
@DisableFeatures({
ChromeFeatureList.CONTEXTUAL_PAGE_ACTION_PRICE_TRACKING,
- ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS
+ ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS,
+ SyncFeatureMap.ENABLE_BOOKMARK_FOLDERS_FOR_ACCOUNT_STORAGE
})
// TODO(crbug.com/1426138): Investigate batching.
@DoNotBatch(reason = "BookmarkTest has behaviours and thus can't be batched.")
@@ -440,6 +445,25 @@
onView(withText("You'll find your reading list here"));
}
+ @Test
+ @MediumTest
+ @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE})
+ public void testOpenFromReadingListAndNavigateBack() throws Exception {
+ openBookmarkManager();
+ BookmarkTestUtil.waitForBookmarkModelLoaded();
+ runOnUiThreadBlocking(
+ () ->
+ mBookmarkModel.addToReadingList(
+ mBookmarkModel.getLocalOrSyncableReadingListFolder(),
+ "test",
+ new GURL("https://test.com")));
+
+ BookmarkTestUtil.openReadingList(mItemsContainer, mDelegate, mBookmarkModel);
+ onView(withText("test")).perform(click());
+ Espresso.pressBack();
+ onView(withText("test")).check(matches(isDisplayed()));
+ }
+
// TODO(twellington): Write a folder navigation test for tablets that waits for the Tab hosting
// the native page to update its url after navigations.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/ReadingListTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/ReadingListTest.java
index 698721f..30f9e44 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/ReadingListTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/ReadingListTest.java
@@ -73,6 +73,7 @@
import org.chromium.components.browser_ui.widget.RecyclerViewTestUtils;
import org.chromium.components.browser_ui.widget.selectable_list.SelectableListToolbar;
import org.chromium.components.embedder_support.util.UrlConstants;
+import org.chromium.components.sync.SyncFeatureMap;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.content_public.browser.test.util.TouchCommon;
import org.chromium.net.test.EmbeddedTestServer;
@@ -86,7 +87,10 @@
/** Tests for the reading list in the bookmark manager. */
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-@DisableFeatures({ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS})
+@DisableFeatures({
+ ChromeFeatureList.ANDROID_IMPROVED_BOOKMARKS,
+ SyncFeatureMap.ENABLE_BOOKMARK_FOLDERS_FOR_ACCOUNT_STORAGE
+})
@DoNotBatch(reason = "BookmarkTest has behaviours and thus can't be batched.")
public class ReadingListTest {
@Rule
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/AccountBookmarkTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/AccountBookmarkTest.java
index 17b1e16..f065d35 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/AccountBookmarkTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/AccountBookmarkTest.java
@@ -5,11 +5,10 @@
package org.chromium.chrome.browser.bookmarks;
import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
@@ -18,14 +17,11 @@
import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking;
-import android.view.View;
-
import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.espresso.ViewInteraction;
-import androidx.test.espresso.matcher.ViewMatchers;
+import androidx.test.espresso.Espresso;
+import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
-import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -34,10 +30,12 @@
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.DoNotBatch;
import org.chromium.base.test.util.Features;
import org.chromium.base.test.util.Features.DisableFeatures;
import org.chromium.base.test.util.Features.EnableFeatures;
+import org.chromium.base.test.util.Restriction;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.profiles.Profile;
@@ -46,8 +44,11 @@
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.R;
import org.chromium.chrome.test.util.BookmarkTestRule;
+import org.chromium.chrome.test.util.BookmarkTestUtil;
import org.chromium.components.browser_ui.widget.RecyclerViewTestUtils;
import org.chromium.components.sync.SyncFeatureMap;
+import org.chromium.ui.test.util.UiRestriction;
+import org.chromium.url.GURL;
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@@ -98,29 +99,44 @@
checkTopLevelAccountFoldersDisplayed();
}
+ @Test
+ @MediumTest
+ @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE})
+ @EnableFeatures({ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS})
+ @DisabledTest(
+ message =
+ "Enable this test when reading list is available w/o restart crbug.com/1510547")
+ public void testOpenFromReadingListAndNavigateBack() throws Exception {
+ mSyncTestRule.setSelectedTypes(true, null);
+ CriteriaHelper.pollUiThread(() -> mBookmarkModel.getAccountReadingListFolder() != null);
+ RecyclerViewTestUtils.waitForStableMvcRecyclerView(
+ mBookmarkManagerCoordinator.getRecyclerViewForTesting());
+
+ runOnUiThreadBlocking(
+ () ->
+ mBookmarkModel.addToReadingList(
+ mBookmarkModel.getAccountReadingListFolder(),
+ "test",
+ new GURL("https://test.com")));
+
+ BookmarkTestUtil.getRecyclerRowViewInteraction(
+ "Reading list", /* isAccountBookmark= */ true)
+ .perform(click());
+ onView(withText("test")).perform(click());
+ Espresso.pressBack();
+ onView(withText("test")).check(matches(isDisplayed()));
+ }
+
private void checkTopLevelAccountFoldersDisplayed() {
checkToolbarTitleMatches("Bookmarks");
onView(withText("In your Google Account")).check(matches(isDisplayed()));
- getRecyclerViewItem("Mobile bookmarks", true).check(matches(isDisplayed()));
+ BookmarkTestUtil.getRecyclerRowViewInteraction("Mobile bookmarks", true)
+ .check(matches(isDisplayed()));
onView(withText("Only on this device")).check(matches(isDisplayed()));
- getRecyclerViewItem("Mobile bookmarks", false).check(matches(isDisplayed()));
- getRecyclerViewItem("Reading list", false).check(matches(isDisplayed()));
- }
-
- private ViewInteraction getRecyclerViewItem(String text, boolean isAccountBookmark) {
- return onView(getRecyclerItemMatcher(text, isAccountBookmark));
- }
-
- private Matcher<View> getRecyclerItemMatcher(String text, boolean isAccountBookmark) {
- ViewMatchers.Visibility visibility =
- isAccountBookmark ? ViewMatchers.Visibility.GONE : ViewMatchers.Visibility.VISIBLE;
- return allOf(
- withId(R.id.container),
- hasDescendant(withText(text)),
- hasDescendant(
- allOf(
- withId(R.id.local_bookmark_image),
- withEffectiveVisibility(visibility))));
+ BookmarkTestUtil.getRecyclerRowViewInteraction("Mobile bookmarks", false)
+ .check(matches(isDisplayed()));
+ BookmarkTestUtil.getRecyclerRowViewInteraction("Reading list", false)
+ .check(matches(isDisplayed()));
}
// Checks the toolbar title against the given string.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkOpenerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkOpenerTest.java
index d246eea..b0363ab 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkOpenerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkOpenerTest.java
@@ -17,6 +17,7 @@
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.chromium.base.metrics.RecordHistogram;
@@ -24,6 +25,8 @@
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.CriteriaHelper;
import org.chromium.base.test.util.DoNotBatch;
+import org.chromium.base.test.util.Features;
+import org.chromium.base.test.util.Features.DisableFeatures;
import org.chromium.base.test.util.UserActionTester;
import org.chromium.chrome.browser.app.bookmarks.BookmarkActivity;
import org.chromium.chrome.browser.flags.ChromeSwitches;
@@ -38,6 +41,7 @@
import org.chromium.components.bookmarks.BookmarkId;
import org.chromium.components.browser_ui.widget.RecyclerViewTestUtils;
import org.chromium.components.embedder_support.util.UrlConstants;
+import org.chromium.components.sync.SyncFeatureMap;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.ui.accessibility.AccessibilityState;
import org.chromium.url.GURL;
@@ -49,10 +53,13 @@
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@DoNotBatch(reason = "Tabs can't be closed reliably between tests.")
+@DisableFeatures({SyncFeatureMap.ENABLE_BOOKMARK_FOLDERS_FOR_ACCOUNT_STORAGE})
public class BookmarkOpenerTest {
@Rule
public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
+ @Rule public TestRule mProcessor = new Features.JUnitProcessor();
+
private BookmarkOpener mBookmarkOpener;
private BookmarkModel mBookmarkModel;
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/BookmarkTestUtil.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/BookmarkTestUtil.java
index feecea6..704a330 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/BookmarkTestUtil.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/BookmarkTestUtil.java
@@ -6,9 +6,16 @@
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
+import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
+import static org.hamcrest.Matchers.allOf;
+
import androidx.recyclerview.widget.RecyclerView;
+import androidx.test.espresso.ViewInteraction;
+import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.platform.app.InstrumentationRegistry;
import org.hamcrest.core.IsInstanceOf;
@@ -16,6 +23,7 @@
import org.chromium.base.ApplicationStatus;
import org.chromium.base.test.util.Criteria;
import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.app.bookmarks.BookmarkActivity;
import org.chromium.chrome.browser.app.bookmarks.BookmarkAddEditFolderActivity;
@@ -175,4 +183,22 @@
return false;
});
}
+
+ /**
+ * Returns the {@link ViewInteraction} for a bookmark row with the given text and account-ness.
+ * The return value can be used to make assertions about.
+ */
+ public static ViewInteraction getRecyclerRowViewInteraction(
+ String text, boolean isAccountBookmark) {
+ ViewMatchers.Visibility visibility =
+ isAccountBookmark ? ViewMatchers.Visibility.GONE : ViewMatchers.Visibility.VISIBLE;
+ return onView(
+ allOf(
+ withId(R.id.container),
+ hasDescendant(withText(text)),
+ hasDescendant(
+ allOf(
+ withId(R.id.local_bookmark_image),
+ withEffectiveVisibility(visibility)))));
+ }
}