analysis.ui: add Export to TSV action test
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui.swtbot.tests / shared / org / eclipse / tracecompass / tmf / ui / swtbot / tests / shared / SWTBotUtils.java
CommitLineData
306e18d0 1/*******************************************************************************
ed902a2b 2 * Copyright (c) 2014, 2015 Ericsson
306e18d0
MK
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Matthew Khouzam - Initial API and implementation
11 *******************************************************************************/
12
fa24d78b 13package org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared;
306e18d0
MK
14
15import static org.junit.Assert.assertNotNull;
21e5206c 16import static org.junit.Assert.assertTrue;
306e18d0
MK
17import static org.junit.Assert.fail;
18
1b9a8a8c 19import java.util.Arrays;
306e18d0 20import java.util.List;
6941941d 21import java.util.TimeZone;
675b1249 22import java.util.concurrent.atomic.AtomicBoolean;
306e18d0 23
1dfcd42b 24import org.apache.log4j.Logger;
29fe7911 25import org.eclipse.core.resources.IFolder;
306e18d0 26import org.eclipse.core.resources.IProject;
93c91230 27import org.eclipse.core.resources.IResource;
29fe7911 28import org.eclipse.core.resources.IResourceVisitor;
93c91230
MAL
29import org.eclipse.core.resources.ResourcesPlugin;
30import org.eclipse.core.runtime.CoreException;
b4290931 31import org.eclipse.core.runtime.IPath;
306e18d0 32import org.eclipse.core.runtime.NullProgressMonitor;
40ba27e1 33import org.eclipse.jdt.annotation.NonNull;
328e5fe4
MK
34import org.eclipse.jface.bindings.keys.IKeyLookup;
35import org.eclipse.jface.bindings.keys.KeyStroke;
36import org.eclipse.jface.bindings.keys.ParseException;
675b1249
PT
37import org.eclipse.swt.events.ControlAdapter;
38import org.eclipse.swt.events.ControlEvent;
328e5fe4
MK
39import org.eclipse.swt.graphics.Point;
40import org.eclipse.swt.graphics.Rectangle;
306e18d0 41import org.eclipse.swt.widgets.Display;
5785ab49 42import org.eclipse.swt.widgets.Shell;
328e5fe4
MK
43import org.eclipse.swt.widgets.Table;
44import org.eclipse.swt.widgets.TableItem;
306e18d0 45import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
693ec829
BH
46import org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory;
47import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor;
306e18d0 48import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
bbdb3d6d 49import org.eclipse.swtbot.swt.finder.SWTBot;
306e18d0 50import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
1c9b6343
MAL
51import org.eclipse.swtbot.swt.finder.keyboard.Keyboard;
52import org.eclipse.swtbot.swt.finder.keyboard.Keystrokes;
328e5fe4 53import org.eclipse.swtbot.swt.finder.results.Result;
306e18d0 54import org.eclipse.swtbot.swt.finder.results.VoidResult;
1dfcd42b 55import org.eclipse.swtbot.swt.finder.utils.MessageFormat;
747d62e1 56import org.eclipse.swtbot.swt.finder.utils.SWTUtils;
93c91230 57import org.eclipse.swtbot.swt.finder.waits.Conditions;
a345ad25 58import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
93c91230
MAL
59import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
60import org.eclipse.swtbot.swt.finder.widgets.SWTBotCheckBox;
61import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
306e18d0 62import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
328e5fe4 63import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
93c91230
MAL
64import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
65import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
65416c44 66import org.eclipse.swtbot.swt.finder.widgets.TimeoutException;
40ba27e1 67import org.eclipse.tracecompass.internal.tmf.ui.project.operations.NewExperimentOperation;
2bdf0193 68import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor;
40ba27e1
BH
69import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement;
70import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder;
2bdf0193 71import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper;
29fe7911 72import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement;
2bdf0193 73import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectRegistry;
29fe7911 74import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement;
2bdf0193 75import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder;
b4290931 76import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder;
21e5206c 77import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers.ProjectElementHasChild;
f0beeb4a 78import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils;
2bdf0193 79import org.eclipse.tracecompass.tmf.ui.views.TracingPerspectiveFactory;
693ec829
BH
80import org.eclipse.ui.IEditorPart;
81import org.eclipse.ui.IEditorReference;
93c91230 82import org.eclipse.ui.IPageLayout;
2470d687 83import org.eclipse.ui.PartInitException;
306e18d0
MK
84import org.eclipse.ui.PlatformUI;
85import org.eclipse.ui.WorkbenchException;
693ec829 86import org.hamcrest.Matcher;
306e18d0
MK
87
88/**
89 * SWTBot Helper functions
90 *
91 * @author Matthew Khouzam
92 */
40ba27e1 93@SuppressWarnings("restriction")
fa24d78b
AM
94public final class SWTBotUtils {
95
747d62e1
MAL
96 private static final String WINDOW_MENU = "Window";
97 private static final String PREFERENCES_MENU_ITEM = "Preferences";
2ad409b3 98 private static boolean fPrintedEnvironment = false;
1dfcd42b 99 private static Logger log = Logger.getLogger(SWTBotUtils.class);
747d62e1 100
328e5fe4 101 private SWTBotUtils() {
1dfcd42b 102
328e5fe4 103 }
fa24d78b 104
306e18d0
MK
105 private static final String TRACING_PERSPECTIVE_ID = TracingPerspectiveFactory.ID;
106
107 /**
fd5f786c 108 * Waits for all Eclipse jobs to finish. Times out after
f0beeb4a 109 * WaitUtils#MAX_JOBS_WAIT_TIME by default.
fd5f786c 110 *
217d5c81 111 * @throws RuntimeException
fd5f786c 112 * once the waiting time passes the default maximum value
f0beeb4a
MAL
113 *
114 * @deprecated Use {@link WaitUtils#waitForJobs()} instead
306e18d0 115 */
f0beeb4a 116 @Deprecated
306e18d0 117 public static void waitForJobs() {
f0beeb4a 118 WaitUtils.waitForJobs();
fd5f786c
MAL
119 }
120
306e18d0
MK
121 /**
122 * Sleeps current thread for a given time.
123 *
124 * @param waitTimeMillis
125 * time in milliseconds to wait
126 */
127 public static void delay(final long waitTimeMillis) {
128 try {
129 Thread.sleep(waitTimeMillis);
130 } catch (final InterruptedException e) {
131 // Ignored
132 }
133 }
134
135 /**
136 * Create a tracing project
137 *
138 * @param projectName
139 * the name of the tracing project
140 */
141 public static void createProject(final String projectName) {
142 /*
143 * Make a new test
144 */
145 UIThreadRunnable.syncExec(new VoidResult() {
146 @Override
147 public void run() {
148 IProject project = TmfProjectRegistry.createProject(projectName, null, new NullProgressMonitor());
149 assertNotNull(project);
150 }
151 });
152
f0beeb4a 153 WaitUtils.waitForJobs();
306e18d0
MK
154 }
155
93c91230 156 /**
bbdb3d6d 157 * Deletes a project
93c91230
MAL
158 *
159 * @param projectName
160 * the name of the tracing project
bbdb3d6d
MAL
161 * @param deleteResources
162 * whether or not to deleted resources under the project
93c91230
MAL
163 * @param bot
164 * the workbench bot
165 */
bbdb3d6d 166 public static void deleteProject(final String projectName, boolean deleteResources, SWTWorkbenchBot bot) {
7777d5f0
MK
167 // Wait for any analysis to complete because it might create
168 // supplementary files
f0beeb4a 169 WaitUtils.waitForJobs();
93c91230
MAL
170 try {
171 ResourcesPlugin.getWorkspace().getRoot().getProject(projectName).refreshLocal(IResource.DEPTH_INFINITE, null);
172 } catch (CoreException e) {
173 }
174
f0beeb4a 175 WaitUtils.waitForJobs();
93c91230 176
1dfcd42b 177 closeSecondaryShells(bot);
f0beeb4a 178 WaitUtils.waitForJobs();
1dfcd42b 179
d2fbf6b6
PT
180 if (!ResourcesPlugin.getWorkspace().getRoot().getProject(projectName).exists()) {
181 return;
182 }
183
93c91230
MAL
184 final SWTBotView projectViewBot = bot.viewById(IPageLayout.ID_PROJECT_EXPLORER);
185 projectViewBot.setFocus();
186
693ec829 187 SWTBotTree treeBot = projectViewBot.bot().tree();
93c91230
MAL
188 SWTBotTreeItem treeItem = treeBot.getTreeItem(projectName);
189 SWTBotMenu contextMenu = treeItem.contextMenu("Delete");
190 contextMenu.click();
191
bbdb3d6d
MAL
192 if (deleteResources) {
193 bot.shell("Delete Resources").setFocus();
194 final SWTBotCheckBox checkBox = bot.checkBox();
195 bot.waitUntil(Conditions.widgetIsEnabled(checkBox));
196 checkBox.click();
197 }
93c91230
MAL
198
199 final SWTBotButton okButton = bot.button("OK");
200 bot.waitUntil(Conditions.widgetIsEnabled(okButton));
201 okButton.click();
202
f0beeb4a 203 WaitUtils.waitForJobs();
93c91230
MAL
204 }
205
bbdb3d6d
MAL
206 /**
207 * Deletes a project and its resources
208 *
209 * @param projectName
210 * the name of the tracing project
211 * @param bot
212 * the workbench bot
213 */
214 public static void deleteProject(String projectName, SWTWorkbenchBot bot) {
215 deleteProject(projectName, true, bot);
216 }
217
40ba27e1
BH
218 /**
219 * Creates an experiment
220 *
221 * @param bot
222 * a given workbench bot
223 * @param projectName
224 * the name of the project, creates the project if needed
225 * @param expName
226 * the experiment name
227 */
228 public static void createExperiment(SWTWorkbenchBot bot, String projectName, final @NonNull String expName) {
229 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
230 TmfProjectElement tmfProject = TmfProjectRegistry.getProject(project, true);
231 TmfExperimentFolder expFolder = tmfProject.getExperimentsFolder();
232 assertNotNull(expFolder);
233 NewExperimentOperation operation = new NewExperimentOperation(expFolder, expName);
234 operation.run(new NullProgressMonitor());
235
236 bot.waitUntil(new DefaultCondition() {
237 @Override
238 public boolean test() throws Exception {
239 TmfExperimentElement experiment = expFolder.getExperiment(expName);
240 return experiment != null;
241 }
242
243 @Override
244 public String getFailureMessage() {
245 return "Experiment (" + expName + ") couldn't be created";
246 }
247 });
248 }
249
306e18d0
MK
250 /**
251 * Focus on the main window
252 *
253 * @param shellBots
254 * swtbotshells for all the shells
255 */
256 public static void focusMainWindow(SWTBotShell[] shellBots) {
1dfcd42b
MAL
257 SWTBotShell mainShell = getMainShell(shellBots);
258 if (mainShell != null) {
259 mainShell.activate();
260 }
261 }
262
263 private static SWTBotShell getMainShell(SWTBotShell[] shellBots) {
264 SWTBotShell mainShell = null;
306e18d0
MK
265 for (SWTBotShell shellBot : shellBots) {
266 if (shellBot.getText().toLowerCase().contains("eclipse")) {
1dfcd42b 267 mainShell = shellBot;
306e18d0
MK
268 }
269 }
1dfcd42b
MAL
270 return mainShell;
271 }
272
273 /**
274 * Close all non-main shells that are visible.
275 *
276 * @param bot
277 * the workbench bot
278 */
279 public static void closeSecondaryShells(SWTWorkbenchBot bot) {
280 SWTBotShell[] shells = bot.shells();
281 SWTBotShell mainShell = getMainShell(shells);
282 if (mainShell == null) {
283 return;
284 }
285
286 // Close all non-main shell but make sure we don't close an invisible
287 // shell such the special "limbo shell" that Eclipse needs to work
288 Arrays.stream(shells)
289 .filter(shell -> shell != mainShell)
d7ac6294 290 .filter(s -> !s.widget.isDisposed())
1dfcd42b 291 .filter(SWTBotShell::isVisible)
a463a9ba 292 .peek(shell -> log.debug(MessageFormat.format("Closing lingering shell with title {0}", shell.getText())))
1dfcd42b 293 .forEach(SWTBotShell::close);
306e18d0
MK
294 }
295
296 /**
297 * Close a view with a title
298 *
299 * @param title
300 * the title, like "welcome"
301 * @param bot
302 * the workbench bot
303 */
304 public static void closeView(String title, SWTWorkbenchBot bot) {
305 final List<SWTBotView> openViews = bot.views();
306 for (SWTBotView view : openViews) {
307 if (view.getTitle().equalsIgnoreCase(title)) {
308 view.close();
309 bot.waitUntil(ConditionHelpers.ViewIsClosed(view));
310 }
311 }
312 }
313
e4d15418
MAL
314 /**
315 * Close a view with an id
316 *
317 * @param viewId
b6fddb83
MK
318 * the view id, like
319 * "org.eclipse.linuxtools.tmf.ui.views.histogram"
e4d15418
MAL
320 * @param bot
321 * the workbench bot
322 */
323 public static void closeViewById(String viewId, SWTWorkbenchBot bot) {
324 final SWTBotView view = bot.viewById(viewId);
325 view.close();
326 bot.waitUntil(ConditionHelpers.ViewIsClosed(view));
327 }
328
306e18d0
MK
329 /**
330 * Switch to the tracing perspective
331 */
332 public static void switchToTracingPerspective() {
664fa59c
MK
333 switchToPerspective(TRACING_PERSPECTIVE_ID);
334 }
335
336 /**
337 * Switch to a given perspective
338 *
339 * @param id
340 * the perspective id (like
341 * "org.eclipse.linuxtools.tmf.ui.perspective"
342 */
343 public static void switchToPerspective(final String id) {
306e18d0
MK
344 UIThreadRunnable.syncExec(new VoidResult() {
345 @Override
346 public void run() {
347 try {
664fa59c 348 PlatformUI.getWorkbench().showPerspective(id, PlatformUI.getWorkbench().getActiveWorkbenchWindow());
306e18d0
MK
349 } catch (WorkbenchException e) {
350 fail(e.getMessage());
351 }
352 }
353 });
354 }
355
5785ab49
MAL
356 /**
357 * Initialize the environment for SWTBot
358 */
359 public static void initialize() {
360 failIfUIThread();
361
362 SWTWorkbenchBot bot = new SWTWorkbenchBot();
363 UIThreadRunnable.syncExec(() -> {
2ad409b3 364 printEnvironment();
5475ad49
MAL
365
366 // There seems to be problems on some system where the main shell is
b6fddb83
MK
367 // not in focus initially. This was seen using Xvfb and Xephyr on
368 // some occasions.
5475ad49
MAL
369 focusMainWindow(bot.shells());
370
5785ab49
MAL
371 Shell shell = bot.activeShell().widget;
372
373 // Only adjust shell if it appears to be the top-most
374 if (shell.getParent() == null) {
375 makeShellFullyVisible(shell);
376 }
377 });
378 }
379
2ad409b3
MAL
380 private static void printEnvironment() {
381 if (fPrintedEnvironment) {
382 return;
383 }
384
b6fddb83
MK
385 // Print some information about the environment that could affect test
386 // outcome
2ad409b3
MAL
387 Rectangle bounds = Display.getDefault().getBounds();
388 System.out.println("Display size: " + bounds.width + "x" + bounds.height);
389
390 String osVersion = System.getProperty("os.version");
391 if (osVersion != null) {
392 System.out.println("OS version=" + osVersion);
393 }
394 String gtkVersion = System.getProperty("org.eclipse.swt.internal.gtk.version");
395 if (gtkVersion != null) {
396 System.out.println("GTK version=" + gtkVersion);
b6fddb83
MK
397 // Try to print the GTK theme information as behavior can change
398 // depending on the theme
7df209fa
MAL
399 String gtkTheme = System.getProperty("org.eclipse.swt.internal.gtk.theme");
400 System.out.println("GTK theme=" + (gtkTheme == null ? "unknown" : gtkTheme));
401
2ad409b3
MAL
402 String overlayScrollbar = System.getenv("LIBOVERLAY_SCROLLBAR");
403 if (overlayScrollbar != null) {
404 System.out.println("LIBOVERLAY_SCROLLBAR=" + overlayScrollbar);
405 }
406 String ubuntuMenuProxy = System.getenv("UBUNTU_MENUPROXY");
407 if (ubuntuMenuProxy != null) {
408 System.out.println("UBUNTU_MENUPROXY=" + ubuntuMenuProxy);
409 }
410 }
411
6941941d
MAL
412 System.out.println("Time zone: " + TimeZone.getDefault().getDisplayName());
413
2ad409b3
MAL
414 fPrintedEnvironment = true;
415 }
416
306e18d0
MK
417 /**
418 * If the test is running in the UI thread then fail
419 */
5785ab49 420 private static void failIfUIThread() {
306e18d0
MK
421 if (Display.getCurrent() != null && Display.getCurrent().getThread() == Thread.currentThread()) {
422 fail("SWTBot test needs to run in a non-UI thread. Make sure that \"Run in UI thread\" is unchecked in your launch configuration or"
423 + " that useUIThread is set to false in the pom.xml");
424 }
5785ab49 425 }
306e18d0 426
5785ab49
MAL
427 /**
428 * Try to make the shell fully visible in the display. If the shell cannot
429 * fit the display, it will be positioned so that top-left corner is at
430 * <code>(0, 0)</code> in display-relative coordinates.
431 *
432 * @param shell
433 * the shell to make fully visible
434 */
435 private static void makeShellFullyVisible(Shell shell) {
436 Rectangle displayBounds = shell.getDisplay().getBounds();
437 Point absCoord = shell.toDisplay(0, 0);
438 Point shellSize = shell.getSize();
439
440 Point newLocation = new Point(absCoord.x, absCoord.y);
441 newLocation.x = Math.max(0, Math.min(absCoord.x, displayBounds.width - shellSize.x));
442 newLocation.y = Math.max(0, Math.min(absCoord.y, displayBounds.height - shellSize.y));
443 if (!newLocation.equals(absCoord)) {
444 shell.setLocation(newLocation);
445 }
306e18d0 446 }
7777d5f0
MK
447
448 /**
449 * Open a trace, this does not perform any validation though
450 *
451 * @param projectName
452 * The project name
453 * @param tracePath
454 * the path of the trace file (absolute or relative)
455 * @param traceType
328e5fe4 456 * the trace type id (eg: org.eclipse.linuxtools.btf.trace)
7777d5f0
MK
457 */
458 public static void openTrace(final String projectName, final String tracePath, final String traceType) {
a3d7df19
BH
459 openTrace(projectName, tracePath, traceType, true);
460 }
461
462 /**
463 * Open a trace, this does not perform any validation though
464 *
465 * @param projectName
466 * The project name
467 * @param tracePath
468 * the path of the trace file (absolute or relative)
469 * @param traceType
328e5fe4 470 * the trace type id (eg: org.eclipse.linuxtools.btf.trace)
a3d7df19
BH
471 * @param delay
472 * delay and wait for jobs
473 */
474 public static void openTrace(final String projectName, final String tracePath, final String traceType, boolean delay) {
7777d5f0
MK
475 final Exception exception[] = new Exception[1];
476 exception[0] = null;
477 UIThreadRunnable.syncExec(new VoidResult() {
478 @Override
479 public void run() {
480 try {
481 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
482 TmfTraceFolder destinationFolder = TmfProjectRegistry.getProject(project, true).getTracesFolder();
483 TmfOpenTraceHelper.openTraceFromPath(destinationFolder, tracePath, PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), traceType);
484 } catch (CoreException e) {
485 exception[0] = e;
486 }
487 }
488 });
489 if (exception[0] != null) {
490 fail(exception[0].getMessage());
491 }
492
a3d7df19
BH
493 if (delay) {
494 delay(1000);
f0beeb4a 495 WaitUtils.waitForJobs();
a3d7df19 496 }
7777d5f0 497 }
693ec829
BH
498
499 /**
b4290931 500 * Finds an editor and sets focus to the editor
693ec829
BH
501 *
502 * @param bot
503 * the workbench bot
504 * @param editorName
505 * the editor name
506 * @return the corresponding SWTBotEditor
507 */
b4290931 508 public static SWTBotEditor activateEditor(SWTWorkbenchBot bot, String editorName) {
693ec829
BH
509 Matcher<IEditorReference> matcher = WidgetMatcherFactory.withPartName(editorName);
510 final SWTBotEditor editorBot = bot.editor(matcher);
511 IEditorPart iep = editorBot.getReference().getEditor(true);
512 final TmfEventsEditor tmfEd = (TmfEventsEditor) iep;
513 editorBot.show();
514 UIThreadRunnable.syncExec(new VoidResult() {
515 @Override
516 public void run() {
517 tmfEd.setFocus();
518 }
519 });
520
f0beeb4a 521 WaitUtils.waitForJobs();
fa24d78b 522 SWTBotUtils.delay(1000);
693ec829
BH
523 assertNotNull(tmfEd);
524 return editorBot;
525 }
b4290931
MAL
526
527 /**
528 * Opens a trace in an editor and get the TmfEventsEditor
529 *
530 * @param bot
531 * the workbench bot
532 * @param projectName
533 * the name of the project that contains the trace
534 * @param elementPath
535 * the trace element path (relative to Traces folder)
536 * @return TmfEventsEditor the opened editor
537 */
538 public static TmfEventsEditor openEditor(SWTWorkbenchBot bot, String projectName, IPath elementPath) {
5b6c8456
MAL
539 final SWTBotView projectExplorerView = bot.viewById(IPageLayout.ID_PROJECT_EXPLORER);
540 projectExplorerView.setFocus();
541 SWTBot projectExplorerBot = projectExplorerView.bot();
b4290931 542
5b6c8456
MAL
543 final SWTBotTree tree = projectExplorerBot.tree();
544 projectExplorerBot.waitUntil(ConditionHelpers.IsTreeNodeAvailable(projectName, tree));
b4290931
MAL
545 final SWTBotTreeItem treeItem = tree.getTreeItem(projectName);
546 treeItem.expand();
547
5b6c8456 548 SWTBotTreeItem tracesNode = getTraceProjectItem(projectExplorerBot, treeItem, TmfTracesFolder.TRACES_FOLDER_NAME);
b4290931
MAL
549 tracesNode.expand();
550
21e5206c 551 SWTBotTreeItem currentItem = tracesNode;
b4290931 552 for (String segment : elementPath.segments()) {
5b6c8456 553 currentItem = getTraceProjectItem(projectExplorerBot, currentItem, segment);
21e5206c 554 currentItem.doubleClick();
b4290931
MAL
555 }
556
21e5206c
PT
557 SWTBotEditor editor = bot.editorByTitle(elementPath.toString());
558 IEditorPart editorPart = editor.getReference().getEditor(false);
559 assertTrue(editorPart instanceof TmfEventsEditor);
560 return (TmfEventsEditor) editorPart;
b4290931
MAL
561 }
562
cdfe10e7
PT
563 /**
564 * Returns the child tree item of the specified item at the given sub-path.
565 * The project element labels may have a count suffix in the format ' [n]'.
566 *
567 * @param bot
568 * a given workbench bot
569 * @param parentItem
570 * the parent tree item
571 * @param path
572 * the desired child element sub-path (without suffix)
573 * @return the a {@link SWTBotTreeItem} with the specified name
574 */
575 public static SWTBotTreeItem getTraceProjectItem(SWTBot bot, final SWTBotTreeItem parentItem, final String... path) {
576 SWTBotTreeItem item = parentItem;
577 for (String name : path) {
578 item = getTraceProjectItem(bot, item, name);
579 }
580 return item;
581 }
582
21e5206c
PT
583 /**
584 * Returns the child tree item of the specified item with the given name.
585 * The project element label may have a count suffix in the format ' [n]'.
586 *
587 * @param bot
588 * a given workbench bot
589 * @param parentItem
590 * the parent tree item
591 * @param name
592 * the desired child element name (without suffix)
593 * @return the a {@link SWTBotTreeItem} with the specified name
594 */
5b6c8456 595 public static SWTBotTreeItem getTraceProjectItem(SWTBot bot, final SWTBotTreeItem parentItem, final String name) {
21e5206c
PT
596 ProjectElementHasChild condition = new ProjectElementHasChild(parentItem, name);
597 bot.waitUntil(condition);
598 return condition.getItem();
b4290931 599 }
34c0fc10
MK
600
601 /**
602 * Select the traces folder
603 *
604 * @param bot
605 * a given workbench bot
606 * @param projectName
328e5fe4
MK
607 * the name of the project (it needs to exist or else it would
608 * time out)
21e5206c 609 * @return a {@link SWTBotTreeItem} of the "Traces" folder
34c0fc10
MK
610 */
611 public static SWTBotTreeItem selectTracesFolder(SWTWorkbenchBot bot, String projectName) {
bbdb3d6d 612 SWTBotTreeItem projectTreeItem = selectProject(bot, projectName);
21e5206c
PT
613 projectTreeItem.select();
614 SWTBotTreeItem tracesFolderItem = getTraceProjectItem(bot, projectTreeItem, TmfTracesFolder.TRACES_FOLDER_NAME);
615 tracesFolderItem.select();
616 return tracesFolderItem;
34c0fc10 617 }
2470d687 618
29fe7911
MAL
619 /**
620 * Clear the traces folder
621 *
622 * @param bot
623 * a given workbench bot
624 * @param projectName
625 * the name of the project (needs to exist)
626 */
627 public static void clearTracesFolder(SWTWorkbenchBot bot, String projectName) {
628 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
629 TmfProjectElement tmfProject = TmfProjectRegistry.getProject(project, false);
630 TmfTraceFolder tracesFolder = tmfProject.getTracesFolder();
631 try {
632 for (TmfTraceElement traceElement : tracesFolder.getTraces()) {
633 traceElement.delete(null);
634 }
635
636 final IFolder resource = tracesFolder.getResource();
637 resource.accept(new IResourceVisitor() {
638 @Override
639 public boolean visit(IResource visitedResource) throws CoreException {
640 if (visitedResource != resource) {
641 visitedResource.delete(true, null);
642 }
643 return true;
644 }
645 }, IResource.DEPTH_ONE, 0);
646 } catch (CoreException e) {
647 fail(e.getMessage());
648 }
649
650 bot.waitUntil(new DefaultCondition() {
651 private int fTraceNb = 0;
652
653 @Override
654 public boolean test() throws Exception {
655 List<TmfTraceElement> traces = tracesFolder.getTraces();
656 fTraceNb = traces.size();
657 return fTraceNb == 0;
658 }
659
660 @Override
661 public String getFailureMessage() {
662 return "Traces Folder not empty (" + fTraceNb + ")";
663 }
664 });
40ba27e1
BH
665 }
666
450daec8
MAL
667 /**
668 * Clear the trace folder (using the UI)
669 *
670 * @param bot
671 * a given workbench bot
672 * @param projectName
673 * the name of the project (needs to exist)
674 */
675 public static void clearTracesFolderUI(SWTWorkbenchBot bot, String projectName) {
676 SWTBotTreeItem tracesFolder = selectTracesFolder(bot, projectName);
677 tracesFolder.contextMenu().menu("Clear").click();
678 String CONFIRM_CLEAR_DIALOG_TITLE = "Confirm Clear";
679 bot.waitUntil(Conditions.shellIsActive(CONFIRM_CLEAR_DIALOG_TITLE));
680
681 SWTBotShell shell = bot.shell(CONFIRM_CLEAR_DIALOG_TITLE);
682 shell.bot().button("Yes").click();
683 bot.waitUntil(Conditions.shellCloses(shell));
684 bot.waitWhile(ConditionHelpers.treeItemHasChildren(tracesFolder));
685 }
686
40ba27e1
BH
687 /**
688 * Clear the experiment folder
689 *
690 * @param bot
691 * a given workbench bot
692 * @param projectName
693 * the name of the project (needs to exist)
694 */
695 public static void clearExperimentFolder(SWTWorkbenchBot bot, String projectName) {
696 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
697 TmfProjectElement tmfProject = TmfProjectRegistry.getProject(project, false);
698 TmfExperimentFolder expFolder = tmfProject.getExperimentsFolder();
699 expFolder.getExperiments().forEach(experiment -> {
700 IResource resource = experiment.getResource();
701 try {
702 // Close the experiment if open
703 experiment.closeEditors();
704
705 IPath path = resource.getLocation();
706 if (path != null) {
707 // Delete supplementary files
708 experiment.deleteSupplementaryFolder();
709 }
710 // Finally, delete the experiment
711 resource.delete(true, null);
712 } catch (CoreException e) {
713 fail(e.getMessage());
714 }
715 });
716
717 bot.waitUntil(new DefaultCondition() {
718 private int fExperimentNb = 0;
29fe7911 719
40ba27e1
BH
720 @Override
721 public boolean test() throws Exception {
722 List<TmfExperimentElement> experiments = expFolder.getExperiments();
723 fExperimentNb = experiments.size();
724 return fExperimentNb == 0;
725 }
726
727 @Override
728 public String getFailureMessage() {
729 return "Experiment Folder not empty (" + fExperimentNb + ")";
730 }
731 });
29fe7911
MAL
732 }
733
bbdb3d6d
MAL
734 /**
735 * Select the project in Project Explorer
736 *
737 * @param bot
738 * a given workbench bot
739 * @param projectName
b6fddb83
MK
740 * the name of the project (it needs to exist or else it would
741 * time out)
bbdb3d6d
MAL
742 * @return a {@link SWTBotTreeItem} of the project
743 */
744 public static SWTBotTreeItem selectProject(SWTWorkbenchBot bot, String projectName) {
745 SWTBotView projectExplorerBot = bot.viewByTitle("Project Explorer");
746 projectExplorerBot.show();
e834a6b4
MAL
747 // FIXME: Bug 496519. Sometimes, the tree becomes disabled for a certain
748 // amount of time. This can happen during a long running operation
749 // (BusyIndicator.showWhile) which brings up the modal dialog "operation
750 // in progress" and this disables all shells
751 projectExplorerBot.bot().waitUntil(Conditions.widgetIsEnabled(projectExplorerBot.bot().tree()));
bbdb3d6d
MAL
752 SWTBotTreeItem treeItem = projectExplorerBot.bot().tree().getTreeItem(projectName);
753 treeItem.select();
754 return treeItem;
755 }
756
2470d687
MK
757 /**
758 * Open a view by id.
759 *
760 * @param id
761 * view id.
762 */
763 public static void openView(final String id) {
764 final PartInitException res[] = new PartInitException[1];
765 UIThreadRunnable.syncExec(new VoidResult() {
766 @Override
767 public void run() {
768 try {
769 PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(id);
770 } catch (PartInitException e) {
771 res[0] = e;
772 }
773 }
774 });
775 if (res[0] != null) {
776 fail(res[0].getMessage());
777 }
f0beeb4a 778 WaitUtils.waitForJobs();
2470d687 779 }
328e5fe4
MK
780
781 /**
782 * Maximize a table
783 *
784 * @param tableBot
785 * the {@link SWTBotTable} table
786 */
787 public static void maximizeTable(SWTBotTable tableBot) {
675b1249
PT
788 final AtomicBoolean controlResized = new AtomicBoolean();
789 UIThreadRunnable.syncExec(new VoidResult() {
790 @Override
791 public void run() {
792 tableBot.widget.addControlListener(new ControlAdapter() {
793 @Override
794 public void controlResized(ControlEvent e) {
795 tableBot.widget.removeControlListener(this);
796 controlResized.set(true);
797 }
798 });
799 }
800 });
328e5fe4
MK
801 try {
802 tableBot.pressShortcut(KeyStroke.getInstance(IKeyLookup.CTRL_NAME + "+"), KeyStroke.getInstance("M"));
803 } catch (ParseException e) {
804 fail();
805 }
675b1249
PT
806 new SWTBot().waitUntil(new DefaultCondition() {
807 @Override
808 public boolean test() throws Exception {
809 return controlResized.get();
810 }
811
812 @Override
813 public String getFailureMessage() {
814 return "Control was not resized";
815 }
816 });
328e5fe4
MK
817 }
818
819 /**
820 * Get the bounds of a cell (SWT.Rectangle) for the specified row and column
821 * index in a table
822 *
823 * @param table
824 * the table
825 * @param row
826 * the row of the table to look up
827 * @param col
828 * the column of the table to look up
829 * @return the bounds in display relative coordinates
830 */
831 public static Rectangle getCellBounds(final Table table, final int row, final int col) {
832 return UIThreadRunnable.syncExec(new Result<Rectangle>() {
833 @Override
834 public Rectangle run() {
835 TableItem item = table.getItem(row);
836 Rectangle bounds = item.getBounds(col);
837 Point p = table.toDisplay(bounds.x, bounds.y);
838 Rectangle rect = new Rectangle(p.x, p.y, bounds.width, bounds.height);
839 return rect;
840 }
841 });
842 }
bbdb3d6d
MAL
843
844 /**
845 * Get the tree item from a tree at the specified location
846 *
847 * @param bot
848 * the SWTBot
849 * @param tree
850 * the tree to find the tree item in
851 * @param nodeNames
852 * the path to the tree item, in the form of node names (from
853 * parent to child).
854 * @return the tree item
855 */
856 public static SWTBotTreeItem getTreeItem(SWTBot bot, SWTBotTree tree, String... nodeNames) {
857 if (nodeNames.length == 0) {
858 return null;
859 }
860
861 bot.waitUntil(ConditionHelpers.IsTreeNodeAvailable(nodeNames[0], tree));
862 SWTBotTreeItem currentNode = tree.getTreeItem(nodeNames[0]);
1b9a8a8c
MAL
863 return getTreeItem(bot, currentNode, Arrays.copyOfRange(nodeNames, 1, nodeNames.length));
864 }
865
866 /**
867 * Get the tree item from a parent tree item at the specified location
868 *
869 * @param bot
870 * the SWTBot
871 * @param treeItem
872 * the treeItem to find the tree item under
873 * @param nodeNames
874 * the path to the tree item, in the form of node names (from
875 * parent to child).
876 * @return the tree item
877 */
878 public static SWTBotTreeItem getTreeItem(SWTBot bot, SWTBotTreeItem treeItem, String... nodeNames) {
879 if (nodeNames.length == 0) {
880 return treeItem;
881 }
882
883 SWTBotTreeItem currentNode = treeItem;
884 for (int i = 0; i < nodeNames.length; i++) {
885 bot.waitUntil(ConditionHelpers.treeItemHasChildren(treeItem));
bbdb3d6d
MAL
886 currentNode.expand();
887
888 String nodeName = nodeNames[i];
65416c44
MAL
889 try {
890 bot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(nodeName, currentNode));
891 } catch (TimeoutException e) {
b6fddb83
MK
892 // FIXME: Sometimes in a JFace TreeViewer, it expands to
893 // nothing. Need to find out why.
65416c44
MAL
894 currentNode.collapse();
895 currentNode.expand();
896 bot.waitUntil(ConditionHelpers.IsTreeChildNodeAvailable(nodeName, currentNode));
897 }
898
bbdb3d6d
MAL
899 SWTBotTreeItem newNode = currentNode.getNode(nodeName);
900 currentNode = newNode;
901 }
902
903 return currentNode;
904 }
a345ad25 905
1c9b6343
MAL
906 /**
907 * Press the keyboard shortcut that goes to the top of a tree widget. The
908 * key combination can differ on different platforms.
909 *
910 * @param keyboard
911 * the keyboard to use
912 */
913 public static void pressShortcutGoToTreeTop(Keyboard keyboard) {
914 if (SWTUtils.isMac()) {
915 keyboard.pressShortcut(Keystrokes.ALT, Keystrokes.UP);
916 } else {
917 keyboard.pressShortcut(Keystrokes.HOME);
918 }
919 }
920
a345ad25
MAL
921 /**
922 * Get the active events editor. Note that this will wait until such editor
923 * is available.
924 *
925 * @param workbenchBot
926 * a given workbench bot
927 * @return the active events editor
928 */
929 public static SWTBotEditor activeEventsEditor(final SWTWorkbenchBot workbenchBot) {
e834a6b4
MAL
930 ConditionHelpers.ActiveEventsEditor condition = new ConditionHelpers.ActiveEventsEditor(workbenchBot, null);
931 workbenchBot.waitUntil(condition);
932 return condition.getActiveEditor();
933 }
a345ad25 934
e834a6b4
MAL
935 /**
936 * Get the active events editor. Note that this will wait until such editor
937 * is available.
938 *
939 * @param workbenchBot
940 * a given workbench bot
941 * @param editorTitle
942 * the desired editor title. If null, any active events editor
943 * will be considered valid.
944 * @return the active events editor
945 */
946 public static SWTBotEditor activeEventsEditor(final SWTWorkbenchBot workbenchBot, String editorTitle) {
947 ConditionHelpers.ActiveEventsEditor condition = new ConditionHelpers.ActiveEventsEditor(workbenchBot, editorTitle);
948 workbenchBot.waitUntil(condition);
949 return condition.getActiveEditor();
a345ad25 950 }
747d62e1
MAL
951
952 /**
953 * Open the preferences dialog and return the corresponding shell.
954 *
955 * @param bot
956 * a given workbench bot
957 * @return the preferences shell
958 */
959 public static SWTBotShell openPreferences(SWTBot bot) {
960 if (SWTUtils.isMac()) {
961 // On Mac, the Preferences menu item is under the application name.
962 // For some reason, we can't access the application menu anymore so
963 // we use the keyboard shortcut.
964 try {
965 bot.activeShell().pressShortcut(KeyStroke.getInstance(IKeyLookup.COMMAND_NAME + "+"), KeyStroke.getInstance(","));
966 } catch (ParseException e) {
967 fail();
968 }
969 } else {
970 bot.menu(WINDOW_MENU).menu(PREFERENCES_MENU_ITEM).click();
971 }
972
973 bot.waitUntil(Conditions.shellIsActive(PREFERENCES_MENU_ITEM));
974 return bot.activeShell();
975 }
306e18d0 976}
This page took 0.127014 seconds and 5 git commands to generate.