Commit | Line | Data |
---|---|---|
c76f2206 JCK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2016 Ericsson and others | |
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 | package org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests; | |
10 | ||
11 | import static org.junit.Assert.assertTrue; | |
12 | ||
13 | import org.eclipse.jdt.annotation.NonNull; | |
14 | import org.eclipse.jface.bindings.keys.KeyStroke; | |
15 | import org.eclipse.jface.viewers.ISelection; | |
16 | import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; | |
17 | import org.eclipse.swtbot.swt.finder.SWTBot; | |
18 | import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; | |
19 | import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; | |
20 | import org.eclipse.swtbot.swt.finder.keyboard.Keyboard; | |
21 | import org.eclipse.swtbot.swt.finder.keyboard.KeyboardFactory; | |
22 | import org.eclipse.swtbot.swt.finder.keyboard.Keystrokes; | |
23 | import org.eclipse.swtbot.swt.finder.matchers.WidgetOfType; | |
1c9b6343 | 24 | import org.eclipse.swtbot.swt.finder.utils.SWTUtils; |
c76f2206 JCK |
25 | import org.eclipse.swtbot.swt.finder.waits.Conditions; |
26 | import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton; | |
27 | import org.eclipse.swtbot.swt.finder.widgets.SWTBotCheckBox; | |
28 | import org.eclipse.swtbot.swt.finder.widgets.SWTBotCombo; | |
29 | import org.eclipse.swtbot.swt.finder.widgets.SWTBotLabel; | |
30 | import org.eclipse.swtbot.swt.finder.widgets.SWTBotRadio; | |
31 | import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell; | |
32 | import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal; | |
33 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; | |
34 | import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; | |
35 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; | |
36 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; | |
37 | import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers; | |
1c9b6343 | 38 | import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils; |
c76f2206 JCK |
39 | import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractTimeGraphView; |
40 | import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; | |
41 | import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl; | |
42 | import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphSelection; | |
43 | import org.junit.AfterClass; | |
44 | import org.junit.Before; | |
45 | import org.junit.Test; | |
46 | import org.junit.runner.RunWith; | |
47 | ||
48 | /** | |
49 | * Abstract class to build SWTBot test for time graph find dialog. Test the time | |
50 | * graph view find dialog and its options. | |
51 | * | |
52 | * @author Jean-Christian Kouame | |
53 | */ | |
54 | @RunWith(SWTBotJunit4ClassRunner.class) | |
55 | public abstract class FindDialogTestBase extends KernelTestBase { | |
56 | ||
57 | private static final Keyboard KEYBOARD = KeyboardFactory.getSWTKeyboard(); | |
58 | private static final @NonNull ITmfTimestamp START_TIME = TmfTimestamp.create(1368000272650993664L, ITmfTimestamp.NANOSECOND_SCALE); | |
59 | private static final @NonNull String SPACE = " "; | |
60 | private static final String REGEX_PREFIX = "\\A"; | |
61 | private static final String DIALOG_TITLE = "Find"; | |
62 | private String fFindText; | |
63 | private SWTBotView fViewBot; | |
64 | ||
65 | private static int fSelectionIndex; | |
66 | ||
67 | /** | |
68 | * Get the title of the time graph view the find dialog will use | |
69 | * | |
70 | * @return The view title | |
71 | */ | |
72 | protected abstract String getViewTitle(); | |
73 | ||
74 | /** | |
75 | * Get the string that will be used for the search | |
76 | * | |
77 | * @return The string | |
78 | */ | |
79 | protected abstract String getFindText(); | |
80 | ||
81 | /** | |
82 | * Initialize the test and open the timegraph view and the find dialog | |
83 | */ | |
84 | @Before | |
85 | public void init() { | |
86 | String title = getViewTitle(); | |
87 | fViewBot = fBot.viewByTitle(title); | |
88 | fViewBot.show(); | |
89 | fViewBot.setFocus(); | |
90 | ||
91 | TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(this, START_TIME)); | |
92 | fBot.waitUntil(ConditionHelpers.timeGraphIsReadyCondition((AbstractTimeGraphView) fViewBot.getViewReference().getPart(false), new TmfTimeRange(START_TIME, START_TIME), START_TIME)); | |
93 | openDialog(fViewBot); | |
94 | ||
95 | fFindText = getFindText(); | |
96 | } | |
97 | ||
98 | /** | |
99 | * After class method to close the dialog | |
100 | */ | |
101 | @AfterClass | |
102 | public static void afterTest() { | |
103 | closeDialog(getDialogBot()); | |
104 | } | |
105 | ||
106 | private static void openDialog(SWTBotView view) { | |
107 | view.setFocus(); | |
1c9b6343 MAL |
108 | SWTBotUtils.pressShortcutGoToTreeTop(KEYBOARD); |
109 | if (SWTUtils.isMac()) { | |
110 | KEYBOARD.pressShortcut(Keystrokes.COMMAND, KeyStroke.getInstance('F')); | |
111 | } else { | |
112 | KEYBOARD.pressShortcut(Keystrokes.CTRL, KeyStroke.getInstance('F')); | |
113 | } | |
c76f2206 JCK |
114 | fBot.waitUntil(Conditions.shellIsActive(DIALOG_TITLE)); |
115 | } | |
116 | ||
117 | /** | |
118 | * Test wrap search option | |
119 | */ | |
120 | @Test | |
121 | public void testWrapSearch() { | |
122 | SWTBot bot = getDialogBot(); | |
123 | SWTBotButton findButton = bot.button("Find"); | |
124 | ||
125 | SearchOptions options = getOptions(false, false, true, false, false); | |
126 | search(fFindText, options, findButton, bot); | |
127 | assertTrue(isWrapped(bot)); | |
128 | verifySelection(fFindText, options, fViewBot, isWrapped(bot)); | |
129 | options = getOptions(true, false, true, false, false); | |
130 | search(fFindText, options, findButton, bot); | |
131 | assertTrue(isWrapped(bot)); | |
132 | } | |
133 | ||
134 | /** | |
135 | * Test the direction search option | |
136 | */ | |
137 | @Test | |
138 | public void testDirection() { | |
139 | SWTBot bot = getDialogBot(); | |
140 | SWTBotButton findButton = bot.button("Find"); | |
141 | ||
142 | // forward | |
143 | testDirectionSearch(true, fFindText, bot, findButton, fViewBot); | |
144 | testDirectionSearch(false, fFindText, bot, findButton, fViewBot); | |
145 | } | |
146 | ||
147 | private void testDirectionSearch(boolean forward, String findText, SWTBot bot, SWTBotButton findButton, SWTBotView view) { | |
148 | SearchOptions options = getOptions(forward, false, true, false, false); | |
149 | fSelectionIndex = getSelectionIndex(view); | |
150 | search(findText, options, findButton, bot); | |
151 | verifySelection(findText, options, view, isWrapped(bot)); | |
152 | } | |
153 | ||
154 | /** | |
155 | * Test the case sensitive search option | |
156 | */ | |
157 | @Test | |
158 | public void testCaseSensitive() { | |
159 | SWTBot bot = getDialogBot(); | |
160 | SWTBotButton findButton = bot.button("Find"); | |
161 | ||
162 | SearchOptions options = getOptions(true, true, false, false, false); | |
163 | search(fFindText, options, findButton, bot); | |
164 | verifyStatusLabel(bot, true); | |
165 | search(fFindText.toLowerCase(), options, findButton, bot); | |
166 | verifyStatusLabel(bot, false); | |
167 | } | |
168 | ||
169 | /** | |
170 | * Test the whole word search option | |
171 | */ | |
172 | @Test | |
173 | public void testWholeWord() { | |
174 | SWTBot bot = getDialogBot(); | |
175 | SWTBotButton findButton = bot.button("Find"); | |
176 | ||
177 | @NonNull | |
178 | String text = fFindText.split(SPACE)[0]; | |
179 | System.out.println("Reg ex : " + text); | |
180 | SearchOptions options = getOptions(true, false, false, true, false); | |
181 | search(text, options, findButton, bot); | |
182 | verifyStatusLabel(bot, true); | |
183 | search(text.substring(0, text.length() - 1), options, findButton, bot); | |
184 | verifyStatusLabel(bot, false); | |
185 | } | |
186 | ||
187 | /** | |
188 | * Test the regular expression search option | |
189 | */ | |
190 | @Test | |
191 | public void testRegEx() { | |
192 | SWTBot bot = getDialogBot(); | |
193 | SWTBotButton findButton = bot.button("Find"); | |
194 | ||
195 | final String text = REGEX_PREFIX + fFindText.split(SPACE)[0]; | |
196 | System.out.println("Reg ex : " + text); | |
197 | SearchOptions options = getOptions(true, false, false, false, true); | |
198 | search(text, options, findButton, bot); | |
199 | verifyStatusLabel(bot, true); | |
200 | options = getOptions(true, false, false, false, false); | |
201 | search(text, options, findButton, bot); | |
202 | verifyStatusLabel(bot, false); | |
203 | } | |
204 | ||
205 | /** | |
206 | * Test open/close the find dialog | |
207 | */ | |
208 | @Test | |
209 | public void testOpenCloseDialog() { | |
210 | SWTBotShell shell = getDialogShell(); | |
211 | closeDialog(getDialogBot()); | |
212 | fBot.waitUntil(Conditions.shellCloses(shell)); | |
213 | openDialog(fViewBot); | |
214 | } | |
215 | ||
216 | private static void verifyStatusLabel(SWTBot bot, boolean shouldBeFound) { | |
217 | // Get the second label in the dialog | |
218 | SWTBotLabel statusLabel = bot.label(1); | |
219 | assertTrue("status label", shouldBeFound == !statusLabel.getText().equals("Entry not found")); | |
220 | } | |
221 | ||
222 | /** | |
223 | * Get the find dialog bot | |
224 | * | |
225 | * @return The bot | |
226 | */ | |
227 | private static SWTBot getDialogBot() { | |
228 | return getDialogShell().bot(); | |
229 | } | |
230 | ||
231 | /** | |
232 | * Get the find dialog shell bot | |
233 | * | |
234 | * @return The shell bot | |
235 | */ | |
236 | private static SWTBotShell getDialogShell() { | |
237 | return fBot.shell(DIALOG_TITLE); | |
238 | } | |
239 | ||
240 | private static void closeDialog(SWTBot bot) { | |
241 | bot.button("Close").click(); | |
242 | } | |
243 | ||
244 | private static void search(String findText, SearchOptions options, SWTBotButton findButton, SWTBot bot) { | |
245 | // set the text to search | |
246 | SWTBotCombo findFieldCombo = bot.comboBox(); | |
247 | findFieldCombo.setText(findText); | |
248 | assertTrue("Find combo", findFieldCombo.getText().equals(findText)); | |
249 | ||
250 | // set the options | |
251 | SWTBotRadio directions = options.forwardSearch ? bot.radio("Forward").click() : bot.radio("Backward").click(); | |
252 | assertTrue("direction", directions.isSelected()); | |
253 | ||
254 | setCheckButton("Case sensitive", options.caseSensitive, bot); | |
255 | setCheckButton("Wrap search", options.wrapSearch, bot); | |
256 | setCheckButton("Whole word", options.wholeWord, bot); | |
257 | setCheckButton("Regular expression", options.regExSearch, bot); | |
258 | ||
259 | findButton.click(); | |
260 | } | |
261 | ||
262 | private SearchOptions getOptions(boolean forward, boolean caseSensitive, boolean wrapSearch, boolean wholeWord, boolean regEx) { | |
263 | SearchOptions options = new SearchOptions(); | |
264 | options.forwardSearch = forward; | |
265 | options.caseSensitive = caseSensitive; | |
266 | options.wrapSearch = wrapSearch; | |
267 | options.wholeWord = wholeWord; | |
268 | options.regExSearch = regEx; | |
269 | return options; | |
270 | } | |
271 | ||
272 | private static void setCheckButton(String mnemonic, boolean option, SWTBot bot) { | |
273 | final SWTBotCheckBox checkBox = bot.checkBox(mnemonic); | |
274 | if (checkBox.isEnabled()) { | |
275 | if (option) { | |
276 | checkBox.select(); | |
277 | } else { | |
278 | checkBox.deselect(); | |
279 | } | |
280 | } | |
281 | } | |
282 | ||
283 | private static void verifySelection(String name, SearchOptions options, SWTBotView view, boolean isWrapped) { | |
284 | final String entryName = getTimegraphSelectionName(view); | |
285 | assertTrue("entry name", entryName != null && entryName.contains(name)); | |
286 | ||
287 | final int selectionIndex = getSelectionIndex(view); | |
288 | if (!isWrapped) { | |
289 | assertTrue("selection index", options.forwardSearch ? selectionIndex > fSelectionIndex : selectionIndex < fSelectionIndex); | |
290 | } else { | |
291 | assertTrue("selection index", options.forwardSearch ? selectionIndex <= fSelectionIndex : selectionIndex >= fSelectionIndex); | |
292 | } | |
293 | fSelectionIndex = selectionIndex; | |
294 | } | |
295 | ||
296 | private static boolean isWrapped(final SWTBot bot) { | |
297 | return bot.label(1).getText().equals("Wrapped search"); | |
298 | } | |
299 | ||
300 | /** | |
301 | * Get the timegraph view selected entry | |
302 | * | |
303 | * @param viewBot | |
304 | * The timegraph view bot | |
305 | * @return The selected entry | |
306 | */ | |
307 | private static String getTimegraphSelectionName(final SWTBotView view) { | |
308 | final TimeGraphControl timegraph = view.bot().widget(WidgetOfType.widgetOfType(TimeGraphControl.class)); | |
309 | return UIThreadRunnable.syncExec(() -> { | |
310 | ISelection selection = timegraph.getSelectionTrace(); | |
311 | if (selection instanceof TimeGraphSelection) { | |
312 | TimeGraphSelection sel = (TimeGraphSelection) selection; | |
313 | ITimeGraphEntry entry = (ITimeGraphEntry) sel.getFirstElement(); | |
314 | return entry.getName(); | |
315 | } | |
316 | return null; | |
317 | }); | |
318 | } | |
319 | ||
320 | /** | |
321 | * Get the index of the entry selected in the timegraph view | |
322 | * | |
323 | * @param viewBot | |
324 | * The timegraph view bot | |
325 | * @return | |
326 | */ | |
327 | private static Integer getSelectionIndex(SWTBotView viewBot) { | |
328 | final TimeGraphControl timegraph = viewBot.bot().widget(WidgetOfType.widgetOfType(TimeGraphControl.class)); | |
329 | return UIThreadRunnable.syncExec(() -> { | |
330 | return timegraph.getSelectedIndex(); | |
331 | }); | |
332 | } | |
333 | ||
334 | private class SearchOptions { | |
335 | boolean forwardSearch; | |
336 | boolean caseSensitive; | |
337 | boolean wrapSearch; | |
338 | boolean wholeWord; | |
339 | boolean regExSearch; | |
340 | } | |
341 | } |