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