--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson and others
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests;
+
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jface.bindings.keys.KeyStroke;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
+import org.eclipse.swtbot.swt.finder.keyboard.Keyboard;
+import org.eclipse.swtbot.swt.finder.keyboard.KeyboardFactory;
+import org.eclipse.swtbot.swt.finder.keyboard.Keystrokes;
+import org.eclipse.swtbot.swt.finder.matchers.WidgetOfType;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotCheckBox;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotCombo;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotLabel;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotRadio;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
+import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers;
+import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractTimeGraphView;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphSelection;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Abstract class to build SWTBot test for time graph find dialog. Test the time
+ * graph view find dialog and its options.
+ *
+ * @author Jean-Christian Kouame
+ */
+@RunWith(SWTBotJunit4ClassRunner.class)
+public abstract class FindDialogTestBase extends KernelTestBase {
+
+ private static final Keyboard KEYBOARD = KeyboardFactory.getSWTKeyboard();
+ private static final @NonNull ITmfTimestamp START_TIME = TmfTimestamp.create(1368000272650993664L, ITmfTimestamp.NANOSECOND_SCALE);
+ private static final @NonNull String SPACE = " ";
+ private static final String REGEX_PREFIX = "\\A";
+ private static final String DIALOG_TITLE = "Find";
+ private String fFindText;
+ private SWTBotView fViewBot;
+
+ private static int fSelectionIndex;
+
+ /**
+ * Get the title of the time graph view the find dialog will use
+ *
+ * @return The view title
+ */
+ protected abstract String getViewTitle();
+
+ /**
+ * Get the string that will be used for the search
+ *
+ * @return The string
+ */
+ protected abstract String getFindText();
+
+ /**
+ * Initialize the test and open the timegraph view and the find dialog
+ */
+ @Before
+ public void init() {
+ String title = getViewTitle();
+ fViewBot = fBot.viewByTitle(title);
+ fViewBot.show();
+ fViewBot.setFocus();
+
+ TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(this, START_TIME));
+ fBot.waitUntil(ConditionHelpers.timeGraphIsReadyCondition((AbstractTimeGraphView) fViewBot.getViewReference().getPart(false), new TmfTimeRange(START_TIME, START_TIME), START_TIME));
+ openDialog(fViewBot);
+
+ fFindText = getFindText();
+ }
+
+ /**
+ * After class method to close the dialog
+ */
+ @AfterClass
+ public static void afterTest() {
+ closeDialog(getDialogBot());
+ }
+
+ private static void openDialog(SWTBotView view) {
+ view.setFocus();
+ KEYBOARD.pressShortcut(Keystrokes.HOME);
+ KEYBOARD.pressShortcut(Keystrokes.CTRL, KeyStroke.getInstance('F'));
+ fBot.waitUntil(Conditions.shellIsActive(DIALOG_TITLE));
+ }
+
+ /**
+ * Test wrap search option
+ */
+ @Test
+ public void testWrapSearch() {
+ SWTBot bot = getDialogBot();
+ SWTBotButton findButton = bot.button("Find");
+
+ SearchOptions options = getOptions(false, false, true, false, false);
+ search(fFindText, options, findButton, bot);
+ assertTrue(isWrapped(bot));
+ verifySelection(fFindText, options, fViewBot, isWrapped(bot));
+ options = getOptions(true, false, true, false, false);
+ search(fFindText, options, findButton, bot);
+ assertTrue(isWrapped(bot));
+ }
+
+ /**
+ * Test the direction search option
+ */
+ @Test
+ public void testDirection() {
+ SWTBot bot = getDialogBot();
+ SWTBotButton findButton = bot.button("Find");
+
+ // forward
+ testDirectionSearch(true, fFindText, bot, findButton, fViewBot);
+ testDirectionSearch(false, fFindText, bot, findButton, fViewBot);
+ }
+
+ private void testDirectionSearch(boolean forward, String findText, SWTBot bot, SWTBotButton findButton, SWTBotView view) {
+ SearchOptions options = getOptions(forward, false, true, false, false);
+ fSelectionIndex = getSelectionIndex(view);
+ search(findText, options, findButton, bot);
+ verifySelection(findText, options, view, isWrapped(bot));
+ }
+
+ /**
+ * Test the case sensitive search option
+ */
+ @Test
+ public void testCaseSensitive() {
+ SWTBot bot = getDialogBot();
+ SWTBotButton findButton = bot.button("Find");
+
+ SearchOptions options = getOptions(true, true, false, false, false);
+ search(fFindText, options, findButton, bot);
+ verifyStatusLabel(bot, true);
+ search(fFindText.toLowerCase(), options, findButton, bot);
+ verifyStatusLabel(bot, false);
+ }
+
+ /**
+ * Test the whole word search option
+ */
+ @Test
+ public void testWholeWord() {
+ SWTBot bot = getDialogBot();
+ SWTBotButton findButton = bot.button("Find");
+
+ @NonNull
+ String text = fFindText.split(SPACE)[0];
+ System.out.println("Reg ex : " + text);
+ SearchOptions options = getOptions(true, false, false, true, false);
+ search(text, options, findButton, bot);
+ verifyStatusLabel(bot, true);
+ search(text.substring(0, text.length() - 1), options, findButton, bot);
+ verifyStatusLabel(bot, false);
+ }
+
+ /**
+ * Test the regular expression search option
+ */
+ @Test
+ public void testRegEx() {
+ SWTBot bot = getDialogBot();
+ SWTBotButton findButton = bot.button("Find");
+
+ final String text = REGEX_PREFIX + fFindText.split(SPACE)[0];
+ System.out.println("Reg ex : " + text);
+ SearchOptions options = getOptions(true, false, false, false, true);
+ search(text, options, findButton, bot);
+ verifyStatusLabel(bot, true);
+ options = getOptions(true, false, false, false, false);
+ search(text, options, findButton, bot);
+ verifyStatusLabel(bot, false);
+ }
+
+ /**
+ * Test open/close the find dialog
+ */
+ @Test
+ public void testOpenCloseDialog() {
+ SWTBotShell shell = getDialogShell();
+ closeDialog(getDialogBot());
+ fBot.waitUntil(Conditions.shellCloses(shell));
+ openDialog(fViewBot);
+ }
+
+ private static void verifyStatusLabel(SWTBot bot, boolean shouldBeFound) {
+ // Get the second label in the dialog
+ SWTBotLabel statusLabel = bot.label(1);
+ assertTrue("status label", shouldBeFound == !statusLabel.getText().equals("Entry not found"));
+ }
+
+ /**
+ * Get the find dialog bot
+ *
+ * @return The bot
+ */
+ private static SWTBot getDialogBot() {
+ return getDialogShell().bot();
+ }
+
+ /**
+ * Get the find dialog shell bot
+ *
+ * @return The shell bot
+ */
+ private static SWTBotShell getDialogShell() {
+ return fBot.shell(DIALOG_TITLE);
+ }
+
+ private static void closeDialog(SWTBot bot) {
+ bot.button("Close").click();
+ }
+
+ private static void search(String findText, SearchOptions options, SWTBotButton findButton, SWTBot bot) {
+ // set the text to search
+ SWTBotCombo findFieldCombo = bot.comboBox();
+ findFieldCombo.setText(findText);
+ assertTrue("Find combo", findFieldCombo.getText().equals(findText));
+
+ // set the options
+ SWTBotRadio directions = options.forwardSearch ? bot.radio("Forward").click() : bot.radio("Backward").click();
+ assertTrue("direction", directions.isSelected());
+
+ setCheckButton("Case sensitive", options.caseSensitive, bot);
+ setCheckButton("Wrap search", options.wrapSearch, bot);
+ setCheckButton("Whole word", options.wholeWord, bot);
+ setCheckButton("Regular expression", options.regExSearch, bot);
+
+ findButton.click();
+ }
+
+ private SearchOptions getOptions(boolean forward, boolean caseSensitive, boolean wrapSearch, boolean wholeWord, boolean regEx) {
+ SearchOptions options = new SearchOptions();
+ options.forwardSearch = forward;
+ options.caseSensitive = caseSensitive;
+ options.wrapSearch = wrapSearch;
+ options.wholeWord = wholeWord;
+ options.regExSearch = regEx;
+ return options;
+ }
+
+ private static void setCheckButton(String mnemonic, boolean option, SWTBot bot) {
+ final SWTBotCheckBox checkBox = bot.checkBox(mnemonic);
+ if (checkBox.isEnabled()) {
+ if (option) {
+ checkBox.select();
+ } else {
+ checkBox.deselect();
+ }
+ }
+ }
+
+ private static void verifySelection(String name, SearchOptions options, SWTBotView view, boolean isWrapped) {
+ final String entryName = getTimegraphSelectionName(view);
+ assertTrue("entry name", entryName != null && entryName.contains(name));
+
+ final int selectionIndex = getSelectionIndex(view);
+ if (!isWrapped) {
+ assertTrue("selection index", options.forwardSearch ? selectionIndex > fSelectionIndex : selectionIndex < fSelectionIndex);
+ } else {
+ assertTrue("selection index", options.forwardSearch ? selectionIndex <= fSelectionIndex : selectionIndex >= fSelectionIndex);
+ }
+ fSelectionIndex = selectionIndex;
+ }
+
+ private static boolean isWrapped(final SWTBot bot) {
+ return bot.label(1).getText().equals("Wrapped search");
+ }
+
+ /**
+ * Get the timegraph view selected entry
+ *
+ * @param viewBot
+ * The timegraph view bot
+ * @return The selected entry
+ */
+ private static String getTimegraphSelectionName(final SWTBotView view) {
+ final TimeGraphControl timegraph = view.bot().widget(WidgetOfType.widgetOfType(TimeGraphControl.class));
+ return UIThreadRunnable.syncExec(() -> {
+ ISelection selection = timegraph.getSelectionTrace();
+ if (selection instanceof TimeGraphSelection) {
+ TimeGraphSelection sel = (TimeGraphSelection) selection;
+ ITimeGraphEntry entry = (ITimeGraphEntry) sel.getFirstElement();
+ return entry.getName();
+ }
+ return null;
+ });
+ }
+
+ /**
+ * Get the index of the entry selected in the timegraph view
+ *
+ * @param viewBot
+ * The timegraph view bot
+ * @return
+ */
+ private static Integer getSelectionIndex(SWTBotView viewBot) {
+ final TimeGraphControl timegraph = viewBot.bot().widget(WidgetOfType.widgetOfType(TimeGraphControl.class));
+ return UIThreadRunnable.syncExec(() -> {
+ return timegraph.getSelectedIndex();
+ });
+ }
+
+ private class SearchOptions {
+ boolean forwardSearch;
+ boolean caseSensitive;
+ boolean wrapSearch;
+ boolean wholeWord;
+ boolean regExSearch;
+ }
+}