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;
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;
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;
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;
@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();
}
/**
}
});
- SWTBotUtils.waitForJobs();
+ WaitUtils.waitForJobs();
}
/**
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();
bot.waitUntil(Conditions.widgetIsEnabled(okButton));
okButton.click();
- SWTBotUtils.waitForJobs();
+ WaitUtils.waitForJobs();
}
/**
});
}
-
/**
* Focus on the main window
*
* 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);
}
/**
* 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
*/
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;
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);
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);
if (delay) {
delay(1000);
- waitForJobs();
+ WaitUtils.waitForJobs();
}
}
}
});
- SWTBotUtils.waitForJobs();
+ WaitUtils.waitForJobs();
SWTBotUtils.delay(1000);
assertNotNull(tmfEd);
return editorBot;
SWTBotTreeItem currentItem = tracesNode;
for (String segment : elementPath.segments()) {
currentItem = getTraceProjectItem(projectExplorerBot, currentItem, segment);
- currentItem.select();
currentItem.doubleClick();
}
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]'.
});
}
+ /**
+ * 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
*
* @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) {
if (res[0] != null) {
fail(res[0].getMessage());
}
- waitForJobs();
+ WaitUtils.waitForJobs();
}
/**
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));