在SWTBot中,触发右键菜单是简单的task,但是当要触发contextMenu的二级菜单时,就会出现问题,原因可能是事件的丢失,诸如下面的菜单:
Tree
TreeItem1
TreeItem2
想要在TreeItem2上触发SOMA->SOMA sub menu是困难的,下面是我的解决方案(从SWTBot 论坛上抄出来的呵呵http://www.eclipse.org/forums/index.php?t=msg&goto=629948&S=96549f36b839765eb99c047d8b51151c)
经验是,不能直接传入TreeItem, 要把整个Tree node传入才行
String[] paths={"SOMA-ME","Extract SOMA Service Model Elements"};
ContextMenuHelper.clickContextMenu(projectTree,paths);
ContextMenuHelper 源代码:
package com.ibm.asset.adit.mdhi.test.util;
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 org.eclipse.swt.SWT;
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.
*
* @param text
* the text on the context menu.
* @throws WidgetNotFoundException
* if the widget is not found.
*/
public static void clickContextMenu(final AbstractSWTBot<?> bot,
final String... texts) {
// show
final MenuItem menuItem = UIThreadRunnable
.syncExec(new WidgetResult<MenuItem>() {
public MenuItem run() {
MenuItem menuItem = null;
Control control = (Control) bot.widget;
Menu menu = control.getMenu();
for (String text : texts) {
Matcher<?> matcher = allOf(
instanceOf(MenuItem.class),
withMnemonic(text));
menuItem = show(menu, matcher);
if (menuItem != null) {
menu = menuItem.getMenu();
} else {
hide(menu);
break;
}
}
return menuItem;
}
});
if (menuItem == null) {
throw new WidgetNotFoundException("Could not find menu: "
+ Arrays.asList(texts));
}
// click
click(menuItem);
// hide
UIThreadRunnable.syncExec(new VoidResult() {
public void run() {
hide(menuItem.getParent());
}
});
}
private static MenuItem show(final Menu menu, final Matcher<?> matcher) {
if (menu != null) {
menu.notifyListeners(SWT.Show, new Event());
MenuItem[] items = menu.getItems();
for (final MenuItem menuItem : items) {
if (matcher.matches(menuItem)) {
return menuItem;
}
}
menu.notifyListeners(SWT.Hide, new Event());
}
return null;
}
private static void click(final MenuItem menuItem) {
final Event event = new Event();
event.time = (int) System.currentTimeMillis();
event.widget = menuItem;
event.display = menuItem.getDisplay();
event.type = SWT.Selection;
UIThreadRunnable.asyncExec(menuItem.getDisplay(), new VoidResult() {
public void run() {
menuItem.notifyListeners(SWT.Selection, event);
}
});
}
private static void hide(final Menu menu) {
menu.notifyListeners(SWT.Hide, new Event());
if (menu.getParentMenu() != null) {
hide(menu.getParentMenu());
}
}
}