/******************************************************************************* * Copyright (c) 2010, 2012 SAP AG and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * Stefan Seelmann - initial implementation posted to * http://www.eclipse.org/forums/index.php?t=msg&th=11863&start=2 *******************************************************************************/ package org.eclipse.egit.ui.test; import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.withMnemonic; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.instanceOf; import java.util.Arrays; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException; import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; import org.eclipse.swtbot.swt.finder.results.VoidResult; import org.eclipse.swtbot.swt.finder.results.WidgetResult; import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot; import org.hamcrest.Matcher; public class ContextMenuHelper { /** * Clicks the context menu matching the text, executing the action * synchronously (blocking until the action completes). *
* This should be used if the action requires no more UI interaction. * * @param bot * * @param texts * the text on the context menu. * @throws WidgetNotFoundException * if the widget is not found. * @throws SWTException * if the menu item is disabled (the root cause being an * {@link IllegalStateException}) */ public static void clickContextMenuSync(final AbstractSWTBot> bot, final String... texts) { clickContextMenuWithRetry(bot, true, texts); } /** * Clicks the context menu matching the text, executing the action * asynchronously (non-blocking). *
* This should only be used when further UI interaction is part of the * action, e.g. a dialog or wizard. Using * {@link #clickContextMenuSync(AbstractSWTBot, String...)} is preferred in * other cases. * * @param bot * * @param texts * the text on the context menu. * @throws WidgetNotFoundException * if the widget is not found. * @throws SWTException * if the menu item is disabled (the root cause being an * {@link IllegalStateException}) */ public static void clickContextMenu(final AbstractSWTBot> bot, final String... texts) { clickContextMenuWithRetry(bot, false, texts); } private static void clickContextMenuWithRetry(final AbstractSWTBot> bot, final boolean sync, final String... texts) { int failCount = 0; int maxFailCount = 4; long sleepTime = 250; while (failCount <= maxFailCount) try { clickContextMenuInternal(bot, sync, texts); if (failCount > 0) System.out.println("Retrying clickContextMenu succeeded"); break; } catch (WidgetNotFoundException e) { failCount++; if (failCount > maxFailCount) { System.out.println("clickContextMenu failed " + failCount + " times"); throw e; } System.out.println("clickContextMenu failed. Retrying in " + sleepTime + " ms"); try { Thread.sleep(sleepTime); sleepTime *= 2; } catch (InterruptedException e1) { // empty } } } private static void clickContextMenuInternal(final AbstractSWTBot> bot, final boolean sync, final String... texts) { // set focus on current widget bot.setFocus(); // show final MenuItem menuItem = UIThreadRunnable .syncExec(new WidgetResult