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