Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[swtbot-dev] Improvement to SWTBot menu API and implementation

Hi,

I have made a contribution to the project that improves the SWTBot menu API and implementation. The change was tracked with https://bugs.eclipse.org/bugs/show_bug.cgi?id=479091 and has been merged.

I have been asked to describe the changes to this mailing list.

In a nutshell, the patch consolidates some improvements that were made through ContextMenuHelper that were only used with Tree and TreeItem context menus, and makes them available for every menu, whether the menu bar of a Shell or the popup (context) menu of a Control. The patch also attempts to more accurately reflect the SWT events that are sent during menu operations.

The existing API SWTBot.menu(String) and AbstractSWTBot.contextMenu(String) will find a menu depth-first recursively and return the first menu item that matches. It will now stop searching as soon as a match is found. For backward compatibility reasons, I did not want to replace these methods with non-recursive find, or with a variable parameter (String...).

The new API is much more explicit. You first get a menu bar with SWTBot.menu() or a popup menu with AbstractSWTBot.contextMenu(). Then you have a SWTBotRootMenu instance and from there you can get menu items using one of many ways:

bot.menu(String...) finds menu item at the given text path relative to this menu

bot.menu(String, boolean, int) finds n'th menu item with given text, recursive or not

bot.menu(Matcher, boolean, int) finds n'th menu item matching given matcher, recursive or not

bot.menu(String, String, boolean, int) finds menu item with given key/value pair in widget data, recursive or not

With the returned SWTBotMenu instance, you can continue finding menu items deeper using the exact same method signatures.

So if for example your tree control menus are:

A > B > C (1)
B > C (2)
C (3)
C (4)

treeBot.contextMenu("C") => C (1) for backward compatibility
treeBot.contextMenu().menu("C") => C (3)
treeBot.contextMenu().menu("A", "B", "C") => C (1)
treeBot.contextMenu().menu("A").menu("B").menu("C") => C (1)
treeBot.contextMenu().menu("A").menu("B", "C") => C (1)
treeBot.contextMenu().menu("B", "C") => C (2)
treeBot.contextMenu().menu("C", true, 0) => C (1)
treeBot.contextMenu().menu("C", true, 1) => C (2)
treeBot.contextMenu().menu("C", true, 2) => C (3)
treeBot.contextMenu().menu("C", true, 3) => C (4)
treeBot.contextMenu().menu("C", false, 0) => C (3)
treeBot.contextMenu().menu("C", false, 1) => C (4)

Same goes for a menu bar e.g. viewBot.menu().menu(...)

If you click() the returned menu item, if it has a sub-menu then nothing happens. Otherwise, the parent menus are hidden recursively, and the menu item is selected.

If you do not intend on clicking the menu item, you can dismiss it by calling hide(), this will also recursively hide the parent menus.

You should not be getting anymore Widget Is Disposed errors, unless you are reusing a menu or menu item after it, or one of its parent or child, has been clicked or hidden. If you do that, your test case is wrong ;)

Clicking should work correctly with SWT.Hide events even for dynamic (JFace) menus or E4 (injection) menus. However, I have not considered updating the code in org.eclipse.swtbot.e4.finder. I'm not sure how this package is used, but I suspect its menu finders could be aligned with the updated ones in org.eclipse.swtbot.swt.finder.

I hope you enjoy the new API. It will be available in SWTBot 2.4.0, or you can use it now if you get SWTBot from http://download.eclipse.org/technology/swtbot/snapshots in your target definition.

Patrick

Back to the top