Make waitForJobs available to non-SWTBot test plugins
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui.swtbot.tests / shared / org / eclipse / tracecompass / tmf / ui / swtbot / tests / shared / SWTBotUtils.java
index 042ab9721dca54f0f8032a9cf08a24f216c23378..a1a8018f06c8356ab78805c42b5bc159d4aa0270 100644 (file)
@@ -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.JobUtils;
 import org.eclipse.tracecompass.tmf.ui.views.TracingPerspectiveFactory;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IEditorReference;
@@ -92,8 +97,10 @@ public final class SWTBotUtils {
     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;
@@ -102,61 +109,11 @@ public final class SWTBotUtils {
      * Waits for all Eclipse jobs to finish. Times out after
      * SWTBotUtils#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
-     */
-    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";
-        }
+        JobUtils.waitForJobs(MAX_JOBS_WAIT_TIME);
     }
 
     /**
@@ -215,6 +172,9 @@ public final class SWTBotUtils {
 
         SWTBotUtils.waitForJobs();
 
+        closeSecondaryShells(bot);
+        SWTBotUtils.waitForJobs();
+
         final SWTBotView projectViewBot = bot.viewById(IPageLayout.ID_PROJECT_EXPLORER);
         projectViewBot.setFocus();
 
@@ -289,11 +249,42 @@ 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(SWTBotShell::isVisible)
+                .peek(shell -> log.debug(MessageFormat.format("Closing lingering shell with title {0}", shell.getText())))
+                .forEach(SWTBotShell::close);
     }
 
     /**
@@ -394,6 +385,10 @@ 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);
@@ -546,7 +541,6 @@ public final class SWTBotUtils {
         SWTBotTreeItem currentItem = tracesNode;
         for (String segment : elementPath.segments()) {
             currentItem = getTraceProjectItem(projectExplorerBot, currentItem, segment);
-            currentItem.select();
             currentItem.doubleClick();
         }
 
@@ -640,6 +634,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
      *
@@ -815,7 +829,29 @@ 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];
@@ -835,6 +871,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.
This page took 0.037528 seconds and 5 git commands to generate.