blob: 574b6e2e104d006879796c9502462e0fd99fd325 [file] [log] [blame]
// Copyright 2013 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.test.util.browser.contextmenu;
import android.test.ActivityInstrumentationTestCase2;
import android.text.TextUtils;
import android.view.ContextMenu;
import android.view.MenuItem;
import junit.framework.Assert;
import org.chromium.chrome.browser.EmptyTabObserver;
import org.chromium.chrome.browser.Tab;
import org.chromium.content.browser.test.util.CallbackHelper;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content.browser.test.util.DOMUtils;
import java.lang.ref.WeakReference;
import java.util.concurrent.TimeoutException;
/**
* A utility class to help open and interact with context menus triggered by a WebContents.
*/
public class ContextMenuUtils {
/**
* Callback helper that also provides access to the last display ContextMenu.
*/
private static class OnContextMenuShownHelper extends CallbackHelper {
private WeakReference<ContextMenu> mContextMenu;
public void notifyCalled(ContextMenu menu) {
mContextMenu = new WeakReference<ContextMenu>(menu);
notifyCalled();
}
public ContextMenu getContextMenu() {
assert getCallCount() > 0;
return mContextMenu.get();
}
}
/**
* Opens a context menu.
* @param testCase The test harness.
* @param tab The tab to open a context menu for.
* @param openerDOMNodeId The DOM node to long press to open the context menu for.
* @return The {@link ContextMenu} that was opened.
* @throws InterruptedException
* @throws TimeoutException
*/
public static ContextMenu openContextMenu(ActivityInstrumentationTestCase2 testCase,
Tab tab, String openerDOMNodeId)
throws InterruptedException, TimeoutException {
final OnContextMenuShownHelper helper = new OnContextMenuShownHelper();
tab.addObserver(new EmptyTabObserver() {
@Override
public void onContextMenuShown(Tab tab, ContextMenu menu) {
helper.notifyCalled(menu);
}
});
int callCount = helper.getCallCount();
DOMUtils.longPressNode(testCase, tab.getContentViewCore(), openerDOMNodeId);
helper.waitForCallback(callCount);
return helper.getContextMenu();
}
/**
* Opens and selects an item from a context menu.
* @param testCase The test harness.
* @param tab The tab to open a context menu for.
* @param openerDOMNodeId The DOM node to long press to open the context menu for.
* @param itemId The context menu item ID to select.
* @throws InterruptedException
* @throws TimeoutException
*/
public static void selectContextMenuItem(ActivityInstrumentationTestCase2 testCase,
Tab tab, String openerDOMNodeId,
final int itemId) throws InterruptedException, TimeoutException {
ContextMenu menu = openContextMenu(testCase, tab, openerDOMNodeId);
Assert.assertNotNull("Failed to open context menu", menu);
selectOpenContextMenuItem(testCase, menu, itemId);
}
/**
* Opens and selects an item from a context menu.
* @param testCase The test harness.
* @param tab The tab to open a context menu for.
* @param openerDOMNodeId The DOM node to long press to open the context menu for.
* @param itemTitle The title of the context menu item to select.
* @throws InterruptedException
* @throws TimeoutException
*/
public static void selectContextMenuItemByTitle(ActivityInstrumentationTestCase2 testCase,
Tab tab, String openerDOMNodeId,
String itemTitle) throws InterruptedException, TimeoutException {
ContextMenu menu = openContextMenu(testCase, tab, openerDOMNodeId);
Assert.assertNotNull("Failed to open context menu", menu);
Integer itemId = null;
for (int i = 0; i < menu.size(); i++) {
MenuItem item = menu.getItem(i);
if (TextUtils.equals(item.getTitle(), itemTitle)) {
itemId = item.getItemId();
break;
}
}
Assert.assertNotNull("Couldn't find context menu item for '" + itemTitle + "'", itemId);
selectOpenContextMenuItem(testCase, menu, itemId);
}
private static void selectOpenContextMenuItem(final ActivityInstrumentationTestCase2 testCase,
final ContextMenu menu, final int itemId) throws InterruptedException {
MenuItem item = menu.findItem(itemId);
Assert.assertNotNull("Could not find '" + itemId + "' in menu", item);
Assert.assertTrue("'" + itemId + "' is not visible", item.isVisible());
Assert.assertTrue("'" + itemId + "' is not enabled", item.isEnabled());
testCase.getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
boolean activated = menu.performIdentifierAction(itemId, 0);
Assert.assertTrue("Failed to activate '" + itemId + "' in menu", activated);
}
});
Assert.assertTrue("Activity did not regain focus.",
CriteriaHelper.pollForCriteria(new Criteria() {
@Override
public boolean isSatisfied() {
return testCase.getActivity().hasWindowFocus();
}
}));
}
}