Finding difficult to select an context menu [message #36892] |
Tue, 26 May 2009 09:15  |
Eclipse User |
|
|
|
I have defined some menu declaratively in plugin.xml. And i want to select
menu at first level.
I am getting following error when i use below mentioned stt.
treeNode.select().contextMenu("<Name>").click();
stack trace:
org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundExcep tion: The
widget {(an instance of org.eclipse.swt.widgets.MenuItem and with mnemonic
'<Menu Name>')} was disposed.
at
org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot.<init>(AbstractSWTBot.java:96)
at
org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu.<init>(SWTBotMenu.java:42)
at
org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot.context Menu(AbstractSWTBot.java:383)
at
org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot.context Menu(AbstractSWTBot.java:356)
at
TestDeregisterMountArtifact.testDeregister(TestDeregisterMou ntArtifact.java:75)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce ssorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:164)
at junit.framework.TestCase.runBare(TestCase.java:130)
at
org.eclipse.swtbot.swt.finder.SWTBotTestCase.runBare(SWTBotT estCase.java:228)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:120)
at
org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestRefer ence.run(JUnit3TestReference.java:130)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(Test Execution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTe sts(RemoteTestRunner.java:460)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTe sts(RemoteTestRunner.java:673)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(R emoteTestRunner.java:386)
at
org.eclipse.swtbot.eclipse.core.RemotePluginTestRunner.main( RemotePluginTestRunner.java:64)
at
org.eclipse.swtbot.eclipse.core.UITestApplication.runTests(U ITestApplication.java:123)
at
org.eclipse.ui.internal.testing.WorkbenchTestable$1.run(Work benchTestable.java:68)
at java.lang.Thread.run(Thread.java:619)
|
|
|
|
Re: Finding difficult to select an context menu [message #38012 is a reply to message #37532] |
Sun, 31 May 2009 17:12   |
Eclipse User |
|
|
|
I have a slight different problem: My context menu is created
programmatically using IMenuListener.menuAboutToShow( IMenuManager )
method. I get the "disposed" exception when I try to access the menu at
the second level.
I created a small helper that works for me, see below. The idea is to
click the menu item _before_ sending the SWT.Hide event for the context
menu. Additionally the whole menu path is expected.
Maybe the others could test this snippet and report if it helps? If so I
would suggest to extend the existing API. The usage is
ContextMenuHelper.clickContextMenu(treeNode, "Import", "LDIF");
Kind Regards,
Stefan
------------------------------------------------------------ -------
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.WidgetNotFoundExcep tion;
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());
}
}
}
|
|
|
Re: Finding difficult to select an context menu [message #479900 is a reply to message #38012] |
Wed, 12 August 2009 20:11   |
Eclipse User |
|
|
|
Originally posted by: jconlon.apache.org
Hi Stefan,
I found your helper in the newsgroup. It's worked well for me.
Added a few log statements to help troubleshoot those pesky 'spaces in
the wrong places' bugs that can really be a pain to find.
See below...
thanks for the suggestion,
John
Stefan Seelmann wrote:
> I have a slight different problem: My context menu is created
> programmatically using IMenuListener.menuAboutToShow( IMenuManager )
> method. I get the "disposed" exception when I try to access the menu at
> the second level.
>
> I created a small helper that works for me, see below. The idea is to
> click the menu item _before_ sending the SWT.Hide event for the context
> menu. Additionally the whole menu path is expected.
>
> Maybe the others could test this snippet and report if it helps? If so I
> would suggest to extend the existing API. The usage is
> ContextMenuHelper.clickContextMenu(treeNode, "Import", "LDIF");
>
> Kind Regards,
> Stefan
>
>
> ------------------------------------------------------------ -------
> 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.WidgetNotFoundExcep tion;
> 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 {
>
private static Logger log = Logger.getLogger(ContextMenuHelper.class);
> /**
> * 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) {
>
log.debug("Searching for "+Arrays.asList(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) {
log.debug("Matching:<"+text+'>');
> 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)) {
log.debug("Found menuItem match: <"+menuItem.getText()+'>');
> return menuItem;
> }
else{
log.debug("Rejecting menuItem match:<"+
menuItem.getText()+'>');
}
> }
> 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());
> }
> }
> }
|
|
|
|
|
|
|
|
Re: Finding difficult to select an context menu [message #491152 is a reply to message #38012] |
Tue, 13 October 2009 09:30   |
Eclipse User |
|
|
|
Stefan Seelmann wrote on Sun, 31 May 2009 17:12 | I have a slight different problem: My context menu is created
programmatically using IMenuListener.menuAboutToShow( IMenuManager )
method. I get the "disposed" exception when I try to access the menu at
the second level.
I created a small helper that works for me, see below. The idea is to
click the menu item _before_ sending the SWT.Hide event for the context
menu. Additionally the whole menu path is expected.
Maybe the others could test this snippet and report if it helps? If so I
would suggest to extend the existing API. The usage is
ContextMenuHelper.clickContextMenu(treeNode, "Import", "LDIF");
Kind Regards,
Stefan
------------------------------------------------------------ -------
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.WidgetNotFoundExcep tion;
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());
}
}
}
|
Hello Stefan.
Have you already suggest to extend the API, because I think your ContextmenHelper works fine. And so could everybody use it, without looking for this thread. 
|
|
|
|
|
Re: Finding difficult to select an context menu [message #664833 is a reply to message #36892] |
Tue, 12 April 2011 04:56   |
Eclipse User |
|
|
|
Hi all,
hopefully no one is offended by me pulling up this old thread.
But I find the proposed ContextMenuHelper of Stefan Seelmann very useful. Thus I'd once again vote for taking this into SWTBot by default 
There's only one small enhancement I needed to add to make this work for me: The MenuDetect-Event. So, before calling the menu of the control, I fire the mentioned event, so that the listeners may prepare for (or prevent) the opening of the menu.
Below is the complete code with my changes
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;
/**
* This helper is a workaround for a bug in SWTBot,
* where the bot can't find a dynamically created context menu
* @author Stefan Seelmann (initial)
* @author Stefan Schaefer (extension)
*/
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;
//MenuDetectEvent added by Stefan Schaefer
Event event = new Event();
control.notifyListeners(SWT.MenuDetect, event);
if (!event.doit) {
return null;
}
Menu menu = control.getMenu();
for (String text : texts) {
@SuppressWarnings("unchecked")
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());
}
}
}
|
|
|
|
|
|
|
Re: Finding difficult to select an context menu [message #994818 is a reply to message #994567] |
Fri, 28 December 2012 06:00   |
Eclipse User |
|
|
|
Hi
if you see https://bugs.eclipse.org/bugs/show_bug.cgi?id=384621 and use
the update site you find there, there should be no need to use the
ContextMenuHelper manually, since the SWTBotTreeItem.contextMenu should
be fixed (it uses internally the ContextMenuHelper)...
are you sure that "Run As","Run on Server" are exactly the labels of the
context menu? No "..." anywhere?
hope this helps
Lorenzo
On 12/27/2012 06:47 PM, Shabari shetty wrote:
> Hi,
>
> I am trying to click the submenu of a context menu on a tree item using ContextMenuHelper. My code looks like below
>
> SWTBotView view = bot.viewByTitle("Package Explorer");
> view.setFocus();
> SWTBotTree tree = view.bot().tree();
> // tree.getAllItems()
> SWTBotTreeItem treeItem = view.bot().tree()
> .getTreeItem("JavaPrj");
> treeItem.expand();
> bot.sleep(1000);
> SWTBotTreeItem[] items = treeItem.getItems();
> SWTBotTreeItem srcNode2 = null;
> SWTBotTreeItem javaClass = null;
> for(SWTBotTreeItem prjNode : items){
> if(prjNode.getText().equals("src")){
> prjNode.expand();
> SWTBotTreeItem [] srcNodes = prjNode.getItems();
>
> for(SWTBotTreeItem srcNode : srcNodes){
> srcNode.expand();
> javaClass = srcNode.getItems()[0];
>
> }
> }
> }
> javaClass.select();
> ContextMenuHelper.clickContextMenu(tree, "Run As","Run on Server");
>
> Here I am trying to select a tree item node which is a java class then say Run As->Run On Server. I get the excatpion widget not found (Run As, Run on Server) exception. Please note that my context menu is not populated programmatic-ally. I am also attaching the class ContextMenuHelper.java which I am using. Can someone please tell m,e what do I need to change to make this working
>
> Thanks in advance
> Shabari
>
--
Lorenzo Bettini, PhD in Computer Science, DI, Univ. Torino
ICQ# lbetto, 16080134 (GNU/Linux User # 158233)
HOME: http://www.lorenzobettini.it MUSIC: http://www.purplesucker.com
http://www.myspace.com/supertrouperabba
BLOGS: http://tronprog.blogspot.com http://longlivemusic.blogspot.com
http://www.gnu.org/software/src-highlite
http://www.gnu.org/software/gengetopt
http://www.gnu.org/software/gengen http://doublecpp.sourceforge.net
|
|
|
|
|
|
|
|
|
|
|
|