/******************************************************************************* * Copyright (c) 2012 VMWare, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VMWare, Inc. - initial API and implementation *******************************************************************************/ package org.grails.ide.eclipse.ui.test.util; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TreeItem; 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.Result; import org.eclipse.swtbot.swt.finder.waits.Conditions; import org.eclipse.swtbot.swt.finder.waits.ICondition; import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton; 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.PlatformUI; import org.springsource.ide.eclipse.commons.frameworks.core.internal.plugins.PluginVersion; import org.springsource.ide.eclipse.commons.frameworks.test.util.SWTBotUtils; import org.springsource.ide.eclipse.commons.frameworks.test.util.TestKeyboard; import org.springsource.ide.eclipse.commons.frameworks.ui.internal.plugins.PluginOperation; import org.springsource.ide.eclipse.commons.frameworks.ui.internal.plugins.PluginState; import org.springsource.ide.eclipse.commons.frameworks.ui.internal.plugins.PluginManagerDialog.TreeElement; import org.grails.ide.eclipse.ui.internal.dialogues.GrailsPluginManagerDialogue; /** * @author Nieraj Singh * @author Kris De Volder * @created Jul 21, 2010 */ public class SWTBotPluginManagerUtil { // May be too long, but for consistency, allow tests to run longer rather // than fail more frequently public static final long PLUGIN_LIST_POPULATE = 40000; public static final long OPEN_MANAGER_TIMEOUT = 5000; private SWTBotPluginManagerUtil() { // util } protected static String getGrailsPluginManagerContextMenuName() { return "Grails Plugin Manager..."; } protected static String getGrailsPluginManagerShellTitle() { return "Grails Plugin Manager"; } /** * Given a tree item, this will retrieve the associated published version. * * @param bot * from which the tree can be accessed * @param item * tree item in the tree that should contain a published version * @return published version associated with given tree item */ public static PluginVersion getPublishedVersion( final SWTWorkbenchBot bot, final SWTBotTreeItem item) { final List<PluginVersion> found = new ArrayList<PluginVersion>(); bot.getDisplay().syncExec(new Runnable() { public void run() { TreeItem actualItem = item.widget; PluginVersion version = ((TreeElement) actualItem.getData()) .getVersionModel(); found.add(version); } }); return found.get(0); } /** * Given a tree item, retrieves the associated image. It may be null * * @param bot * from which tree can be accessed * @param item * whose image should be retrieved. * @return found image, or null if no image for this item */ public static Image getIconForPluginElement(final SWTWorkbenchBot bot, final SWTBotTreeItem item) { final List<Image> found = new ArrayList<Image>(); bot.getDisplay().syncExec(new Runnable() { public void run() { TreeItem actualItem = item.widget; found.add(actualItem.getImage()); } }); return found.get(0); } /** * Returns the plugin state of the given tree item. Can be null if it has no * state. * * @param bot * from which tree can be accessed * @param item * in the tree associated with a plugin version * @return plugin state for the plugin version. */ public static PluginState getStateOfPlugin(final SWTWorkbenchBot bot, final SWTBotTreeItem item) { final List<PluginState> found = new ArrayList<PluginState>(); bot.getDisplay().syncExec(new Runnable() { public void run() { TreeItem actualItem = item.widget; found.add(((TreeElement) actualItem.getData()).getPluginState()); } }); return found.get(0); } /** * Returns the tree item corresponding to the child version matching the * root item version. * * @param bot * from which access to tree is possible * @param rootItem * @return child version that matches the version of the root element */ public static SWTBotTreeItem getCorrespondingChildVersion( SWTWorkbenchBot bot, SWTBotTreeItem rootItem) { PluginVersion rootVersion = getPublishedVersion(bot, rootItem); return getPluginTreeItem(bot, rootVersion.getName(), rootVersion.getVersion()); } /** * Gets the tree item associated with the given plugin. The version ID * (number) is optional. If the version ID is null, this method will only * return the ROOT element matching the plugin name. * <p/> * If a version ID is specified, this method will return the exact CHILD * element matching the plugin name AND version ID. * * @param bot * from which access to tree is possible * @param pluginName * to find in tree * @param versionID * optional. If specified, the CHILD version element is return. * If null, only the ROOT element is returned * @return Child version element matching plugin name and version ID, or * ROOT element if no version ID is specified. */ public static SWTBotTreeItem getPluginTreeItem(SWTWorkbenchBot bot, final String pluginName, final String versionID) { SWTBotTreeItem[] items = bot.tree().getAllItems(); SWTBotTreeItem foundItem = null; for (SWTBotTreeItem item : items) { PluginVersion rootVersion = getPublishedVersion(bot, item); if (rootVersion.getName().equals(pluginName)) { if (versionID != null) { item.expand(); SWTBotTreeItem[] childElements = item.getItems(); for (SWTBotTreeItem childElement : childElements) { PluginVersion childVersion = SWTBotPluginManagerUtil .getPublishedVersion(bot, childElement); if (childVersion.getVersion().equals(versionID)) { SWTBotUtils .print("Found expected child version plugin for: " + childVersion.getName() + " Actual version:" + childVersion.getVersion() + ". Expected version: " + versionID); foundItem = childElement; break; } } } else { SWTBotUtils.print("Found expected root plugin. Actual: " + rootVersion.getName() + ". Expected: " + pluginName); foundItem = item; } break; } } return foundItem; } /** * Gets Grails manager dialogue controller by using a keyboard shortcut. * Note that if a dialogue is already opened, whether it was opened directly * programmatically or through an actual UI path like a keyboard shortcut or * context menu action, the opened dialogue will be returned instead until * it is closed. * * @param bot * that has access to the manager UI in the runtime * @param viewName * containing the project selection * @param projectName * name of a selected project for the manager * @return opened manager. */ public static GrailsDialogueController getGrailsManagerDialogueViaShortcutKey( final SWTWorkbenchBot bot, String viewName, String projectName) throws Exception { return new GrailsDialogueShortcutKeyController(projectName, bot, viewName); } public static void pressInstallButton(SWTWorkbenchBot bot) { pressButton(getInstallButton(bot)); } public static void pressOKButton(SWTWorkbenchBot bot) { pressButton(getOKButton(bot)); } public static void pressUninstallButton(SWTWorkbenchBot bot) { pressButton(getUninstallButton(bot)); } public static void pressUpdateButton(SWTWorkbenchBot bot) { pressButton(getUpdateButton(bot)); } public static void pressButton(SWTBotButton button) { button.setFocus(); if (button.isEnabled()) { button.click(); } } public static SWTBotButton getOKButton(SWTWorkbenchBot bot) { return bot.button("OK"); } public static SWTBotButton getInstallButton(SWTWorkbenchBot bot) { return bot.button(PluginOperation.INSTALL.getName()); } public static SWTBotButton getUninstallButton(SWTWorkbenchBot bot) { return bot.button(PluginOperation.UNINSTALL.getName()); } public static SWTBotButton getUpdateButton(SWTWorkbenchBot bot) { return bot.button(PluginOperation.UPDATE.getName()); } public static List<String> switchToInstallOnlyView(SWTWorkbenchBot bot) { return null; } public static List<String> switchToUpdateOnlyView(SWTWorkbenchBot bot) { return null; } public static List<String> switchToPendingChangesOnlyView( SWTWorkbenchBot bot) { return null; } public static SWTBotTree waitUntilManagerTreePopulates( final SWTWorkbenchBot bot) { final SWTBotTree tree = bot.tree(); bot.waitUntil(new ICondition() { public boolean test() throws Exception { SWTBotTreeItem[] items = tree.getAllItems(); if (items != null && items.length > 0) { return true; } return false; } public void init(SWTBot bot) { // nothing } public String getFailureMessage() { return "Manager tree did not populate"; } }, PLUGIN_LIST_POPULATE); return tree; } static class GrailsDialogueShortcutKeyController extends GrailsDialogueController { public GrailsDialogueShortcutKeyController(String projectName, SWTWorkbenchBot bot, String viewName) { super(projectName, bot, viewName); } protected void openGrailsManager() throws Exception { SWTBotUtils.print("Opening Grails Plugin manager for: " + getProject().getName()); new TestKeyboard(bot).ALT_G_M(); // wait for the manager to open. bot.sleep(OPEN_MANAGER_TIMEOUT); //May get a progress dialog while waiting for plugin list to resolve SWTBotShell warningShell = bot.activeShell(); if (warningShell!=null && warningShell.isOpen() && warningShell.getText().equals("Progress Information")) { bot.waitUntil(Conditions.shellCloses(warningShell), PLUGIN_LIST_POPULATE); } // May get a warning dialogue warningShell = bot.activeShell(); if (warningShell != null && warningShell.isOpen() && warningShell .getText() .equals(GrailsPluginManagerDialogue.INITIAL_REFRESH_DEPENDENCIES_DIALOGUE_TITLE)) { bot.button("Yes").click(); } waitUntilManagerTreePopulates(bot); } } public abstract static class GrailsDialogueController { private static SWTBotShell activeManager; protected SWTWorkbenchBot bot; private String projectName; private String viewName; // Access through accessor method only private IProject project; public GrailsDialogueController(String projectName, SWTWorkbenchBot bot, String viewName) { this.projectName = projectName; this.bot = bot; this.viewName = viewName; } public SWTBotShell getOpenedGrailsManager() throws Exception { if (activeManager != null && activeManager.isOpen()) { return activeManager; } if (activeManager != null) { activeManager.close(); } // Activate the main shell first. UIThreadRunnable.syncExec(new Result<Shell>() { public Shell run() { Shell mainShell = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getShell(); mainShell.setActive(); mainShell.setFocus(); return mainShell; } }); SWTBotTree explorerTree = SWTBotUtils.selectProject(bot, getProject().getName(), viewName); bot.waitUntil(SWTBotUtils.widgetMakeActive(explorerTree)); assertTrue(explorerTree.isActive()); openGrailsManager(); try { activeManager = bot.shell(getGrailsPluginManagerShellTitle()); } catch (WidgetNotFoundException e) { //Create an error message with some info about what's going on in the console (command output should be there) throw new Error("Couldn't find the PluginManager.\n" + "---- Console text at this time ----\n" + SWTBotUtils.getConsoleText(bot)); } bot.waitUntil(SWTBotUtils.widgetMakeActive(activeManager)); assertTrue(activeManager.isOpen()); return activeManager; } public boolean isOpen() { return activeManager != null && activeManager.isOpen(); } protected IProject getProject() { if (project == null) { project = ResourcesPlugin.getWorkspace().getRoot() .getProject(projectName); SWTBotUtils .print("Obtained project selection for Grails Plugin Manager test: " + project.getName()); } return project; } abstract protected void openGrailsManager() throws Exception; } }