1 /*******************************************************************************
2 * Copyright (c) 2013, 2015 Ericsson
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
10 * Matthew Khouzam - Initial API and implementation
11 * Alexandre Montplaisir - Replaced separate Condition objects by anonymous classes
12 * Patrick Tasse - Add projectElementHasChild and isEditorOpened conditions
13 *******************************************************************************/
15 package org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
;
17 import static org
.eclipse
.swtbot
.eclipse
.finder
.matchers
.WidgetMatcherFactory
.withPartName
;
19 import java
.util
.Arrays
;
21 import org
.eclipse
.jdt
.annotation
.NonNull
;
22 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
23 import org
.eclipse
.jface
.wizard
.IWizardContainer
;
24 import org
.eclipse
.jface
.wizard
.IWizardPage
;
25 import org
.eclipse
.jface
.wizard
.Wizard
;
26 import org
.eclipse
.osgi
.util
.NLS
;
27 import org
.eclipse
.swtbot
.eclipse
.finder
.SWTWorkbenchBot
;
28 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotEditor
;
29 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotView
;
30 import org
.eclipse
.swtbot
.swt
.finder
.SWTBot
;
31 import org
.eclipse
.swtbot
.swt
.finder
.finders
.UIThreadRunnable
;
32 import org
.eclipse
.swtbot
.swt
.finder
.results
.Result
;
33 import org
.eclipse
.swtbot
.swt
.finder
.utils
.TableCollection
;
34 import org
.eclipse
.swtbot
.swt
.finder
.waits
.DefaultCondition
;
35 import org
.eclipse
.swtbot
.swt
.finder
.waits
.ICondition
;
36 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTable
;
37 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTree
;
38 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeItem
;
39 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
40 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimestamp
;
41 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
42 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
43 import org
.eclipse
.tracecompass
.tmf
.ui
.editors
.TmfEventsEditor
;
44 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.timegraph
.AbstractTimeGraphView
;
45 import org
.eclipse
.ui
.IEditorReference
;
46 import org
.hamcrest
.Matcher
;
49 * Is a tree node available
51 * @author Matthew Khouzam
53 public final class ConditionHelpers
{
55 private ConditionHelpers() {}
58 * Provide default implementations for some {@link ICondition} methods.
60 private abstract static class SWTBotTestCondition
implements ICondition
{
63 public abstract boolean test() throws Exception
;
66 public final void init(SWTBot bot
) {
70 public String
getFailureMessage() {
76 * Is a tree node available
79 * the name of the node
82 * @return true or false, it should swallow all exceptions
84 public static ICondition
IsTreeNodeAvailable(final String name
, final SWTBotTree tree
) {
85 return new SWTBotTestCondition() {
87 public boolean test() throws Exception
{
89 final SWTBotTreeItem
[] treeItems
= tree
.getAllItems();
90 for (SWTBotTreeItem ti
: treeItems
) {
91 final String text
= ti
.getText();
92 if (text
.equals(name
)) {
96 } catch (Exception e
) {
102 public String
getFailureMessage() {
103 return NLS
.bind("No child of tree {0} found with text '{1}'. Child items: {2}",
104 new String
[] { tree
.toString(), name
, Arrays
.toString(tree
.getAllItems()) });
110 * Is a table item available
113 * the name of the item
116 * @return true or false, it should swallow all exceptions
118 public static ICondition
isTableItemAvailable(final String name
, final SWTBotTable table
) {
119 return new SWTBotTestCondition() {
121 public boolean test() throws Exception
{
123 return table
.containsItem(name
);
124 } catch (Exception e
) {
130 public String
getFailureMessage() {
131 return NLS
.bind("No child of table {0} found with text '{1}'.", table
, name
);
137 * Is the treeItem's node available
140 * the name of the node
143 * @return true or false, it should swallow all exceptions
145 public static ICondition
IsTreeChildNodeAvailable(final String name
, final SWTBotTreeItem treeItem
) {
146 return new SWTBotTestCondition() {
148 public boolean test() throws Exception
{
150 return treeItem
.getNode(name
) != null;
151 } catch (Exception e
) {
157 public String
getFailureMessage() {
158 return NLS
.bind("No child of tree item {0} found with text '{1}'. Child items: {2}",
159 new String
[] { treeItem
.toString(), name
, Arrays
.toString(treeItem
.getItems()) });
165 * Checks if the wizard's shell is null
169 * @return false if either are null
171 public static ICondition
isWizardReady(final Wizard wizard
) {
172 return new SWTBotTestCondition() {
174 public boolean test() throws Exception
{
175 if (wizard
.getShell() == null) {
184 * Is the wizard on the page you want?
190 * @return true or false
192 public static ICondition
isWizardOnPage(final Wizard wizard
, final IWizardPage page
) {
193 return new SWTBotTestCondition() {
195 public boolean test() throws Exception
{
196 if (wizard
== null || page
== null) {
199 final IWizardContainer container
= wizard
.getContainer();
200 if (container
== null) {
203 IWizardPage currentPage
= container
.getCurrentPage();
204 return page
.equals(currentPage
);
210 * Wait for a view to close
213 * bot view for the view
214 * @return true if the view is closed, false if it's active.
216 public static ICondition
ViewIsClosed(final SWTBotView view
) {
217 return new SWTBotTestCondition() {
219 public boolean test() throws Exception
{
220 return (view
!= null) && (!view
.isActive());
226 * Wait till table cell has a given content.
229 * the table bot reference
231 * the content to check
233 * the row of the cell
235 * the column of the cell
236 * @return ICondition for verification
238 public static ICondition
isTableCellFilled(final SWTBotTable table
,
239 final String content
, final int row
, final int column
) {
240 return new SWTBotTestCondition() {
242 public boolean test() throws Exception
{
244 String cell
= table
.cell(row
, column
);
248 return cell
.endsWith(content
);
249 } catch (Exception e
) {
257 * Condition to check if a tracing project element has a child with the
258 * specified name. A project element label may have a count suffix in the
261 public static class ProjectElementHasChild
extends DefaultCondition
{
263 private final SWTBotTreeItem fParentItem
;
264 private final String fName
;
265 private final String fRegex
;
266 private SWTBotTreeItem fItem
= null;
274 * the child name to look for
276 public ProjectElementHasChild(final SWTBotTreeItem parentItem
, final String name
) {
277 fParentItem
= parentItem
;
279 /* Project element labels may have count suffix */
280 fRegex
= name
+ "(\\s\\[(\\d)+\\])?";
284 public boolean test() throws Exception
{
285 fParentItem
.expand();
286 for (SWTBotTreeItem item
: fParentItem
.getItems()) {
287 if (item
.getText().matches(fRegex
)) {
296 public String
getFailureMessage() {
297 return NLS
.bind("No child of {0} found with name {1}", fParentItem
.getText(), fName
);
301 * Returns the matching child item if the condition returned true.
303 * @return the matching item
305 public SWTBotTreeItem
getItem() {
311 * Condition to check if an editor with the specified title is opened.
317 * @return ICondition for verification
319 public static ICondition
isEditorOpened(final SWTWorkbenchBot bot
, final String title
) {
320 return new SWTBotTestCondition() {
322 public boolean test() throws Exception
{
323 Matcher
<IEditorReference
> withPartName
= withPartName(title
);
324 return !bot
.editors(withPartName
).isEmpty();
330 * Condition to check if the selection range equals the specified range.
333 * the selection range
334 * @return ICondition for verification
336 public static ICondition
selectionRange(final TmfTimeRange range
) {
337 return new SWTBotTestCondition() {
339 public boolean test() throws Exception
{
340 return TmfTraceManager
.getInstance().getCurrentTraceContext().getSelectionRange().equals(range
);
344 public String
getFailureMessage() {
345 return NLS
.bind("Selection range: {0} expected: {1}",
346 TmfTraceManager
.getInstance().getCurrentTraceContext().getSelectionRange(), range
);
352 * Condition to check if the window range equals the specified range.
356 * @return ICondition for verification
358 public static ICondition
windowRange(final TmfTimeRange range
) {
359 return new SWTBotTestCondition() {
361 public boolean test() throws Exception
{
362 return TmfTraceManager
.getInstance().getCurrentTraceContext().getWindowRange().equals(range
);
366 public String
getFailureMessage() {
367 return NLS
.bind("Window range: {0} expected: {1}",
368 TmfTraceManager
.getInstance().getCurrentTraceContext().getWindowRange(), range
);
374 * Condition to check if the selection contains the specified text at the
375 * specified column. The text is checked in any item of the tree selection.
383 * @return ICondition for verification
385 public static ICondition
treeSelectionContains(final SWTBotTree tree
, final int column
, final String text
) {
386 return new SWTBotTestCondition() {
388 public boolean test() throws Exception
{
389 TableCollection selection
= tree
.selection();
390 for (int row
= 0; row
< selection
.rowCount(); row
++) {
391 if (selection
.get(row
, column
).equals(text
)) {
399 public String
getFailureMessage() {
400 return NLS
.bind("Tree selection [0,{0}]: {1} expected: {2}",
401 new Object
[] { column
, tree
.selection().get(0, column
), text
});
406 private static class EventsTableSelectionCondition
extends DefaultCondition
{
407 private long fSelectionTime
;
408 private SWTWorkbenchBot fBot
;
410 private EventsTableSelectionCondition(SWTWorkbenchBot bot
, long selectionTime
) {
412 fSelectionTime
= selectionTime
;
416 public boolean test() throws Exception
{
417 StructuredSelection eventsTableSelection
= getEventsTableSelection();
418 if (eventsTableSelection
.isEmpty()) {
421 return ((ITmfEvent
) eventsTableSelection
.getFirstElement()).getTimestamp().getValue() == fSelectionTime
;
425 public String
getFailureMessage() {
426 return "The selection in the table was not an event with timestamp " + fSelectionTime
;
429 private StructuredSelection
getEventsTableSelection() {
430 return UIThreadRunnable
.syncExec(new Result
<StructuredSelection
>() {
433 public StructuredSelection
run() {
434 SWTBotEditor eventsEditor
= SWTBotUtils
.activeEventsEditor(fBot
);
435 TmfEventsEditor part
= (TmfEventsEditor
) eventsEditor
.getReference().getPart(false);
436 StructuredSelection selection
= (StructuredSelection
) part
.getSelection();
444 * Wait until the events table selection matches the specified time stamp.
449 * @param selectionTime
451 * @return ICondition for verification
453 public static ICondition
selectionInEventsTable(final SWTWorkbenchBot bot
, long selectionTime
) {
454 return new EventsTableSelectionCondition(bot
, selectionTime
);
457 private static class TimeGraphIsReadyCondition
extends DefaultCondition
{
459 private @NonNull TmfTimeRange fSelectionRange
;
460 private @NonNull ITmfTimestamp fVisibleTime
;
461 private AbstractTimeGraphView fView
;
463 private TimeGraphIsReadyCondition(AbstractTimeGraphView view
, @NonNull TmfTimeRange selectionRange
, @NonNull ITmfTimestamp visibleTime
) {
465 fSelectionRange
= selectionRange
;
466 fVisibleTime
= visibleTime
;
470 public boolean test() throws Exception
{
471 if (!ConditionHelpers
.selectionRange(fSelectionRange
).test()) {
474 if (!TmfTraceManager
.getInstance().getCurrentTraceContext().getWindowRange().contains(fVisibleTime
)) {
477 return !fView
.isDirty();
481 public String
getFailureMessage() {
482 return "Time graph is not ready";
488 * Wait until the Time Graph view is ready. The Time Graph view is
489 * considered ready if the selectionRange is selected, the visibleTime is
490 * visible and the view is not dirty (its model is done updating).
493 * the time graph view
494 * @param selectionRange
495 * the selection that the time graph should have
497 * the visible time that the time graph should have
498 * @return ICondition for verification
500 public static ICondition
timeGraphIsReadyCondition(AbstractTimeGraphView view
, @NonNull TmfTimeRange selectionRange
, @NonNull ITmfTimestamp visibleTime
) {
501 return new TimeGraphIsReadyCondition(view
, selectionRange
, visibleTime
);