1 /*******************************************************************************
2 * Copyright (c) 2013, 2016 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 public 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 * Is the treeItem's node removed
168 * length of the node after removal
171 * @return true or false, it should swallow all exceptions
173 public static ICondition
isTreeChildNodeRemoved(final int length
, final SWTBotTreeItem treeItem
) {
174 return new SWTBotTestCondition() {
176 public boolean test() throws Exception
{
178 return treeItem
.getNodes().size() == length
;
179 } catch (Exception e
) {
185 public String
getFailureMessage() {
186 return NLS
.bind("Child of tree item {0} found with text '{1}' not removed. Child items: {2}",
187 new String
[] { treeItem
.toString(), String
.valueOf(length
), Arrays
.toString(treeItem
.getItems()) });
193 * Condition to check if the number of direct children of the
194 * provided tree item equals the specified count.
197 * the SWTBot tree item
200 * @return ICondition for verification
202 public static ICondition
treeItemCount(final SWTBotTreeItem treeItem
, int count
) {
203 return new SWTBotTestCondition() {
205 public boolean test() throws Exception
{
206 return treeItem
.rowCount() == count
;
210 public String
getFailureMessage() {
211 return NLS
.bind("Tree item count: {0} expected: {1}",
212 treeItem
.rowCount(), count
);
218 * Checks if the wizard's shell is null
222 * @return false if either are null
224 public static ICondition
isWizardReady(final Wizard wizard
) {
225 return new SWTBotTestCondition() {
227 public boolean test() throws Exception
{
228 if (wizard
.getShell() == null) {
237 * Is the wizard on the page you want?
243 * @return true or false
245 public static ICondition
isWizardOnPage(final Wizard wizard
, final IWizardPage page
) {
246 return new SWTBotTestCondition() {
248 public boolean test() throws Exception
{
249 if (wizard
== null || page
== null) {
252 final IWizardContainer container
= wizard
.getContainer();
253 if (container
== null) {
256 IWizardPage currentPage
= container
.getCurrentPage();
257 return page
.equals(currentPage
);
263 * Wait for a view to close
266 * bot view for the view
267 * @return true if the view is closed, false if it's active.
269 public static ICondition
ViewIsClosed(final SWTBotView view
) {
270 return new SWTBotTestCondition() {
272 public boolean test() throws Exception
{
273 return (view
!= null) && (!view
.isActive());
279 * Wait till table cell has a given content.
282 * the table bot reference
284 * the content to check
286 * the row of the cell
288 * the column of the cell
289 * @return ICondition for verification
291 public static ICondition
isTableCellFilled(final SWTBotTable table
,
292 final String content
, final int row
, final int column
) {
293 return new SWTBotTestCondition() {
295 public boolean test() throws Exception
{
297 String cell
= table
.cell(row
, column
);
301 return cell
.contains(content
);
302 } catch (Exception e
) {
310 * Condition to check if a tracing project element has a child with the
311 * specified name. A project element label may have a count suffix in the
314 public static class ProjectElementHasChild
extends DefaultCondition
{
316 private final SWTBotTreeItem fParentItem
;
317 private final String fName
;
318 private final String fRegex
;
319 private SWTBotTreeItem fItem
= null;
327 * the child name to look for
329 public ProjectElementHasChild(final SWTBotTreeItem parentItem
, final String name
) {
330 fParentItem
= parentItem
;
332 /* Project element labels may have count suffix */
333 fRegex
= name
+ "(\\s\\[(\\d)+\\])?";
337 public boolean test() throws Exception
{
338 fParentItem
.expand();
339 for (SWTBotTreeItem item
: fParentItem
.getItems()) {
340 if (item
.getText().matches(fRegex
)) {
349 public String
getFailureMessage() {
350 return NLS
.bind("No child of {0} found with name {1}", fParentItem
.getText(), fName
);
354 * Returns the matching child item if the condition returned true.
356 * @return the matching item
358 public SWTBotTreeItem
getItem() {
364 * Condition to check if an editor with the specified title is opened.
370 * @return ICondition for verification
372 public static ICondition
isEditorOpened(final SWTWorkbenchBot bot
, final String title
) {
373 return new SWTBotTestCondition() {
375 public boolean test() throws Exception
{
376 Matcher
<IEditorReference
> withPartName
= withPartName(title
);
377 return !bot
.editors(withPartName
).isEmpty();
383 * Condition to check if the selection range equals the specified range.
386 * the selection range
387 * @return ICondition for verification
389 public static ICondition
selectionRange(final TmfTimeRange range
) {
390 return new SWTBotTestCondition() {
392 public boolean test() throws Exception
{
393 return TmfTraceManager
.getInstance().getCurrentTraceContext().getSelectionRange().equals(range
);
397 public String
getFailureMessage() {
398 return NLS
.bind("Selection range: {0} expected: {1}",
399 TmfTraceManager
.getInstance().getCurrentTraceContext().getSelectionRange(), range
);
405 * Condition to check if the window range equals the specified range.
409 * @return ICondition for verification
411 public static ICondition
windowRange(final TmfTimeRange range
) {
412 return new SWTBotTestCondition() {
414 public boolean test() throws Exception
{
415 return TmfTraceManager
.getInstance().getCurrentTraceContext().getWindowRange().equals(range
);
419 public String
getFailureMessage() {
420 return NLS
.bind("Window range: {0} expected: {1}",
421 TmfTraceManager
.getInstance().getCurrentTraceContext().getWindowRange(), range
);
427 * Condition to check if the selection contains the specified text at the
428 * specified column. The text is checked in any item of the tree selection.
436 * @return ICondition for verification
438 public static ICondition
treeSelectionContains(final SWTBotTree tree
, final int column
, final String text
) {
439 return new SWTBotTestCondition() {
441 public boolean test() throws Exception
{
442 TableCollection selection
= tree
.selection();
443 for (int row
= 0; row
< selection
.rowCount(); row
++) {
444 if (selection
.get(row
, column
).equals(text
)) {
452 public String
getFailureMessage() {
453 return NLS
.bind("Tree selection [0,{0}]: {1} expected: {2}",
454 new Object
[] { column
, tree
.selection().get(0, column
), text
});
459 private static class EventsTableSelectionCondition
extends DefaultCondition
{
460 private long fSelectionTime
;
461 private SWTWorkbenchBot fBot
;
462 private long fCurValue
;
464 private EventsTableSelectionCondition(SWTWorkbenchBot bot
, long selectionTime
) {
466 fSelectionTime
= selectionTime
;
470 public boolean test() throws Exception
{
471 StructuredSelection eventsTableSelection
= getEventsTableSelection();
472 if (eventsTableSelection
.isEmpty()) {
475 fCurValue
= ((ITmfEvent
) eventsTableSelection
.getFirstElement()).getTimestamp().getValue();
476 return fCurValue
== fSelectionTime
;
480 public String
getFailureMessage() {
481 return "The selection in the table was not an event with timestamp " + fSelectionTime
+ ". Actual is " + fCurValue
;
484 private StructuredSelection
getEventsTableSelection() {
485 return UIThreadRunnable
.syncExec(new Result
<StructuredSelection
>() {
488 public StructuredSelection
run() {
489 SWTBotEditor eventsEditor
= SWTBotUtils
.activeEventsEditor(fBot
);
490 TmfEventsEditor part
= (TmfEventsEditor
) eventsEditor
.getReference().getPart(false);
491 StructuredSelection selection
= (StructuredSelection
) part
.getSelection();
499 * Wait until the events table selection matches the specified time stamp.
504 * @param selectionTime
506 * @return ICondition for verification
508 public static ICondition
selectionInEventsTable(final SWTWorkbenchBot bot
, long selectionTime
) {
509 return new EventsTableSelectionCondition(bot
, selectionTime
);
512 private static class TimeGraphIsReadyCondition
extends DefaultCondition
{
514 private @NonNull TmfTimeRange fSelectionRange
;
515 private @NonNull ITmfTimestamp fVisibleTime
;
516 private AbstractTimeGraphView fView
;
517 private String fFailureMessage
;
519 private TimeGraphIsReadyCondition(AbstractTimeGraphView view
, @NonNull TmfTimeRange selectionRange
, @NonNull ITmfTimestamp visibleTime
) {
521 fSelectionRange
= selectionRange
;
522 fVisibleTime
= visibleTime
;
526 public boolean test() throws Exception
{
527 ICondition selectionRangeCondition
= ConditionHelpers
.selectionRange(fSelectionRange
);
528 if (!selectionRangeCondition
.test()) {
529 fFailureMessage
= selectionRangeCondition
.getFailureMessage();
532 @NonNull TmfTimeRange curWindowRange
= TmfTraceManager
.getInstance().getCurrentTraceContext().getWindowRange();
533 if (!curWindowRange
.contains(fVisibleTime
)) {
534 fFailureMessage
= "Current window range " + curWindowRange
+ " does not contain " + fVisibleTime
;
538 if (fView
.isDirty()) {
539 fFailureMessage
= "Time graph is dirty";
547 public String
getFailureMessage() {
548 return fFailureMessage
;
554 * Wait until the Time Graph view is ready. The Time Graph view is
555 * considered ready if the selectionRange is selected, the visibleTime is
556 * visible and the view is not dirty (its model is done updating).
559 * the time graph view
560 * @param selectionRange
561 * the selection that the time graph should have
563 * the visible time that the time graph should have
564 * @return ICondition for verification
566 public static ICondition
timeGraphIsReadyCondition(AbstractTimeGraphView view
, @NonNull TmfTimeRange selectionRange
, @NonNull ITmfTimestamp visibleTime
) {
567 return new TimeGraphIsReadyCondition(view
, selectionRange
, visibleTime
);