Chromium Code Reviews| 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..dd5d28f262e76a07d412217dad1bce9559aaea0a |
| --- /dev/null |
| +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java |
| @@ -0,0 +1,186 @@ |
| +// 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 org.chromium.base.ThreadUtils; |
| +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.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. |
|
Michael van Ouwerkerk
2017/03/20 11:10:18
Is this actually a test for TileGridLayout? It see
dgn
2017/03/20 16:06:45
TileGridLayout is mentioned just because that is h
|
| + */ |
| +@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])}; |
| + |
| + 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 { |
| + startMainActivityOnBlankPage(); |
| + Tab mTab = getActivity().getActivityTab(); |
| + |
| + mMostVisitedSites = new FakeMostVisitedSites(); |
|
Michael van Ouwerkerk
2017/03/20 11:10:19
Can this block be in setUp?
dgn
2017/03/20 16:06:45
Done.
|
| + mMostVisitedSites.setTileSuggestions(mSiteSuggestionUrls); |
| + TileGroupDelegateImpl.setMostVisitedSitesForTests(mMostVisitedSites); |
| + |
| + loadUrl(UrlConstants.NTP_URL); |
| + 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 the removal update goes through. |
| + mMostVisitedSites.setTileSuggestions(mSiteSuggestionUrls[1], mSiteSuggestionUrls[2]); |
| + waitForViewDetached(tileView); |
| + waitForChildCountChanged(getTileGridLayout(), 2); |
|
Michael van Ouwerkerk
2017/03/20 11:10:19
Please assert earlier in the test that it has 3 ch
dgn
2017/03/20 16:06:44
Done.
|
| + } |
| + |
| + @MediumTest |
| + @Feature({"NewTabPage"}) |
| + public void testDismissTileUndo() throws InterruptedException, TimeoutException { |
| + final TileGridLayout tileGridLayout = getTileGridLayout(); |
| + final View tileView = getTileViewForUrl(mSiteSuggestionUrls[0]); |
| + assertEquals(mSiteSuggestionUrls.length, tileGridLayout.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]); |
| + waitForChildCountChanged(tileGridLayout, 2); |
| + waitForSnackbar(getActivity()); |
| + |
| + assertTrue(mMostVisitedSites.isUrlBlacklisted(mSiteSuggestionUrls[0])); |
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| + @Override |
| + public void run() { |
| + getActivity().getSnackbarManager().onClick(null); |
| + } |
| + }); |
| + |
| + assertFalse(mMostVisitedSites.isUrlBlacklisted(mSiteSuggestionUrls[0])); |
| + |
| + // Ensure that the removal of the update goes through. |
|
Michael van Ouwerkerk
2017/03/20 11:10:18
"Ensure that undoing the removal is reflected in t
dgn
2017/03/20 16:06:44
Done.
|
| + mMostVisitedSites.setTileSuggestions(mSiteSuggestionUrls); |
| + waitForChildCountChanged(tileGridLayout, mSiteSuggestionUrls.length); |
| + } |
| + |
| + 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)); |
| + } |
| + |
| + private static void waitForSnackbar(final ChromeActivity activity) { |
|
Michael van Ouwerkerk
2017/03/20 11:10:19
Other instrumentation tests seems to rely on getCu
dgn
2017/03/20 16:06:44
As explained below, Snackbar is not super usable o
|
| + CriteriaHelper.pollUiThread(new Criteria("The snackbar was not shown.") { |
| + @Override |
| + public boolean isSatisfied() { |
| + return activity.findViewById(R.id.snackbar) != null; |
|
Michael van Ouwerkerk
2017/03/20 11:10:19
DataReductionPromoSnackbarControllerTest also conf
dgn
2017/03/20 16:06:44
That one has access to package private methods fro
|
| + } |
| + }); |
| + } |
| + |
| + private static void waitForViewDetached(final View view) { |
|
Michael van Ouwerkerk
2017/03/20 11:10:18
This seems like a very generic method, is there a
dgn
2017/03/20 16:06:45
Removed
|
| + CriteriaHelper.pollUiThread(new Criteria("The view did not detach.") { |
| + @Override |
| + public boolean isSatisfied() { |
| + return view.getParent() == null; |
| + } |
| + }); |
| + } |
| + |
| + private static void waitForChildCountChanged(final ViewGroup parent, final int expectedCount) { |
|
Michael van Ouwerkerk
2017/03/20 11:10:19
nit: rename to waitForChildCount, it's shorter. An
Michael van Ouwerkerk
2017/03/20 11:10:19
This might also be fine in a generic test util.
dgn
2017/03/20 16:06:44
Done.
dgn
2017/03/20 16:06:44
Removed the polling, but because for the case of t
|
| + CriteriaHelper.pollUiThread(new Criteria("The child count did not change.") { |
| + @Override |
| + public boolean isSatisfied() { |
| + return parent.getChildCount() == expectedCount; |
| + } |
| + }); |
| + } |
| +} |