| Index: chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java
|
| diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9b9bedaa77d97d63e25a0b2c798e21bb3c71f5f2
|
| --- /dev/null
|
| +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java
|
| @@ -0,0 +1,224 @@
|
| +// Copyright 2017 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +package org.chromium.chrome.browser.suggestions;
|
| +
|
| +import android.support.test.filters.MediumTest;
|
| +import android.view.View;
|
| +import android.view.ViewGroup;
|
| +import android.widget.TextView;
|
| +
|
| +import org.chromium.base.ThreadUtils;
|
| +import org.chromium.base.test.util.CallbackHelper;
|
| +import org.chromium.base.test.util.Feature;
|
| +import org.chromium.base.test.util.RetryOnFailure;
|
| +import org.chromium.chrome.R;
|
| +import org.chromium.chrome.browser.ChromeActivity;
|
| +import org.chromium.chrome.browser.UrlConstants;
|
| +import org.chromium.chrome.browser.ntp.ContextMenuManager;
|
| +import org.chromium.chrome.browser.ntp.NewTabPage;
|
| +import org.chromium.chrome.browser.ntp.cards.NewTabPageRecyclerView;
|
| +import org.chromium.chrome.browser.snackbar.SnackbarManager;
|
| +import org.chromium.chrome.browser.tab.Tab;
|
| +import org.chromium.chrome.test.ChromeTabbedActivityTestBase;
|
| +import org.chromium.chrome.test.util.NewTabPageTestUtils;
|
| +import org.chromium.chrome.test.util.browser.RecyclerViewTestUtils;
|
| +import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource;
|
| +import org.chromium.content.browser.test.util.Criteria;
|
| +import org.chromium.content.browser.test.util.CriteriaHelper;
|
| +import org.chromium.content.browser.test.util.TestTouchUtils;
|
| +import org.chromium.net.test.EmbeddedTestServer;
|
| +
|
| +import java.util.concurrent.TimeoutException;
|
| +
|
| +/**
|
| + * Instrumentation tests for {@link TileGroup} on the New Tab Page.
|
| + */
|
| +@RetryOnFailure
|
| +public class TileGroupTest extends ChromeTabbedActivityTestBase {
|
| + private static final String[] FAKE_MOST_VISITED_URLS =
|
| + new String[] {"/chrome/test/data/android/navigate/one.html",
|
| + "/chrome/test/data/android/navigate/two.html",
|
| + "/chrome/test/data/android/navigate/three.html"};
|
| +
|
| + private NewTabPage mNtp;
|
| + private String[] mSiteSuggestionUrls;
|
| + private FakeMostVisitedSites mMostVisitedSites;
|
| + private EmbeddedTestServer mTestServer;
|
| +
|
| + @Override
|
| + protected void setUp() throws Exception {
|
| + mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext());
|
| +
|
| + mSiteSuggestionUrls = new String[] {mTestServer.getURL(FAKE_MOST_VISITED_URLS[0]),
|
| + mTestServer.getURL(FAKE_MOST_VISITED_URLS[1]),
|
| + mTestServer.getURL(FAKE_MOST_VISITED_URLS[2])};
|
| +
|
| + mMostVisitedSites = new FakeMostVisitedSites();
|
| + mMostVisitedSites.setTileSuggestions(mSiteSuggestionUrls);
|
| + TileGroupDelegateImpl.setMostVisitedSitesForTests(mMostVisitedSites);
|
| +
|
| + FakeSuggestionsSource mSource = new FakeSuggestionsSource();
|
| + NewTabPage.setSuggestionsSourceForTests(mSource);
|
| +
|
| + super.setUp();
|
| + }
|
| +
|
| + @Override
|
| + protected void tearDown() throws Exception {
|
| + TileGroupDelegateImpl.setMostVisitedSitesForTests(null);
|
| + NewTabPage.setSuggestionsSourceForTests(null);
|
| + mTestServer.stopAndDestroyServer();
|
| +
|
| + super.tearDown();
|
| + }
|
| +
|
| + @Override
|
| + public void startMainActivity() throws InterruptedException {
|
| + startMainActivityWithURL(UrlConstants.NTP_URL);
|
| + Tab mTab = getActivity().getActivityTab();
|
| + NewTabPageTestUtils.waitForNtpLoaded(mTab);
|
| +
|
| + assertTrue(mTab.getNativePage() instanceof NewTabPage);
|
| + mNtp = (NewTabPage) mTab.getNativePage();
|
| +
|
| + RecyclerViewTestUtils.waitForStableRecyclerView(getRecyclerView());
|
| + }
|
| +
|
| + @MediumTest
|
| + @Feature({"NewTabPage"})
|
| + public void testDismissTileWithContextMenu() throws InterruptedException, TimeoutException {
|
| + final View tileView = getTileViewForUrl(mSiteSuggestionUrls[0]);
|
| +
|
| + // Dismiss the tile using the context menu.
|
| + invokeContextMenu(tileView, ContextMenuManager.ID_REMOVE);
|
| + assertTrue(mMostVisitedSites.isUrlBlacklisted(mSiteSuggestionUrls[0]));
|
| +
|
| + // Ensure that undoing the removal is reflected in the ui.
|
| + assertEquals(3, getTileGridLayout().getChildCount());
|
| + mMostVisitedSites.setTileSuggestions(mSiteSuggestionUrls[1], mSiteSuggestionUrls[2]);
|
| + waitForTileRemoved(mSiteSuggestionUrls[0]);
|
| + assertEquals(2, getTileGridLayout().getChildCount());
|
| + }
|
| +
|
| + @MediumTest
|
| + @Feature({"NewTabPage"})
|
| + public void testDismissTileUndo() throws InterruptedException, TimeoutException {
|
| + final ViewGroup tileContainer = getTileGridLayout();
|
| + final View tileView = getTileViewForUrl(mSiteSuggestionUrls[0]);
|
| + assertEquals(3, tileContainer.getChildCount());
|
| +
|
| + // Dismiss the tile using the context menu.
|
| + invokeContextMenu(tileView, ContextMenuManager.ID_REMOVE);
|
| +
|
| + // Ensure that the removal update goes through.
|
| + mMostVisitedSites.setTileSuggestions(mSiteSuggestionUrls[1], mSiteSuggestionUrls[2]);
|
| + waitForTileRemoved(mSiteSuggestionUrls[0]);
|
| + assertEquals(2, tileContainer.getChildCount());
|
| + final View snackbarButton = waitForSnackbar(getActivity());
|
| +
|
| + assertTrue(mMostVisitedSites.isUrlBlacklisted(mSiteSuggestionUrls[0]));
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + snackbarButton.callOnClick();
|
| + }
|
| + });
|
| +
|
| + assertFalse(mMostVisitedSites.isUrlBlacklisted(mSiteSuggestionUrls[0]));
|
| +
|
| + // Ensure that the removal of the update goes through.
|
| + mMostVisitedSites.setTileSuggestions(mSiteSuggestionUrls);
|
| + waitForTileAdded(mSiteSuggestionUrls[0]);
|
| + assertEquals(3, tileContainer.getChildCount());
|
| + }
|
| +
|
| + private NewTabPageRecyclerView getRecyclerView() {
|
| + return mNtp.getNewTabPageView().getRecyclerView();
|
| + }
|
| +
|
| + private TileGridLayout getTileGridLayout() {
|
| + ViewGroup aboveTheFoldView = getRecyclerView().getAboveTheFoldView();
|
| + assertNotNull("Unable to retrieve the AboveTheFold view.", aboveTheFoldView);
|
| +
|
| + TileGridLayout tileGridLayout =
|
| + (TileGridLayout) aboveTheFoldView.findViewById(R.id.tile_grid_layout);
|
| + assertNotNull("Unable to retrieve the TileGridLayout.", tileGridLayout);
|
| + return tileGridLayout;
|
| + }
|
| +
|
| + private View getTileViewForUrl(String url) {
|
| + View tileView = getTileGridLayout().getTileView(url);
|
| + assertNotNull("Tile not found for url " + url, tileView);
|
| +
|
| + return tileView;
|
| + }
|
| +
|
| + private void invokeContextMenu(View view, int contextMenuItemId) {
|
| + TestTouchUtils.longClickView(getInstrumentation(), view);
|
| + assertTrue(
|
| + getInstrumentation().invokeContextMenuAction(getActivity(), contextMenuItemId, 0));
|
| + }
|
| +
|
| + /** Wait for the snackbar associated to a tile dismissal to be shown and returns its button. */
|
| + private static View waitForSnackbar(final ChromeActivity activity) {
|
| + final String expectedSnackbarMessage =
|
| + activity.getResources().getString(R.string.most_visited_item_removed);
|
| + CriteriaHelper.pollUiThread(new Criteria("The snackbar was not shown.") {
|
| + @Override
|
| + public boolean isSatisfied() {
|
| + SnackbarManager snackbarManager = activity.getSnackbarManager();
|
| + if (!snackbarManager.isShowing()) return false;
|
| +
|
| + TextView snackbarMessage = (TextView) activity.findViewById(R.id.snackbar_message);
|
| + if (snackbarMessage == null) return false;
|
| +
|
| + return snackbarMessage.getText().toString().equals(expectedSnackbarMessage);
|
| + }
|
| + });
|
| +
|
| + return activity.findViewById(R.id.snackbar_button);
|
| + }
|
| +
|
| + private void waitForTileRemoved(final String url)
|
| + throws TimeoutException, InterruptedException {
|
| + TileGridLayout tileContainer = getTileGridLayout();
|
| + final TileView removedTile = tileContainer.getTileView(url);
|
| + if (removedTile == null) return;
|
| +
|
| + final CallbackHelper callback = new CallbackHelper();
|
| + tileContainer.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
|
| + @Override
|
| + public void onChildViewAdded(View parent, View child) {}
|
| +
|
| + @Override
|
| + public void onChildViewRemoved(View parent, View child) {
|
| + if (child == removedTile) callback.notifyCalled();
|
| + }
|
| + });
|
| + callback.waitForCallback("The expected tile was not removed.", 0);
|
| + tileContainer.setOnHierarchyChangeListener(null);
|
| + }
|
| +
|
| + private void waitForTileAdded(final String url) throws TimeoutException, InterruptedException {
|
| + TileGridLayout tileContainer = getTileGridLayout();
|
| + if (tileContainer.getTileView(url) != null) return;
|
| +
|
| + final CallbackHelper callback = new CallbackHelper();
|
| + tileContainer.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
|
| + @Override
|
| + public void onChildViewAdded(View parent, View child) {
|
| + if (!(child instanceof TileView)) return;
|
| + if (!((TileView) child).getUrl().equals(url)) return;
|
| +
|
| + callback.notifyCalled();
|
| + }
|
| +
|
| + @Override
|
| + public void onChildViewRemoved(View parent, View child) {}
|
| + });
|
| + callback.waitForCallback("The expected tile was not added.", 0);
|
| + tileContainer.setOnHierarchyChangeListener(null);
|
| + }
|
| +}
|
|
|