| Index: chrome/android/javatests/src/org/chromium/chrome/browser/browseractions/BrowserActionActivityTest.java
|
| diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browseractions/BrowserActionActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browseractions/BrowserActionActivityTest.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1889808e2e9c5227b880dc0e51eed16606f57ca5
|
| --- /dev/null
|
| +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browseractions/BrowserActionActivityTest.java
|
| @@ -0,0 +1,353 @@
|
| +// 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.browseractions;
|
| +
|
| +import android.app.Activity;
|
| +import android.app.Instrumentation;
|
| +import android.app.Instrumentation.ActivityMonitor;
|
| +import android.app.PendingIntent;
|
| +import android.app.ProgressDialog;
|
| +import android.content.Context;
|
| +import android.content.Intent;
|
| +import android.net.Uri;
|
| +import android.os.Bundle;
|
| +import android.support.customtabs.browseractions.BrowserActionsIntent;
|
| +import android.support.test.InstrumentationRegistry;
|
| +import android.support.test.filters.SmallTest;
|
| +import android.util.Pair;
|
| +import android.util.SparseArray;
|
| +
|
| +import org.junit.After;
|
| +import org.junit.Assert;
|
| +import org.junit.Before;
|
| +import org.junit.Rule;
|
| +import org.junit.Test;
|
| +import org.junit.runner.RunWith;
|
| +
|
| +import org.chromium.base.ThreadUtils;
|
| +import org.chromium.base.test.util.CallbackHelper;
|
| +import org.chromium.base.test.util.CommandLineFlags;
|
| +import org.chromium.chrome.R;
|
| +import org.chromium.chrome.browser.ChromeSwitches;
|
| +import org.chromium.chrome.browser.browseractions.BrowserActionsContextMenuHelper.BrowserActionsTestDelegate;
|
| +import org.chromium.chrome.browser.contextmenu.ChromeContextMenuItem;
|
| +import org.chromium.chrome.browser.contextmenu.ContextMenuItem;
|
| +import org.chromium.chrome.browser.contextmenu.ShareContextMenuItem;
|
| +import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
|
| +import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
|
| +import org.chromium.chrome.browser.firstrun.FirstRunStatus;
|
| +import org.chromium.chrome.browser.util.IntentUtils;
|
| +import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
|
| +import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
|
| +import org.chromium.content.browser.test.util.CriteriaHelper;
|
| +import org.chromium.net.test.EmbeddedTestServer;
|
| +
|
| +import java.util.ArrayList;
|
| +import java.util.List;
|
| +
|
| +/**
|
| + * Instrumentation tests for context menu of a {@link BrowserActionActivity}.
|
| + */
|
| +@RunWith(ChromeJUnit4ClassRunner.class)
|
| +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
|
| +public class BrowserActionActivityTest {
|
| + private static final String TEST_PAGE = "/chrome/test/data/android/google.html";
|
| + private static final String TEST_PAGE_2 = "/chrome/test/data/android/test.html";
|
| + private static final String TEST_PAGE_3 = "/chrome/test/data/android/simple.html";
|
| + private static final String CUSTOM_ITEM_TITLE = "Custom item";
|
| +
|
| + private final CallbackHelper mOnBrowserActionsMenuShownCallback = new CallbackHelper();
|
| + private final CallbackHelper mOnFinishNativeInitializationCallback = new CallbackHelper();
|
| + private final CallbackHelper mOnOpenTabInBackgroundStartCallback = new CallbackHelper();
|
| +
|
| + private BrowserActionsContextMenuItemDelegate mMenuItemDelegate;
|
| + private SparseArray<PendingIntent> mCustomActions;
|
| + private List<Pair<Integer, List<ContextMenuItem>>> mItems;
|
| + private ProgressDialog mProgressDialog;
|
| + private TestDelegate mTestDelegate;
|
| + private EmbeddedTestServer mTestServer;
|
| + private String mTestPage;
|
| + private String mTestPage2;
|
| + private String mTestPage3;
|
| + private PendingIntent mCustomPendingItent;
|
| + @Rule
|
| + public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
|
| + @Rule
|
| + public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule();
|
| +
|
| + private class TestDelegate implements BrowserActionsTestDelegate {
|
| + @Override
|
| + public void onBrowserActionsMenuShown() {
|
| + mOnBrowserActionsMenuShownCallback.notifyCalled();
|
| + }
|
| +
|
| + @Override
|
| + public void onFinishNativeInitialization() {
|
| + mOnFinishNativeInitializationCallback.notifyCalled();
|
| + }
|
| +
|
| + @Override
|
| + public void onOpenTabInBackgroundStart() {
|
| + mOnOpenTabInBackgroundStartCallback.notifyCalled();
|
| + }
|
| +
|
| + @Override
|
| + public void initialize(BrowserActionsContextMenuItemDelegate menuItemDelegate,
|
| + SparseArray<PendingIntent> customActions,
|
| + List<Pair<Integer, List<ContextMenuItem>>> items,
|
| + ProgressDialog progressDialog) {
|
| + mMenuItemDelegate = menuItemDelegate;
|
| + mCustomActions = customActions;
|
| + mItems = items;
|
| + mProgressDialog = progressDialog;
|
| + }
|
| + }
|
| +
|
| + @Before
|
| + public void setUp() throws Exception {
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + FirstRunStatus.setFirstRunFlowComplete(true);
|
| + }
|
| + });
|
| + mTestDelegate = new TestDelegate();
|
| + Context appContext = InstrumentationRegistry.getInstrumentation()
|
| + .getTargetContext()
|
| + .getApplicationContext();
|
| + mTestServer = EmbeddedTestServer.createAndStartServer(appContext);
|
| + mTestPage = mTestServer.getURL(TEST_PAGE);
|
| + mTestPage2 = mTestServer.getURL(TEST_PAGE_2);
|
| + mTestPage3 = mTestServer.getURL(TEST_PAGE_3);
|
| + }
|
| +
|
| + @After
|
| + public void tearDown() throws Exception {
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + FirstRunStatus.setFirstRunFlowComplete(false);
|
| + }
|
| + });
|
| + mTestServer.stopAndDestroyServer();
|
| + }
|
| +
|
| + @Test
|
| + @SmallTest
|
| + public void testMenuShownCorrectly() throws Exception {
|
| + startBrowserActionActivity(mTestPage);
|
| +
|
| + // Menu should be shown before native finish loading.
|
| + mOnBrowserActionsMenuShownCallback.waitForCallback(0);
|
| + Assert.assertEquals(0, mOnFinishNativeInitializationCallback.getCallCount());
|
| + Assert.assertEquals(0, mOnOpenTabInBackgroundStartCallback.getCallCount());
|
| +
|
| + // Let the initialization completes.
|
| + mOnFinishNativeInitializationCallback.waitForCallback(0);
|
| + Assert.assertEquals(1, mOnBrowserActionsMenuShownCallback.getCallCount());
|
| + Assert.assertEquals(1, mOnFinishNativeInitializationCallback.getCallCount());
|
| +
|
| + // Check menu populated correctly.
|
| + List<Pair<Integer, List<ContextMenuItem>>> menus = mItems;
|
| + Assert.assertEquals(1, menus.size());
|
| + List<ContextMenuItem> items = menus.get(0).second;
|
| + Assert.assertEquals(6, items.size());
|
| + for (int i = 0; i < 4; i++) {
|
| + Assert.assertTrue(items.get(i) instanceof ChromeContextMenuItem);
|
| + }
|
| + Assert.assertTrue(items.get(4) instanceof ShareContextMenuItem);
|
| + Assert.assertTrue(items.get(5) instanceof BrowserActionsCustomContextMenuItem);
|
| + Assert.assertEquals(mCustomPendingItent,
|
| + mCustomActions.get(
|
| + BrowserActionsContextMenuHelper.CUSTOM_BROWSER_ACTIONS_ID_GROUP.get(0)));
|
| + }
|
| +
|
| + @Test
|
| + @SmallTest
|
| + public void testOpenTabInBackgroundAfterInitialization() throws Exception {
|
| + final BrowserActionActivity activity = startBrowserActionActivity(mTestPage);
|
| + mOnBrowserActionsMenuShownCallback.waitForCallback(0);
|
| + // Open a tab in background before initialization finishes.
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + activity.getHelperForTesting().onItemSelected(
|
| + R.id.browser_actions_open_in_background);
|
| + }
|
| + });
|
| +
|
| + // A ProgressDialog should be displayed and tab opening should be pending until
|
| + // initialization finishes.
|
| + Assert.assertTrue(mProgressDialog.isShowing());
|
| + Assert.assertEquals(0, mOnOpenTabInBackgroundStartCallback.getCallCount());
|
| + mOnFinishNativeInitializationCallback.waitForCallback(0);
|
| + mOnOpenTabInBackgroundStartCallback.waitForCallback(0);
|
| + Assert.assertFalse(mProgressDialog.isShowing());
|
| + Assert.assertEquals(1, mOnOpenTabInBackgroundStartCallback.getCallCount());
|
| + }
|
| +
|
| + @Test
|
| + @SmallTest
|
| + public void testOpenSingleTabInBackgroundWhenChromeAvailable() throws Exception {
|
| + // Start ChromeTabbedActivity first.
|
| + mActivityTestRule.startMainActivityWithURL(mTestPage);
|
| +
|
| + // Load Browser Actions menu completely.
|
| + final BrowserActionActivity activity = startBrowserActionActivity(mTestPage2);
|
| + mOnBrowserActionsMenuShownCallback.waitForCallback(0);
|
| + mOnFinishNativeInitializationCallback.waitForCallback(0);
|
| + Assert.assertEquals(1, mActivityTestRule.getActivity().getCurrentTabModel().getCount());
|
| + // No notification should be shown.
|
| + Assert.assertFalse(mMenuItemDelegate.hasBrowserActionsNotification());
|
| +
|
| + // Open a tab in the background.
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + activity.getHelperForTesting().onItemSelected(
|
| + R.id.browser_actions_open_in_background);
|
| + }
|
| + });
|
| +
|
| + // Notification for single tab should be shown.
|
| + Assert.assertTrue(mMenuItemDelegate.hasBrowserActionsNotification());
|
| + // Tabs should always be added at the end of the model.
|
| + Assert.assertEquals(2, mActivityTestRule.getActivity().getCurrentTabModel().getCount());
|
| + Assert.assertEquals(mTestPage,
|
| + mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getUrl());
|
| + Assert.assertEquals(mTestPage2,
|
| + mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(1).getUrl());
|
| + int prevTabId = mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getId();
|
| + int newTabId = mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(1).getId();
|
| + // TODO(ltian): overwrite delegate prevent creating notifcation for test.
|
| + Intent notificationIntent = mMenuItemDelegate.getNotificationIntent();
|
| + notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
| +
|
| + // Force ChromeTabbedActivity dismissed to make sure it calls onStop then calls onStart next
|
| + // time it is started by an Intent.
|
| + Intent customTabIntent = CustomTabsTestUtils.createMinimalCustomTabIntent(
|
| + InstrumentationRegistry.getInstrumentation().getTargetContext(), mTestPage);
|
| + mCustomTabActivityTestRule.startCustomTabActivityWithIntent(customTabIntent);
|
| +
|
| + // The Intent of the Browser Actions notification should not toggle overview mode and should
|
| + mActivityTestRule.startActivityCompletely(notificationIntent);
|
| + Assert.assertFalse(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
|
| + Assert.assertNotEquals(prevTabId, mActivityTestRule.getActivity().getActivityTab().getId());
|
| + Assert.assertEquals(newTabId, mActivityTestRule.getActivity().getActivityTab().getId());
|
| + }
|
| +
|
| + @Test
|
| + @SmallTest
|
| + public void testOpenMulitpleTabInBackgroundWhenChromeAvailable() throws Exception {
|
| + // Start ChromeTabbedActivity first.
|
| + mActivityTestRule.startMainActivityWithURL(mTestPage);
|
| +
|
| + // Open two tabs in the background.
|
| + final BrowserActionActivity activity1 = startBrowserActionActivity(mTestPage2);
|
| + mOnBrowserActionsMenuShownCallback.waitForCallback(0);
|
| + mOnFinishNativeInitializationCallback.waitForCallback(0);
|
| + Assert.assertEquals(1, mActivityTestRule.getActivity().getCurrentTabModel().getCount());
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + activity1.getHelperForTesting().onItemSelected(
|
| + R.id.browser_actions_open_in_background);
|
| + }
|
| + });
|
| +
|
| + final BrowserActionActivity activity2 = startBrowserActionActivity(mTestPage3, 1);
|
| + mOnBrowserActionsMenuShownCallback.waitForCallback(1);
|
| + mOnFinishNativeInitializationCallback.waitForCallback(1);
|
| + Assert.assertEquals(2, mActivityTestRule.getActivity().getCurrentTabModel().getCount());
|
| +
|
| + // Notification for multiple tabs should be shown.
|
| + Assert.assertTrue(mMenuItemDelegate.hasBrowserActionsNotification());
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + activity2.getHelperForTesting().onItemSelected(
|
| + R.id.browser_actions_open_in_background);
|
| + }
|
| + });
|
| +
|
| + // Tabs should always be added at the end of the model.
|
| + Assert.assertEquals(3, mActivityTestRule.getActivity().getCurrentTabModel().getCount());
|
| + Assert.assertEquals(mTestPage,
|
| + mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getUrl());
|
| + Assert.assertEquals(mTestPage2,
|
| + mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(1).getUrl());
|
| + Assert.assertEquals(mTestPage3,
|
| + mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(2).getUrl());
|
| + Intent notificationIntent = mMenuItemDelegate.getNotificationIntent();
|
| + notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
| +
|
| + // Force ChromeTabbedActivity dismissed to make sure it calls onStop then calls onStart next
|
| + // time it is started by an Intent.
|
| + Intent customTabIntent = CustomTabsTestUtils.createMinimalCustomTabIntent(
|
| + InstrumentationRegistry.getInstrumentation().getTargetContext(), mTestPage);
|
| + mCustomTabActivityTestRule.startCustomTabActivityWithIntent(customTabIntent);
|
| +
|
| + // The Intent of the Browser Actions notification should toggle overview mode.
|
| + mActivityTestRule.startActivityCompletely(notificationIntent);
|
| + Assert.assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
|
| + }
|
| +
|
| + private BrowserActionActivity startBrowserActionActivity(String url) throws Exception {
|
| + return startBrowserActionActivity(url, 0);
|
| + }
|
| +
|
| + private BrowserActionActivity startBrowserActionActivity(String url, int expectedCallCount)
|
| + throws Exception {
|
| + final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
|
| + ActivityMonitor browserActionMonitor =
|
| + new ActivityMonitor(BrowserActionActivity.class.getName(), null, false);
|
| + instrumentation.addMonitor(browserActionMonitor);
|
| +
|
| + // The BrowserActionActivity shouldn't have started yet.
|
| + Assert.assertEquals(expectedCallCount, mOnBrowserActionsMenuShownCallback.getCallCount());
|
| + Assert.assertEquals(
|
| + expectedCallCount, mOnFinishNativeInitializationCallback.getCallCount());
|
| + Assert.assertEquals(expectedCallCount, mOnOpenTabInBackgroundStartCallback.getCallCount());
|
| +
|
| + // Fire an Intent to start the BrowserActionActivity.
|
| + sendBrowserActionIntent(instrumentation, url);
|
| +
|
| + Activity activity = instrumentation.waitForMonitorWithTimeout(
|
| + browserActionMonitor, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL);
|
| + Assert.assertNotNull("Activity didn't start", activity);
|
| + Assert.assertTrue("Wrong activity started", activity instanceof BrowserActionActivity);
|
| + instrumentation.removeMonitor(browserActionMonitor);
|
| + ((BrowserActionActivity) activity)
|
| + .getHelperForTesting()
|
| + .setTestDelegateForTesting(mTestDelegate);
|
| + return (BrowserActionActivity) activity;
|
| + }
|
| +
|
| + private void sendBrowserActionIntent(Instrumentation instrumentation, String url) {
|
| + Context context = instrumentation.getTargetContext();
|
| + Intent intent = new Intent(BrowserActionsIntent.ACTION_BROWSER_ACTIONS_OPEN);
|
| + intent.setData(Uri.parse(url));
|
| + intent.putExtra(BrowserActionsIntent.EXTRA_TYPE, BrowserActionsIntent.URL_TYPE_NONE);
|
| + PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, new Intent(), 0);
|
| + intent.putExtra(BrowserActionsIntent.EXTRA_APP_ID, pendingIntent);
|
| +
|
| + // Add a custom item.
|
| + Intent customIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
| + mCustomPendingItent = PendingIntent.getActivity(context, 0, customIntent, 0);
|
| + Bundle item = new Bundle();
|
| + item.putString(BrowserActionsIntent.KEY_TITLE, CUSTOM_ITEM_TITLE);
|
| + item.putParcelable(BrowserActionsIntent.KEY_ACTION, mCustomPendingItent);
|
| + ArrayList<Bundle> items = new ArrayList<>();
|
| + items.add(item);
|
| + intent.putParcelableArrayListExtra(BrowserActionsIntent.EXTRA_MENU_ITEMS, items);
|
| + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
| +
|
| + intent.setClass(context, BrowserActionActivity.class);
|
| + // Android Test Rule auto adds {@link Intent.FLAG_ACTIVITY_NEW_TASK} which violates {@link
|
| + // BrowserActionsIntent} policy. Add an extra to skip Intent.FLAG_ACTIVITY_NEW_TASK check
|
| + // for test.
|
| + IntentUtils.safeStartActivity(context, intent);
|
| + }
|
| +}
|
|
|