blob: cbd097e82ecdfdd3bef37e77e751a545d98b9da4 [file] [log] [blame]
package org.eclipse.jpt.jpadiagrameditor.swtbot.tests.utils;
import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.withMnemonic;
import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.withRegex;
import static org.eclipse.swtbot.swt.finder.waits.Conditions.shellIsActive;
import static org.eclipse.swtbot.swt.finder.waits.Conditions.widgetIsEnabled;
import static org.hamcrest.core.AllOf.allOf;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import java.text.MessageFormat;
import java.util.Arrays;
import org.eclipse.core.runtime.Assert;
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.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.swt.finder.SWTBot;
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.utils.SWTBotPreferences;
import org.eclipse.swtbot.swt.finder.utils.SWTUtils;
import org.eclipse.swtbot.swt.finder.waits.Conditions;
import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.hamcrest.Matcher;
@SuppressWarnings("restriction")
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 )
{
final Matcher<?>[] matchers = new Matcher<?>[texts.length];
for ( int i = 0; i < texts.length; i++ )
{
// matchers[i] = allOf( instanceOf( MenuItem.class ), withMnemonic( texts[i] ) );
matchers[i] = allOf( instanceOf( MenuItem.class ), withRegex( texts[i] ) );
}
// 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 ( int i = 0; i < matchers.length; i++ )
{
menuItem = show( menu, matchers[i] );
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() );
}
} );
}
/**
* Clicks the menu from the menu bar matching the given text in the active
* shell.
*
* @param texts
* the text on the context menu.
* @throws WidgetNotFoundException
* if the widget is not found.
*/
public static void clickMenu(final String... texts) {
clickMenu(new SWTWorkbenchBot().activeShell(), texts);
}
/**
* Clicks the menu from the menu bar matching the given text.
*
* @param bot
* the widget.
* @param texts
* the text on the context menu.
* @throws WidgetNotFoundException
* if the widget is not found.
*/
public static MenuItem clickMenu(final AbstractSWTBot<?> bot, final String... texts) {
return clickMenu(bot, false, texts);
}
/**
* Clicks the menu from the menu bar matching the given text and toggles the
* selection of the menu item
*
* @param bot
* the widget.
* @param texts
* the text on the context menu.
* @throws WidgetNotFoundException
* if the widget is not found.
*/
public static void clickMenuToggleSeletion(final AbstractSWTBot<?> bot, final String... texts) {
clickMenu(bot, true, texts);
}
/**
* Clicks the menu from the menu bar matching the given text and toggles the
* selection of the menu item
*
* @param bot
* the widget.
* @param texts
* the text on the context menu.
* @param toggleSelection
* a flag that shows if the selection of the menu item should be
* toggled
* @throws WidgetNotFoundException
* if the widget is not found.
*/
private static MenuItem clickMenu(final AbstractSWTBot<?> bot, boolean toggleSelection, final String... texts) {
// show
final MenuItem menuItem = UIThreadRunnable.syncExec(new WidgetResult<MenuItem>() {
@Override
public MenuItem run() {
MenuItem item = null;
Shell control = (Shell) bot.widget;
Menu menu = control.getMenuBar();
for (String text : texts) {
Matcher<?> matcher = allOf(instanceOf(MenuItem.class), withMnemonic(text));
item = show(menu, matcher);
if (item != null) {
menu = item.getMenu();
} else {
hide(menu);
break;
}
}
return item;
}
});
if (menuItem == null) {
throw new WidgetNotFoundException("Could not find menu: " + Arrays.asList(texts));
}
// click
new SWTWorkbenchBot().waitUntil(Conditions.widgetIsEnabled(new SWTBotMenu(menuItem)));
click(menuItem, toggleSelection);
// hide
UIThreadRunnable.syncExec(new VoidResult() {
@Override
public void run() {
hide(menuItem.getParent());
}
});
return menuItem;
}
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 );
}
} );
}
/**
* Click on a menu item
*
* @param menuItem
* the menu item that will click
* @param toogleSelection
* a flag that shows if the selection of the menu item should be
* toggled
*/
private static void click(final MenuItem menuItem, final boolean toogleSelection) {
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() {
@Override
public void run() {
boolean seleted = true;
if (toogleSelection && (SWTUtils.hasStyle(menuItem, SWT.CHECK) | SWTUtils.hasStyle(menuItem, SWT.RADIO))) {
seleted = !menuItem.getSelection();
}
menuItem.setSelection(seleted);
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() );
}
}
/**
* Selects an tree item in the browser tree and expands the selected tree
* item. Takes care that all attributes and child entries are initialized so
* that there are no pending background actions and event notifications.
* This is necessary to avoid race conditions.
*
* @param tree
* the browser tree
* @param path
* the path to the tree item
* @return the selected tree item as SWTBotTreeItem
* @throws WidgetNotFoundException
* when the tree item is not found in the tree
*/
public static SWTBotTreeItem selectTreeItem(final SWTBotTree tree, final String... path) throws WidgetNotFoundException {
return selectTreeItem(tree, true, path);
}
/**
* Selects an tree item in the browser tree and optionally expands the
* selected tree item. Takes care that all attributes and child entries are
* initialized so that there are no pending background actions and event
* notifications. This is necessary to avoid race conditions.
*
* @param tree
* the browser tree
* @param expandChild
* true to expand the child tree item
* @param path
* the path to the tree item
* @return the selected tree item as SWTBotTreeItem
* @throws WidgetNotFoundException
* when the tree item is not found in the tree
*/
public static SWTBotTreeItem selectTreeItem(final SWTBotTree tree, final boolean expandChild, final String... path)
throws WidgetNotFoundException {
tree.unselect();
SWTBotTreeItem treeItem = getTreeItem(tree, expandChild, path);
waitForWidgetEnabled(treeItem);
treeItem.select();
return treeItem;
}
/**
* Finds a tree item in a tree and and optionally expands the found tree
* item. Takes care that all attributes and child entries are initialized so
* that there are no pending background actions and event notifications.
* This is necessary to avoid race conditions.
*
* @param tree
* the tree
* @param expandChild
* true to expand the found tree item
* @param path
* the path to the tree item
* @return the tree item as SWTBotTreeItem
* @throws WidgetNotFoundException
* when the tree item is not found in the tree
*/
public static SWTBotTreeItem getTreeItem(final SWTBotTree tree, final boolean expandChild, final String... path) throws WidgetNotFoundException {
Assert.isTrue(path.length > 0);
SWTBotTreeItem treeItem = null;
// try {
// wait for the first item
new SWTBot().waitUntil(new DefaultCondition() {
@Override
public boolean test() throws Exception {
try {
tree.getTreeItem(path[0]);
return true;
} catch (WidgetNotFoundException wnfe) {
return false;
}
}
@Override
public String getFailureMessage() {
return "Could not find node with text " + path[0]; //$NON-NLS-1$
}
});
treeItem = tree.getTreeItem(path[0]);
for (int i = 1; i < path.length; i++) {
if (treeItem.rowCount() > 0) {
waitForWidgetEnabled(tree);
treeItem.expand();
}
final String nodeText = path[i];
final SWTBotTreeItem currentTreeItem = treeItem;
// wait until the node appears in the
// expanded subtree
// as the expansion is executed
// asynchronously in the UI thread
new SWTBot().waitUntil(new DefaultCondition() {
@Override
public boolean test() throws Exception {
try {
currentTreeItem.getNode(nodeText);
return true;
} catch (WidgetNotFoundException wnfe) {
currentTreeItem.collapse();
currentTreeItem.expand();
return false;
}
}
@Override
public String getFailureMessage() {
return "Could not find node with text " + nodeText; //$NON-NLS-1$
}
});
treeItem = treeItem.getNode(nodeText);
}
if (treeItem.widget.isDisposed()) {
getTreeItem(tree, expandChild, path);
} else {
if (expandChild && (treeItem.rowCount() > 0)) {
waitForWidgetEnabled(tree);
treeItem.expand();
}
}
// } catch (TimeoutException te) {
// throw new WidgetNotFoundException(te.getMessage());
// }
return treeItem;
}
/**
* Waits until a widget is enabled
*
* @param widget
* the widget
*/
public static void waitForWidgetEnabled(AbstractSWTBot<? extends Widget> widget) {
waitForWidgetEnabled(widget, SWTBotPreferences.DEFAULT_POLL_DELAY);
}
/**
* Waits until a widget is enabled
*
* @param widget
* @param pollDelay
* the interval on which the check is performed
*/
public static void waitForWidgetEnabled(AbstractSWTBot<? extends Widget> widget, long pollDelay) {
new SWTWorkbenchBot().waitUntil(widgetIsEnabled(widget), SWTBotPreferences.TIMEOUT, pollDelay);
}
public static SWTBotTreeItem selectNodeInTree(SWTBotTree tree, String... path) {
SWTBotTreeItem firstLevelTreeItem = tree.getTreeItem(path[0]);
firstLevelTreeItem.select();
firstLevelTreeItem.click();
firstLevelTreeItem.expand();
if (path.length > 1) {
String[] newPath = Arrays.copyOfRange(path, 1, path.length);
return selectSubnode(firstLevelTreeItem, newPath);
}
return firstLevelTreeItem;
}
private static SWTBotTreeItem selectSubnode(SWTBotTreeItem parentNode, String... path) {
SWTBotTreeItem resultTreeItem = parentNode;
for (int i = 0; i < path.length; i++) {
resultTreeItem = parentNode.getNode(path[i]);
resultTreeItem.select();
resultTreeItem.click();
resultTreeItem.expand();
if (i < (path.length - 1)) {
String[] newPath = Arrays.copyOfRange(path, 1, path.length);
return selectSubnode(resultTreeItem, newPath);
}
}
return resultTreeItem;
}
/**
* Open properties in the given path
*
* @param contextMenu
* the name of the context menu
* @param pathToResource
* the path to the resource
* @return the workbench bot
*/
public static SWTWorkbenchBot openProjectProperties(SWTWorkbenchBot bot, String projectName) {
bot.viewByTitle("Project Explorer").show();
SWTBotTree resourcesTree = bot.tree();
// Depending on the previous operation the tree can
// be disabled.
// This will fail expanded operations below. That is
// way we need wait condition.
bot.waitUntil(widgetIsEnabled(resourcesTree));
selectTreeItem(resourcesTree, projectName);
clickContextMenu(resourcesTree, WorkbenchMessages.Workbench_properties);
bot.waitUntil(shellIsActive(MessageFormat.format(WorkbenchMessages.PropertyDialog_propertyMessage, projectName)), 20000);
SWTBotShell shell = bot.shell(MessageFormat.format(WorkbenchMessages.PropertyDialog_propertyMessage, projectName));
shell.activate();
return bot;
}
}