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