X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=tmf%2Forg.eclipse.tracecompass.tmf.ui.swtbot.tests%2Fshared%2Forg%2Feclipse%2Ftracecompass%2Ftmf%2Fui%2Fswtbot%2Ftests%2Fshared%2FSWTBotUtils.java;h=dc2189419a885ef14ce8b340d1125caf97989ba2;hb=b6fddb839ef7b61c5a418a5e05091c52b3d25c67;hp=f8edc19304a22d0bffedbf67a4b0dc3cad5bd3e0;hpb=fd5f786c909184371b5873a14def2c86d3248f43;p=deliverable%2Ftracecompass.git diff --git a/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/SWTBotUtils.java b/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/SWTBotUtils.java index f8edc19304..dc2189419a 100644 --- a/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/SWTBotUtils.java +++ b/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/SWTBotUtils.java @@ -16,10 +16,12 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.util.Arrays; import java.util.List; import java.util.TimeZone; import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.log4j.Logger; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -28,7 +30,6 @@ import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jface.bindings.keys.IKeyLookup; import org.eclipse.jface.bindings.keys.KeyStroke; @@ -47,8 +48,11 @@ import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor; import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; import org.eclipse.swtbot.swt.finder.SWTBot; import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; +import org.eclipse.swtbot.swt.finder.keyboard.Keyboard; +import org.eclipse.swtbot.swt.finder.keyboard.Keystrokes; import org.eclipse.swtbot.swt.finder.results.Result; import org.eclipse.swtbot.swt.finder.results.VoidResult; +import org.eclipse.swtbot.swt.finder.utils.MessageFormat; import org.eclipse.swtbot.swt.finder.utils.SWTUtils; import org.eclipse.swtbot.swt.finder.waits.Conditions; import org.eclipse.swtbot.swt.finder.waits.DefaultCondition; @@ -71,6 +75,7 @@ import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder; import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers.ProjectElementHasChild; +import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils; import org.eclipse.tracecompass.tmf.ui.views.TracingPerspectiveFactory; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; @@ -88,75 +93,29 @@ import org.hamcrest.Matcher; @SuppressWarnings("restriction") public final class SWTBotUtils { - private static final long MAX_JOBS_WAIT_TIME = 300000; private static final String WINDOW_MENU = "Window"; private static final String PREFERENCES_MENU_ITEM = "Preferences"; private static boolean fPrintedEnvironment = false; + private static Logger log = Logger.getLogger(SWTBotUtils.class); private SWTBotUtils() { + } private static final String TRACING_PERSPECTIVE_ID = TracingPerspectiveFactory.ID; /** * Waits for all Eclipse jobs to finish. Times out after - * SWTBotUtils#MAX_JOBS_WAIT_TIME by default. + * WaitUtils#MAX_JOBS_WAIT_TIME by default. * - * @throws TimeoutException + * @throws RuntimeException * once the waiting time passes the default maximum value - */ - public static void waitForJobs() { - waitForJobs(MAX_JOBS_WAIT_TIME); - } - - /** - * Waits for all Eclipse jobs to finish * - * @param maxWait - * the maximum time to wait, in milliseconds. Once the waiting - * time passes the maximum value, a TimeoutException is thrown - * @throws TimeoutException - * once the waiting time passes the maximum value + * @deprecated Use {@link WaitUtils#waitForJobs()} instead */ - public static void waitForJobs(long maxWait) { - long waitStart = System.currentTimeMillis(); - while (!Job.getJobManager().isIdle()) { - if (System.currentTimeMillis() - waitStart > maxWait) { - printJobs(); - throw new TimeoutException("Timed out waiting for jobs to finish."); - } - - delay(100); - } - } - - private static void printJobs() { - Job[] jobs = Job.getJobManager().find(null); - for (Job job : jobs) { - System.err.println(job.toString() + " state: " + jobStateToString(job.getState())); - Thread thread = job.getThread(); - if (thread != null) { - for (StackTraceElement stractTraceElement : thread.getStackTrace()) { - System.err.println(" " + stractTraceElement); - } - } - System.err.println(); - } - } - - private static String jobStateToString(int jobState) { - switch (jobState) { - case Job.RUNNING: - return "RUNNING"; - case Job.WAITING: - return "WAITING"; - case Job.SLEEPING: - return "SLEEPING"; - case Job.NONE: - return "NONE"; - default: - return "UNKNOWN"; - } + @Deprecated + public static void waitForJobs() { + WaitUtils.waitForJobs(); } /** @@ -191,7 +150,7 @@ public final class SWTBotUtils { } }); - SWTBotUtils.waitForJobs(); + WaitUtils.waitForJobs(); } /** @@ -207,13 +166,20 @@ public final class SWTBotUtils { public static void deleteProject(final String projectName, boolean deleteResources, SWTWorkbenchBot bot) { // Wait for any analysis to complete because it might create // supplementary files - SWTBotUtils.waitForJobs(); + WaitUtils.waitForJobs(); try { ResourcesPlugin.getWorkspace().getRoot().getProject(projectName).refreshLocal(IResource.DEPTH_INFINITE, null); } catch (CoreException e) { } - SWTBotUtils.waitForJobs(); + WaitUtils.waitForJobs(); + + closeSecondaryShells(bot); + WaitUtils.waitForJobs(); + + if (!ResourcesPlugin.getWorkspace().getRoot().getProject(projectName).exists()) { + return; + } final SWTBotView projectViewBot = bot.viewById(IPageLayout.ID_PROJECT_EXPLORER); projectViewBot.setFocus(); @@ -234,7 +200,7 @@ public final class SWTBotUtils { bot.waitUntil(Conditions.widgetIsEnabled(okButton)); okButton.click(); - SWTBotUtils.waitForJobs(); + WaitUtils.waitForJobs(); } /** @@ -281,7 +247,6 @@ public final class SWTBotUtils { }); } - /** * Focus on the main window * @@ -289,11 +254,43 @@ public final class SWTBotUtils { * swtbotshells for all the shells */ public static void focusMainWindow(SWTBotShell[] shellBots) { + SWTBotShell mainShell = getMainShell(shellBots); + if (mainShell != null) { + mainShell.activate(); + } + } + + private static SWTBotShell getMainShell(SWTBotShell[] shellBots) { + SWTBotShell mainShell = null; for (SWTBotShell shellBot : shellBots) { if (shellBot.getText().toLowerCase().contains("eclipse")) { - shellBot.activate(); + mainShell = shellBot; } } + return mainShell; + } + + /** + * Close all non-main shells that are visible. + * + * @param bot + * the workbench bot + */ + public static void closeSecondaryShells(SWTWorkbenchBot bot) { + SWTBotShell[] shells = bot.shells(); + SWTBotShell mainShell = getMainShell(shells); + if (mainShell == null) { + return; + } + + // Close all non-main shell but make sure we don't close an invisible + // shell such the special "limbo shell" that Eclipse needs to work + Arrays.stream(shells) + .filter(shell -> shell != mainShell) + .filter(s -> !s.widget.isDisposed()) + .filter(SWTBotShell::isVisible) + .peek(shell -> log.debug(MessageFormat.format("Closing lingering shell with title {0}", shell.getText()))) + .forEach(SWTBotShell::close); } /** @@ -318,7 +315,8 @@ public final class SWTBotUtils { * Close a view with an id * * @param viewId - * the view id, like "org.eclipse.linuxtools.tmf.ui.views.histogram" + * the view id, like + * "org.eclipse.linuxtools.tmf.ui.views.histogram" * @param bot * the workbench bot */ @@ -366,7 +364,8 @@ public final class SWTBotUtils { printEnvironment(); // There seems to be problems on some system where the main shell is - // not in focus initially. This was seen using Xvfb and Xephyr on some occasions. + // not in focus initially. This was seen using Xvfb and Xephyr on + // some occasions. focusMainWindow(bot.shells()); Shell shell = bot.activeShell().widget; @@ -383,7 +382,8 @@ public final class SWTBotUtils { return; } - // Print some information about the environment that could affect test outcome + // Print some information about the environment that could affect test + // outcome Rectangle bounds = Display.getDefault().getBounds(); System.out.println("Display size: " + bounds.width + "x" + bounds.height); @@ -394,6 +394,11 @@ public final class SWTBotUtils { String gtkVersion = System.getProperty("org.eclipse.swt.internal.gtk.version"); if (gtkVersion != null) { System.out.println("GTK version=" + gtkVersion); + // Try to print the GTK theme information as behavior can change + // depending on the theme + String gtkTheme = System.getProperty("org.eclipse.swt.internal.gtk.theme"); + System.out.println("GTK theme=" + (gtkTheme == null ? "unknown" : gtkTheme)); + String overlayScrollbar = System.getenv("LIBOVERLAY_SCROLLBAR"); if (overlayScrollbar != null) { System.out.println("LIBOVERLAY_SCROLLBAR=" + overlayScrollbar); @@ -487,7 +492,7 @@ public final class SWTBotUtils { if (delay) { delay(1000); - waitForJobs(); + WaitUtils.waitForJobs(); } } @@ -513,7 +518,7 @@ public final class SWTBotUtils { } }); - SWTBotUtils.waitForJobs(); + WaitUtils.waitForJobs(); SWTBotUtils.delay(1000); assertNotNull(tmfEd); return editorBot; @@ -546,7 +551,6 @@ public final class SWTBotUtils { SWTBotTreeItem currentItem = tracesNode; for (String segment : elementPath.segments()) { currentItem = getTraceProjectItem(projectExplorerBot, currentItem, segment); - currentItem.select(); currentItem.doubleClick(); } @@ -556,6 +560,26 @@ public final class SWTBotUtils { return (TmfEventsEditor) editorPart; } + /** + * Returns the child tree item of the specified item at the given sub-path. + * The project element labels may have a count suffix in the format ' [n]'. + * + * @param bot + * a given workbench bot + * @param parentItem + * the parent tree item + * @param path + * the desired child element sub-path (without suffix) + * @return the a {@link SWTBotTreeItem} with the specified name + */ + public static SWTBotTreeItem getTraceProjectItem(SWTBot bot, final SWTBotTreeItem parentItem, final String... path) { + SWTBotTreeItem item = parentItem; + for (String name : path) { + item = getTraceProjectItem(bot, item, name); + } + return item; + } + /** * Returns the child tree item of the specified item with the given name. * The project element label may have a count suffix in the format ' [n]'. @@ -640,6 +664,26 @@ public final class SWTBotUtils { }); } + /** + * Clear the trace folder (using the UI) + * + * @param bot + * a given workbench bot + * @param projectName + * the name of the project (needs to exist) + */ + public static void clearTracesFolderUI(SWTWorkbenchBot bot, String projectName) { + SWTBotTreeItem tracesFolder = selectTracesFolder(bot, projectName); + tracesFolder.contextMenu().menu("Clear").click(); + String CONFIRM_CLEAR_DIALOG_TITLE = "Confirm Clear"; + bot.waitUntil(Conditions.shellIsActive(CONFIRM_CLEAR_DIALOG_TITLE)); + + SWTBotShell shell = bot.shell(CONFIRM_CLEAR_DIALOG_TITLE); + shell.bot().button("Yes").click(); + bot.waitUntil(Conditions.shellCloses(shell)); + bot.waitWhile(ConditionHelpers.treeItemHasChildren(tracesFolder)); + } + /** * Clear the experiment folder * @@ -693,12 +737,18 @@ public final class SWTBotUtils { * @param bot * a given workbench bot * @param projectName - * the name of the project (it needs to exist or else it would time out) + * the name of the project (it needs to exist or else it would + * time out) * @return a {@link SWTBotTreeItem} of the project */ public static SWTBotTreeItem selectProject(SWTWorkbenchBot bot, String projectName) { SWTBotView projectExplorerBot = bot.viewByTitle("Project Explorer"); projectExplorerBot.show(); + // FIXME: Bug 496519. Sometimes, the tree becomes disabled for a certain + // amount of time. This can happen during a long running operation + // (BusyIndicator.showWhile) which brings up the modal dialog "operation + // in progress" and this disables all shells + projectExplorerBot.bot().waitUntil(Conditions.widgetIsEnabled(projectExplorerBot.bot().tree())); SWTBotTreeItem treeItem = projectExplorerBot.bot().tree().getTreeItem(projectName); treeItem.select(); return treeItem; @@ -725,7 +775,7 @@ public final class SWTBotUtils { if (res[0] != null) { fail(res[0].getMessage()); } - waitForJobs(); + WaitUtils.waitForJobs(); } /** @@ -810,14 +860,37 @@ public final class SWTBotUtils { bot.waitUntil(ConditionHelpers.IsTreeNodeAvailable(nodeNames[0], tree)); SWTBotTreeItem currentNode = tree.getTreeItem(nodeNames[0]); - for (int i = 1; i < nodeNames.length; i++) { + return getTreeItem(bot, currentNode, Arrays.copyOfRange(nodeNames, 1, nodeNames.length)); + } + + /** + * Get the tree item from a parent tree item at the specified location + * + * @param bot + * the SWTBot + * @param treeItem + * the treeItem to find the tree item under + * @param nodeNames + * the path to the tree item, in the form of node names (from + * parent to child). + * @return the tree item + */ + public static SWTBotTreeItem getTreeItem(SWTBot bot, SWTBotTreeItem treeItem, String... nodeNames) { + if (nodeNames.length == 0) { + return treeItem; + } + + SWTBotTreeItem currentNode = treeItem; + for (int i = 0; i < nodeNames.length; i++) { + bot.waitUntil(ConditionHelpers.treeItemHasChildren(treeItem)); currentNode.expand(); String nodeName = nodeNames[i]; try { bot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(nodeName, currentNode)); } catch (TimeoutException e) { - //FIXME: Sometimes in a JFace TreeViewer, it expands to nothing. Need to find out why. + // FIXME: Sometimes in a JFace TreeViewer, it expands to + // nothing. Need to find out why. currentNode.collapse(); currentNode.expand(); bot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(nodeName, currentNode)); @@ -830,6 +903,21 @@ public final class SWTBotUtils { return currentNode; } + /** + * Press the keyboard shortcut that goes to the top of a tree widget. The + * key combination can differ on different platforms. + * + * @param keyboard + * the keyboard to use + */ + public static void pressShortcutGoToTreeTop(Keyboard keyboard) { + if (SWTUtils.isMac()) { + keyboard.pressShortcut(Keystrokes.ALT, Keystrokes.UP); + } else { + keyboard.pressShortcut(Keystrokes.HOME); + } + } + /** * Get the active events editor. Note that this will wait until such editor * is available. @@ -839,26 +927,26 @@ public final class SWTBotUtils { * @return the active events editor */ public static SWTBotEditor activeEventsEditor(final SWTWorkbenchBot workbenchBot) { - final SWTBotEditor editor[] = new SWTBotEditor[1]; - workbenchBot.waitUntil(new DefaultCondition() { - @Override - public boolean test() throws Exception { - List editors = workbenchBot.editors(WidgetMatcherFactory.withPartId(TmfEventsEditor.ID)); - for (SWTBotEditor e : editors) { - if (e.isActive() && !e.getWidget().isDisposed()) { - editor[0] = e; - return true; - } - } - return false; - } + ConditionHelpers.ActiveEventsEditor condition = new ConditionHelpers.ActiveEventsEditor(workbenchBot, null); + workbenchBot.waitUntil(condition); + return condition.getActiveEditor(); + } - @Override - public String getFailureMessage() { - return "Active events editor not found"; - } - }); - return editor[0]; + /** + * Get the active events editor. Note that this will wait until such editor + * is available. + * + * @param workbenchBot + * a given workbench bot + * @param editorTitle + * the desired editor title. If null, any active events editor + * will be considered valid. + * @return the active events editor + */ + public static SWTBotEditor activeEventsEditor(final SWTWorkbenchBot workbenchBot, String editorTitle) { + ConditionHelpers.ActiveEventsEditor condition = new ConditionHelpers.ActiveEventsEditor(workbenchBot, editorTitle); + workbenchBot.waitUntil(condition); + return condition.getActiveEditor(); } /**