Chromium Code Reviews| Index: chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java |
| diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..7e388ac5c706d2167ba1fa1873e1e97a1636c010 |
| --- /dev/null |
| +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java |
| @@ -0,0 +1,163 @@ |
| +// Copyright 2015 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.offlinepages; |
| + |
| +import android.content.Context; |
| +import android.support.test.filters.MediumTest; |
| + |
| +import org.chromium.base.Callback; |
| +import org.chromium.base.ThreadUtils; |
| +import org.chromium.base.test.util.CommandLineFlags; |
| +import org.chromium.chrome.browser.offlinepages.OfflinePageBridge.OfflinePageModelObserver; |
| +import org.chromium.chrome.browser.profiles.Profile; |
| +import org.chromium.chrome.browser.tab.Tab; |
| +import org.chromium.chrome.test.ChromeTabbedActivityTestBase; |
| +import org.chromium.net.NetworkChangeNotifier; |
| +import org.chromium.net.test.EmbeddedTestServer; |
| + |
| +import java.util.ArrayList; |
| +import java.util.List; |
| +import java.util.concurrent.Semaphore; |
| +import java.util.concurrent.TimeUnit; |
| + |
| +/** Integration tests for the Last 1 feature of Offline Pages. */ |
| +@CommandLineFlags.Add("enable-features=OfflineRecentPages") |
| +public class RecentTabsTest extends ChromeTabbedActivityTestBase { |
| + private static final String TEST_PAGE = "/chrome/test/data/android/about.html"; |
| + private static final int TIMEOUT_MS = 5000; |
| + |
| + private OfflinePageBridge mOfflinePageBridge; |
| + private EmbeddedTestServer mTestServer; |
| + private String mTestPage; |
| + |
| + private void initializeBridgeForProfile(final boolean incognitoProfile) |
| + throws InterruptedException { |
| + final Semaphore semaphore = new Semaphore(0); |
| + ThreadUtils.runOnUiThread(new Runnable() { |
|
fgorski
2017/02/23 20:23:12
did you try: runOnUiThreadBlocking with no semapho
dewittj
2017/02/27 19:53:46
This does not work because we need to wait for the
|
| + @Override |
| + public void run() { |
| + Profile profile = Profile.getLastUsedProfile(); |
| + if (incognitoProfile) { |
| + profile = profile.getOffTheRecordProfile(); |
| + } |
| + // Ensure we start in an offline state. |
| + mOfflinePageBridge = OfflinePageBridge.getForProfile(profile); |
| + if (mOfflinePageBridge == null || mOfflinePageBridge.isOfflinePageModelLoaded()) { |
| + semaphore.release(); |
| + return; |
| + } |
| + mOfflinePageBridge.addObserver(new OfflinePageModelObserver() { |
| + @Override |
| + public void offlinePageModelLoaded() { |
| + semaphore.release(); |
| + mOfflinePageBridge.removeObserver(this); |
| + } |
| + }); |
| + } |
| + }); |
| + assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| + } |
| + |
| + @Override |
| + protected void setUp() throws Exception { |
| + super.setUp(); |
| + |
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| + @Override |
| + public void run() { |
| + // Ensure we start in an offline state. |
| + NetworkChangeNotifier.forceConnectivityState(false); |
| + Context context = getActivity().getBaseContext(); |
| + if (!NetworkChangeNotifier.isInitialized()) { |
| + NetworkChangeNotifier.init(context); |
| + } |
| + } |
| + }); |
| + |
| + initializeBridgeForProfile(false); |
| + |
| + mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation().getContext()); |
| + mTestPage = mTestServer.getURL(TEST_PAGE); |
| + } |
| + |
| + @Override |
| + protected void tearDown() throws Exception { |
| + mTestServer.stopAndDestroyServer(); |
| + super.tearDown(); |
| + } |
| + |
| + @Override |
| + public void startMainActivity() throws InterruptedException { |
| + startMainActivityOnBlankPage(); |
| + } |
| + |
| + @CommandLineFlags.Add("short-offline-page-snapshot-delay-for-test") |
| + @MediumTest |
| + public void testLastNPageSavedWhenTabSwitched() throws Exception { |
| + // The tab of interest. |
| + Tab tab = loadUrlInNewTab(mTestPage); |
| + |
| + final ClientId firstTabClientId = |
| + new ClientId(OfflinePageBridge.LAST_N_NAMESPACE, Integer.toString(tab.getId())); |
| + |
| + // The tab should be foreground and so no snapshot should exist. |
| + assertNull(getPageByClientId(firstTabClientId)); |
| + |
| + // Note, that switching to a new tab must occur after the SnapshotController believes the |
| + // page quality is good enough. With the debug flag, the delay after DomContentLoaded is 0 |
| + // so we can definitely snapshot after onload (which is what |loadUrlInNewTab| waits for). |
| + |
| + // Switch to a new tab to cause the WebContents hidden event. |
| + loadUrlInNewTab("about:blank"); |
| + |
| + waitForPageWithClientId(firstTabClientId); |
| + } |
| + |
| + private void waitForPageWithClientId(final ClientId clientId) throws InterruptedException { |
| + if (getPageByClientId(clientId) != null) return; |
| + |
| + final Semaphore semaphore = new Semaphore(0); |
| + ThreadUtils.runOnUiThread(new Runnable() { |
|
fgorski
2017/02/23 20:23:11
did you try: runOnUiThreadBlocking with no semapho
dewittj
2017/02/27 19:53:46
ditto.
|
| + @Override |
| + public void run() { |
| + mOfflinePageBridge.addObserver(new OfflinePageModelObserver() { |
| + @Override |
| + public void offlinePageAdded(OfflinePageItem newPage) { |
| + if (newPage.getClientId().equals(clientId)) { |
| + mOfflinePageBridge.removeObserver(this); |
| + semaphore.release(); |
| + } |
| + } |
| + }); |
| + } |
| + }); |
| + assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| + } |
| + |
| + private OfflinePageItem getPageByClientId(ClientId clientId) throws InterruptedException { |
| + final OfflinePageItem[] result = {null}; |
| + final Semaphore semaphore = new Semaphore(0); |
| + final List<ClientId> clientIdList = new ArrayList<>(); |
| + clientIdList.add(clientId); |
| + |
| + ThreadUtils.runOnUiThread(new Runnable() { |
|
fgorski
2017/02/23 20:23:12
Does this work?
OfflinePageItem item = ThreadUtils
dewittj
2017/02/27 19:53:46
No, and for the same reason. Since the API is asyn
|
| + @Override |
| + public void run() { |
| + mOfflinePageBridge.getPagesByClientIds( |
| + clientIdList, new Callback<List<OfflinePageItem>>() { |
| + @Override |
| + public void onResult(List<OfflinePageItem> items) { |
| + if (!items.isEmpty()) { |
| + result[0] = items.get(0); |
| + } |
| + semaphore.release(); |
| + } |
| + }); |
| + } |
| + }); |
| + assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); |
| + return result[0]; |
| + } |
| +} |