swtbot: Fix SWTBotUtils instability
authorPatrick Tasse <patrick.tasse@gmail.com>
Fri, 27 Mar 2015 21:50:58 +0000 (17:50 -0400)
committerPatrick Tasse <patrick.tasse@gmail.com>
Tue, 31 Mar 2015 15:28:11 +0000 (11:28 -0400)
Tracing project elements that have a label with a count suffix (e.g.
trace folders) can have the count updated in the middle of a test by a
resource change event. Methods to get those tree items should be able to
handle this atomically.

Methods that need a project tree item now wait until it is available.

The method openEditor() now waits for the editor to be opened.

Change-Id: I4c2540fcc8a947ca4f61de66372968b11b10df7c
Signed-off-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-on: https://git.eclipse.org/r/44788
Reviewed-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/ConditionHelpers.java
org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/SWTBotUtils.java

index fe7b0b1c036a052acb9a80cf3e8d68a198fd1918..f4bef92e864d432439d9f42f7ff1859c4b3dd7fb 100644 (file)
@@ -9,6 +9,7 @@
  * Contributors:
  *   Matthew Khouzam - Initial API and implementation
  *   Alexandre Montplaisir - Replaced separate Condition objects by anonymous classes
+ *   Patrick Tasse - Add projectElementHasChild condition
  *******************************************************************************/
 
 package org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared;
@@ -17,8 +18,10 @@ package org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared;
 import org.eclipse.jface.wizard.IWizardContainer;
 import org.eclipse.jface.wizard.IWizardPage;
 import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.osgi.util.NLS;
 import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
 import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
 import org.eclipse.swtbot.swt.finder.waits.ICondition;
 import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
 import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
@@ -192,4 +195,58 @@ public final class ConditionHelpers {
             }
         };
     }
+
+    /**
+     * Condition to check if a tracing project element has a child with the
+     * specified name. A project element label may have a count suffix in the
+     * format ' [n]'.
+     */
+    public static class ProjectElementHasChild extends DefaultCondition {
+
+        private final SWTBotTreeItem fParentItem;
+        private final String fName;
+        private final String fRegex;
+        private SWTBotTreeItem fItem = null;
+
+        /**
+         * Constructor.
+         *
+         * @param parentItem
+         *            the parent item
+         * @param name
+         *            the child name to look for
+         */
+        public ProjectElementHasChild(final SWTBotTreeItem parentItem, final String name) {
+            fParentItem = parentItem;
+            fName = name;
+            /* Project element labels may have count suffix */
+            fRegex = name + "(\\s\\[(\\d)+\\])?";
+        }
+
+        @Override
+        public boolean test() throws Exception {
+            fParentItem.expand();
+            for (SWTBotTreeItem item : fParentItem.getItems()) {
+                if (item.getText().matches(fRegex)) {
+                    fItem = item;
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public String getFailureMessage() {
+            return NLS.bind("No child of {0} found with name {1}", fParentItem.getText(), fName);
+        }
+
+        /**
+         * Returns the matching child item if the condition returned true.
+         *
+         * @return the matching item
+         */
+        public SWTBotTreeItem getItem() {
+            return fItem;
+        }
+    }
 }
\ No newline at end of file
index ceccb7a22c0136f6342b3599d0e26548a13a4696..7454d19a488f53b083ef227a1bda81cf6c9e3451 100644 (file)
@@ -13,6 +13,7 @@
 package org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared;
 
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.util.List;
@@ -52,6 +53,7 @@ import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper;
 import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry;
 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.views.TracingPerspectiveFactory;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IEditorReference;
@@ -321,56 +323,42 @@ public final class SWTBotUtils {
         projectExplorerBot.setFocus();
 
         final SWTBotTree tree = bot.tree();
+        bot.waitUntil(ConditionHelpers.IsTreeNodeAvailable(projectName, tree));
         final SWTBotTreeItem treeItem = tree.getTreeItem(projectName);
         treeItem.expand();
 
-        String nodeName = getFullNodeName(treeItem, TmfTracesFolder.TRACES_FOLDER_NAME);
-        bot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(nodeName, treeItem));
-        SWTBotTreeItem tracesNode = treeItem.getNode(nodeName);
+        SWTBotTreeItem tracesNode = getTraceProjectItem(bot, treeItem, TmfTracesFolder.TRACES_FOLDER_NAME);
         tracesNode.expand();
 
-        SWTBotTreeItem currentNode = tracesNode;
+        SWTBotTreeItem currentItem = tracesNode;
         for (String segment : elementPath.segments()) {
-            String fullNodeName = getFullNodeName(currentNode, segment);
-            bot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(fullNodeName, currentNode));
-            SWTBotTreeItem newNode = currentNode.getNode(fullNodeName);
-            newNode.select();
-            newNode.doubleClick();
-            currentNode = newNode;
+            currentItem = getTraceProjectItem(bot, currentItem, segment);
+            currentItem.select();
+            currentItem.doubleClick();
         }
 
-        SWTBotUtils.delay(1000);
-        SWTBotUtils.waitForJobs();
-        final String expectedTitle = elementPath.toString();
-
-        final IEditorPart iep[] = new IEditorPart[1];
-        UIThreadRunnable.syncExec(new VoidResult() {
-            @Override
-            public void run() {
-                IEditorReference[] ieds = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences();
-                assertNotNull(ieds);
-                iep[0] = null;
-                for (IEditorReference ied : ieds) {
-                    if (ied.getTitle().equals(expectedTitle)) {
-                        iep[0] = ied.getEditor(true);
-                        break;
-                    }
-                }
-            }
-        });
-        assertNotNull(iep[0]);
-        return (TmfEventsEditor) iep[0];
+        SWTBotEditor editor = bot.editorByTitle(elementPath.toString());
+        IEditorPart editorPart = editor.getReference().getEditor(false);
+        assertTrue(editorPart instanceof TmfEventsEditor);
+        return (TmfEventsEditor) editorPart;
     }
 
-    private static String getFullNodeName(final SWTBotTreeItem treeItem, String prefix) {
-        List<String> nodes = treeItem.getNodes();
-        String nodeName = "";
-        for (String node : nodes) {
-            if (node.startsWith(prefix)) {
-                nodeName = node;
-            }
-        }
-        return nodeName;
+    /**
+     * 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]'.
+     *
+     * @param bot
+     *            a given workbench bot
+     * @param parentItem
+     *            the parent tree item
+     * @param name
+     *            the desired child element name (without suffix)
+     * @return the a {@link SWTBotTreeItem} with the specified name
+     */
+    public static SWTBotTreeItem getTraceProjectItem(SWTWorkbenchBot bot, final SWTBotTreeItem parentItem, final String name) {
+        ProjectElementHasChild condition = new ProjectElementHasChild(parentItem, name);
+        bot.waitUntil(condition);
+        return condition.getItem();
     }
 
     /**
@@ -381,23 +369,18 @@ public final class SWTBotUtils {
      * @param projectName
      *            the name of the project (it needs to exist or else it would
      *            time out)
-     * @return a {@link SWTBotTreeItem} of the "Traces" directory
+     * @return a {@link SWTBotTreeItem} of the "Traces" folder
      */
     public static SWTBotTreeItem selectTracesFolder(SWTWorkbenchBot bot, String projectName) {
         SWTBotView projectExplorerBot = bot.viewByTitle("Project Explorer");
         projectExplorerBot.show();
-        SWTBotTreeItem treeItem = projectExplorerBot.bot().tree().getTreeItem(projectName);
-        treeItem.select();
-        treeItem.expand();
-        SWTBotTreeItem treeNode = null;
-        for (String node : treeItem.getNodes()) {
-            if (node.matches("Traces\\s\\[(\\d)*\\]")) {
-                treeNode = treeItem.getNode(node);
-                break;
-            }
-        }
-        assertNotNull(treeNode);
-        return treeNode;
+        SWTBotTree tree = projectExplorerBot.bot().tree();
+        bot.waitUntil(ConditionHelpers.IsTreeNodeAvailable(projectName, tree));
+        SWTBotTreeItem projectTreeItem = tree.getTreeItem(projectName);
+        projectTreeItem.select();
+        SWTBotTreeItem tracesFolderItem = getTraceProjectItem(bot, projectTreeItem, TmfTracesFolder.TRACES_FOLDER_NAME);
+        tracesFolderItem.select();
+        return tracesFolderItem;
     }
 
     /**
This page took 0.02909 seconds and 5 git commands to generate.