Commit | Line | Data |
---|---|---|
fa24d78b | 1 | /******************************************************************************* |
ed902a2b | 2 | * Copyright (c) 2013, 2015 Ericsson |
fa24d78b AM |
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 | * Alexandre Montplaisir - Replaced separate Condition objects by anonymous classes | |
88051e61 | 12 | * Patrick Tasse - Add projectElementHasChild and isEditorOpened conditions |
fa24d78b AM |
13 | *******************************************************************************/ |
14 | ||
15 | package org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared; | |
16 | ||
88051e61 PT |
17 | import static org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory.withPartName; |
18 | ||
46958d08 PT |
19 | import java.util.Arrays; |
20 | ||
156e9ead | 21 | import org.eclipse.jdt.annotation.NonNull; |
573087b4 | 22 | import org.eclipse.jface.viewers.StructuredSelection; |
fa24d78b AM |
23 | import org.eclipse.jface.wizard.IWizardContainer; |
24 | import org.eclipse.jface.wizard.IWizardPage; | |
25 | import org.eclipse.jface.wizard.Wizard; | |
21e5206c | 26 | import org.eclipse.osgi.util.NLS; |
88051e61 | 27 | import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; |
573087b4 | 28 | import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor; |
fa24d78b AM |
29 | import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; |
30 | import org.eclipse.swtbot.swt.finder.SWTBot; | |
573087b4 MAL |
31 | import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; |
32 | import org.eclipse.swtbot.swt.finder.results.Result; | |
6e4a07af | 33 | import org.eclipse.swtbot.swt.finder.utils.TableCollection; |
21e5206c | 34 | import org.eclipse.swtbot.swt.finder.waits.DefaultCondition; |
fa24d78b AM |
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; | |
573087b4 | 39 | import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; |
156e9ead | 40 | import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; |
2fe6a9ea PT |
41 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; |
42 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; | |
573087b4 | 43 | import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor; |
156e9ead | 44 | import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractTimeGraphView; |
88051e61 PT |
45 | import org.eclipse.ui.IEditorReference; |
46 | import org.hamcrest.Matcher; | |
fa24d78b AM |
47 | |
48 | /** | |
49 | * Is a tree node available | |
50 | * | |
51 | * @author Matthew Khouzam | |
52 | */ | |
53 | public final class ConditionHelpers { | |
54 | ||
55 | private ConditionHelpers() {} | |
56 | ||
57 | /** | |
58 | * Provide default implementations for some {@link ICondition} methods. | |
59 | */ | |
60 | private abstract static class SWTBotTestCondition implements ICondition { | |
61 | ||
62 | @Override | |
63 | public abstract boolean test() throws Exception; | |
64 | ||
65 | @Override | |
66 | public final void init(SWTBot bot) { | |
67 | } | |
68 | ||
69 | @Override | |
2fe6a9ea | 70 | public String getFailureMessage() { |
fa24d78b AM |
71 | return null; |
72 | } | |
73 | } | |
74 | ||
75 | /** | |
76 | * Is a tree node available | |
77 | * | |
78 | * @param name | |
79 | * the name of the node | |
80 | * @param tree | |
81 | * the parent tree | |
82 | * @return true or false, it should swallow all exceptions | |
83 | */ | |
84 | public static ICondition IsTreeNodeAvailable(final String name, final SWTBotTree tree) { | |
85 | return new SWTBotTestCondition() { | |
86 | @Override | |
87 | public boolean test() throws Exception { | |
88 | try { | |
89 | final SWTBotTreeItem[] treeItems = tree.getAllItems(); | |
90 | for (SWTBotTreeItem ti : treeItems) { | |
91 | final String text = ti.getText(); | |
92 | if (text.equals(name)) { | |
93 | return true; | |
94 | } | |
95 | } | |
96 | } catch (Exception e) { | |
97 | } | |
98 | return false; | |
99 | } | |
46958d08 PT |
100 | |
101 | @Override | |
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()) }); | |
105 | } | |
fa24d78b AM |
106 | }; |
107 | } | |
108 | ||
bbdb3d6d MAL |
109 | /** |
110 | * Is a table item available | |
111 | * | |
112 | * @param name | |
113 | * the name of the item | |
114 | * @param table | |
115 | * the parent table | |
116 | * @return true or false, it should swallow all exceptions | |
117 | */ | |
118 | public static ICondition isTableItemAvailable(final String name, final SWTBotTable table) { | |
119 | return new SWTBotTestCondition() { | |
120 | @Override | |
121 | public boolean test() throws Exception { | |
122 | try { | |
123 | return table.containsItem(name); | |
124 | } catch (Exception e) { | |
125 | } | |
126 | return false; | |
127 | } | |
46958d08 PT |
128 | |
129 | @Override | |
130 | public String getFailureMessage() { | |
131 | return NLS.bind("No child of table {0} found with text '{1}'.", table, name); | |
132 | } | |
bbdb3d6d MAL |
133 | }; |
134 | } | |
135 | ||
fa24d78b AM |
136 | /** |
137 | * Is the treeItem's node available | |
138 | * | |
139 | * @param name | |
140 | * the name of the node | |
141 | * @param treeItem | |
142 | * the treeItem | |
143 | * @return true or false, it should swallow all exceptions | |
144 | */ | |
145 | public static ICondition IsTreeChildNodeAvailable(final String name, final SWTBotTreeItem treeItem) { | |
146 | return new SWTBotTestCondition() { | |
147 | @Override | |
148 | public boolean test() throws Exception { | |
149 | try { | |
150 | return treeItem.getNode(name) != null; | |
151 | } catch (Exception e) { | |
152 | } | |
153 | return false; | |
154 | } | |
46958d08 PT |
155 | |
156 | @Override | |
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()) }); | |
160 | } | |
fa24d78b AM |
161 | }; |
162 | } | |
163 | ||
164 | /** | |
165 | * Checks if the wizard's shell is null | |
166 | * | |
167 | * @param wizard | |
168 | * the null | |
169 | * @return false if either are null | |
170 | */ | |
171 | public static ICondition isWizardReady(final Wizard wizard) { | |
172 | return new SWTBotTestCondition() { | |
173 | @Override | |
174 | public boolean test() throws Exception { | |
175 | if (wizard.getShell() == null) { | |
176 | return false; | |
177 | } | |
178 | return true; | |
179 | } | |
180 | }; | |
181 | } | |
182 | ||
183 | /** | |
184 | * Is the wizard on the page you want? | |
185 | * | |
186 | * @param wizard | |
187 | * wizard | |
188 | * @param page | |
189 | * the desired page | |
190 | * @return true or false | |
191 | */ | |
192 | public static ICondition isWizardOnPage(final Wizard wizard, final IWizardPage page) { | |
193 | return new SWTBotTestCondition() { | |
194 | @Override | |
195 | public boolean test() throws Exception { | |
196 | if (wizard == null || page == null) { | |
197 | return false; | |
198 | } | |
199 | final IWizardContainer container = wizard.getContainer(); | |
200 | if (container == null) { | |
201 | return false; | |
202 | } | |
203 | IWizardPage currentPage = container.getCurrentPage(); | |
204 | return page.equals(currentPage); | |
205 | } | |
206 | }; | |
207 | } | |
208 | ||
209 | /** | |
210 | * Wait for a view to close | |
211 | * | |
212 | * @param view | |
213 | * bot view for the view | |
214 | * @return true if the view is closed, false if it's active. | |
215 | */ | |
216 | public static ICondition ViewIsClosed(final SWTBotView view) { | |
217 | return new SWTBotTestCondition() { | |
218 | @Override | |
219 | public boolean test() throws Exception { | |
220 | return (view != null) && (!view.isActive()); | |
221 | } | |
222 | }; | |
223 | } | |
224 | ||
225 | /** | |
226 | * Wait till table cell has a given content. | |
227 | * | |
228 | * @param table | |
229 | * the table bot reference | |
230 | * @param content | |
231 | * the content to check | |
232 | * @param row | |
233 | * the row of the cell | |
234 | * @param column | |
235 | * the column of the cell | |
236 | * @return ICondition for verification | |
237 | */ | |
238 | public static ICondition isTableCellFilled(final SWTBotTable table, | |
239 | final String content, final int row, final int column) { | |
240 | return new SWTBotTestCondition() { | |
241 | @Override | |
242 | public boolean test() throws Exception { | |
243 | try { | |
2470d687 MK |
244 | String cell = table.cell(row, column); |
245 | if( cell == null ) { | |
246 | return false; | |
247 | } | |
248 | return cell.endsWith(content); | |
fa24d78b AM |
249 | } catch (Exception e) { |
250 | } | |
251 | return false; | |
252 | } | |
253 | }; | |
254 | } | |
21e5206c PT |
255 | |
256 | /** | |
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 | |
259 | * format ' [n]'. | |
260 | */ | |
261 | public static class ProjectElementHasChild extends DefaultCondition { | |
262 | ||
263 | private final SWTBotTreeItem fParentItem; | |
264 | private final String fName; | |
265 | private final String fRegex; | |
266 | private SWTBotTreeItem fItem = null; | |
267 | ||
268 | /** | |
269 | * Constructor. | |
270 | * | |
271 | * @param parentItem | |
272 | * the parent item | |
273 | * @param name | |
274 | * the child name to look for | |
275 | */ | |
276 | public ProjectElementHasChild(final SWTBotTreeItem parentItem, final String name) { | |
277 | fParentItem = parentItem; | |
278 | fName = name; | |
279 | /* Project element labels may have count suffix */ | |
280 | fRegex = name + "(\\s\\[(\\d)+\\])?"; | |
281 | } | |
282 | ||
283 | @Override | |
284 | public boolean test() throws Exception { | |
285 | fParentItem.expand(); | |
286 | for (SWTBotTreeItem item : fParentItem.getItems()) { | |
287 | if (item.getText().matches(fRegex)) { | |
288 | fItem = item; | |
289 | return true; | |
290 | } | |
291 | } | |
292 | return false; | |
293 | } | |
294 | ||
295 | @Override | |
296 | public String getFailureMessage() { | |
297 | return NLS.bind("No child of {0} found with name {1}", fParentItem.getText(), fName); | |
298 | } | |
299 | ||
300 | /** | |
301 | * Returns the matching child item if the condition returned true. | |
302 | * | |
303 | * @return the matching item | |
304 | */ | |
305 | public SWTBotTreeItem getItem() { | |
306 | return fItem; | |
307 | } | |
308 | } | |
88051e61 PT |
309 | |
310 | /** | |
311 | * Condition to check if an editor with the specified title is opened. | |
312 | * | |
313 | * @param bot | |
314 | * a workbench bot | |
315 | * @param title | |
316 | * the editor title | |
317 | * @return ICondition for verification | |
318 | */ | |
319 | public static ICondition isEditorOpened(final SWTWorkbenchBot bot, final String title) { | |
320 | return new SWTBotTestCondition() { | |
321 | @Override | |
322 | public boolean test() throws Exception { | |
323 | Matcher<IEditorReference> withPartName = withPartName(title); | |
324 | return !bot.editors(withPartName).isEmpty(); | |
325 | } | |
326 | }; | |
327 | } | |
2fe6a9ea PT |
328 | |
329 | /** | |
330 | * Condition to check if the selection range equals the specified range. | |
331 | * | |
332 | * @param range | |
333 | * the selection range | |
334 | * @return ICondition for verification | |
335 | */ | |
336 | public static ICondition selectionRange(final TmfTimeRange range) { | |
337 | return new SWTBotTestCondition() { | |
338 | @Override | |
339 | public boolean test() throws Exception { | |
340 | return TmfTraceManager.getInstance().getCurrentTraceContext().getSelectionRange().equals(range); | |
341 | } | |
342 | ||
343 | @Override | |
344 | public String getFailureMessage() { | |
345 | return NLS.bind("Selection range: {0} expected: {1}", | |
346 | TmfTraceManager.getInstance().getCurrentTraceContext().getSelectionRange(), range); | |
347 | } | |
348 | }; | |
349 | } | |
350 | ||
351 | /** | |
352 | * Condition to check if the window range equals the specified range. | |
353 | * | |
354 | * @param range | |
355 | * the window range | |
356 | * @return ICondition for verification | |
357 | */ | |
358 | public static ICondition windowRange(final TmfTimeRange range) { | |
359 | return new SWTBotTestCondition() { | |
360 | @Override | |
361 | public boolean test() throws Exception { | |
362 | return TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange().equals(range); | |
363 | } | |
364 | ||
365 | @Override | |
366 | public String getFailureMessage() { | |
367 | return NLS.bind("Window range: {0} expected: {1}", | |
368 | TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange(), range); | |
369 | } | |
370 | }; | |
371 | } | |
6e4a07af PT |
372 | |
373 | /** | |
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. | |
376 | * | |
377 | * @param tree | |
378 | * the SWTBot tree | |
379 | * @param column | |
380 | * the column index | |
381 | * @param text | |
382 | * the expected text | |
383 | * @return ICondition for verification | |
384 | */ | |
385 | public static ICondition treeSelectionContains(final SWTBotTree tree, final int column, final String text) { | |
386 | return new SWTBotTestCondition() { | |
387 | @Override | |
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)) { | |
392 | return true; | |
393 | } | |
394 | } | |
395 | return false; | |
396 | } | |
397 | ||
398 | @Override | |
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}); | |
402 | } | |
403 | }; | |
404 | } | |
573087b4 MAL |
405 | |
406 | private static class EventsTableSelectionCondition extends DefaultCondition { | |
407 | private long fSelectionTime; | |
408 | private SWTWorkbenchBot fBot; | |
409 | ||
410 | private EventsTableSelectionCondition(SWTWorkbenchBot bot, long selectionTime) { | |
411 | fBot = bot; | |
412 | fSelectionTime = selectionTime; | |
413 | } | |
414 | ||
415 | @Override | |
416 | public boolean test() throws Exception { | |
417 | StructuredSelection eventsTableSelection = getEventsTableSelection(); | |
418 | if (eventsTableSelection.isEmpty()) { | |
419 | return false; | |
420 | } | |
421 | return ((ITmfEvent) eventsTableSelection.getFirstElement()).getTimestamp().getValue() == fSelectionTime; | |
422 | } | |
423 | ||
424 | @Override | |
425 | public String getFailureMessage() { | |
426 | return "The selection in the table was not an event with timestamp " + fSelectionTime; | |
427 | } | |
428 | ||
429 | private StructuredSelection getEventsTableSelection() { | |
430 | return UIThreadRunnable.syncExec(new Result<StructuredSelection>() { | |
431 | ||
432 | @Override | |
433 | public StructuredSelection run() { | |
434 | SWTBotEditor eventsEditor = SWTBotUtils.activeEventsEditor(fBot); | |
435 | TmfEventsEditor part = (TmfEventsEditor) eventsEditor.getReference().getPart(false); | |
436 | StructuredSelection selection = (StructuredSelection) part.getSelection(); | |
437 | return selection; | |
438 | } | |
439 | }); | |
440 | } | |
441 | } | |
442 | ||
443 | /** | |
444 | * Wait until the events table selection matches the specified time stamp. | |
445 | * | |
446 | * @param bot | |
447 | * a workbench bot | |
448 | * | |
449 | * @param selectionTime | |
450 | * the selection time | |
451 | * @return ICondition for verification | |
452 | */ | |
453 | public static ICondition selectionInEventsTable(final SWTWorkbenchBot bot, long selectionTime) { | |
454 | return new EventsTableSelectionCondition(bot, selectionTime); | |
455 | } | |
156e9ead MAL |
456 | |
457 | private static class TimeGraphIsReadyCondition extends DefaultCondition { | |
458 | ||
459 | private @NonNull TmfTimeRange fSelectionRange; | |
460 | private @NonNull ITmfTimestamp fVisibleTime; | |
461 | private AbstractTimeGraphView fView; | |
462 | ||
463 | private TimeGraphIsReadyCondition(AbstractTimeGraphView view, @NonNull TmfTimeRange selectionRange, @NonNull ITmfTimestamp visibleTime) { | |
464 | fView = view; | |
465 | fSelectionRange = selectionRange; | |
466 | fVisibleTime = visibleTime; | |
467 | } | |
468 | ||
469 | @Override | |
470 | public boolean test() throws Exception { | |
471 | if (!ConditionHelpers.selectionRange(fSelectionRange).test()) { | |
472 | return false; | |
473 | } | |
474 | if (!TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange().contains(fVisibleTime)) { | |
475 | return false; | |
476 | } | |
477 | return !fView.isDirty(); | |
478 | } | |
479 | ||
480 | @Override | |
481 | public String getFailureMessage() { | |
482 | return "Time graph is not ready"; | |
483 | } | |
484 | } | |
485 | ||
486 | /** | |
487 | * | |
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). | |
491 | * | |
492 | * @param view | |
493 | * the time graph view | |
494 | * @param selectionRange | |
495 | * the selection that the time graph should have | |
496 | * @param visibleTime | |
497 | * the visible time that the time graph should have | |
498 | * @return ICondition for verification | |
499 | */ | |
500 | public static ICondition timeGraphIsReadyCondition(AbstractTimeGraphView view, @NonNull TmfTimeRange selectionRange, @NonNull ITmfTimestamp visibleTime) { | |
501 | return new TimeGraphIsReadyCondition(view, selectionRange, visibleTime); | |
502 | } | |
88051e61 | 503 | } |