1 /******************************************************************************
2 * Copyright (c) 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
8 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.projectexplorer
;
12 import static org
.junit
.Assert
.assertEquals
;
13 import static org
.junit
.Assert
.assertTrue
;
14 import static org
.junit
.Assert
.fail
;
17 import java
.io
.IOException
;
19 import java
.net
.URISyntaxException
;
21 import java
.util
.List
;
22 import java
.util
.stream
.Collectors
;
24 import org
.apache
.log4j
.ConsoleAppender
;
25 import org
.apache
.log4j
.Logger
;
26 import org
.apache
.log4j
.SimpleLayout
;
27 import org
.eclipse
.core
.runtime
.FileLocator
;
28 import org
.eclipse
.core
.runtime
.Path
;
29 import org
.eclipse
.jdt
.annotation
.NonNull
;
30 import org
.eclipse
.swt
.widgets
.MenuItem
;
31 import org
.eclipse
.swtbot
.eclipse
.finder
.SWTWorkbenchBot
;
32 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotEditor
;
33 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotView
;
34 import org
.eclipse
.swtbot
.swt
.finder
.exceptions
.WidgetNotFoundException
;
35 import org
.eclipse
.swtbot
.swt
.finder
.finders
.ContextMenuFinder
;
36 import org
.eclipse
.swtbot
.swt
.finder
.finders
.UIThreadRunnable
;
37 import org
.eclipse
.swtbot
.swt
.finder
.junit
.SWTBotJunit4ClassRunner
;
38 import org
.eclipse
.swtbot
.swt
.finder
.keyboard
.Keystrokes
;
39 import org
.eclipse
.swtbot
.swt
.finder
.utils
.SWTBotPreferences
;
40 import org
.eclipse
.swtbot
.swt
.finder
.waits
.Conditions
;
41 import org
.eclipse
.swtbot
.swt
.finder
.waits
.DefaultCondition
;
42 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotShell
;
43 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTable
;
44 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotText
;
45 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeItem
;
46 import org
.eclipse
.tracecompass
.tmf
.core
.tests
.TmfCoreTestPlugin
;
47 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
48 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.ConditionHelpers
;
49 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.SWTBotUtils
;
50 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.statistics
.TmfStatisticsView
;
51 import org
.eclipse
.ui
.IEditorReference
;
52 import org
.hamcrest
.core
.IsAnything
;
53 import org
.junit
.AfterClass
;
54 import org
.junit
.BeforeClass
;
55 import org
.junit
.Test
;
56 import org
.junit
.runner
.RunWith
;
58 import com
.google
.common
.collect
.ImmutableList
;
61 * SWTBot test for testing Project Explorer Trace actions (context-menus,
64 @RunWith(SWTBotJunit4ClassRunner
.class)
65 public class ProjectExplorerTraceActionsTest
{
66 private static final String TRACE_PROJECT_NAME
= "test";
67 private static final String TRACE_NAME
= "syslog_collapse";
68 private static final String RENAMED_TRACE_NAME
= TRACE_NAME
+ 2;
69 private static final String TRACE_PATH
= "testfiles/" + TRACE_NAME
;
70 private static final String TRACE_TYPE
= "org.eclipse.linuxtools.tmf.tests.stubs.trace.text.testsyslog";
72 private static File fTestFile
= null;
74 private static SWTWorkbenchBot fBot
;
76 /** The Log4j logger instance. */
77 private static final Logger fLogger
= Logger
.getRootLogger();
78 private static final long NB_EVENTS
= 22;
84 public static void init() {
85 SWTBotUtils
.initialize();
87 /* set up test trace */
88 URL location
= FileLocator
.find(TmfCoreTestPlugin
.getDefault().getBundle(), new Path(TRACE_PATH
), null);
91 uri
= FileLocator
.toFileURL(location
).toURI();
92 fTestFile
= new File(uri
);
93 } catch (URISyntaxException
| IOException e
) {
98 assertTrue(fTestFile
.exists());
100 /* Set up for swtbot */
101 SWTBotPreferences
.TIMEOUT
= 20000; /* 20 second timeout */
102 SWTBotPreferences
.KEYBOARD_LAYOUT
= "EN_US";
103 fLogger
.removeAllAppenders();
104 fLogger
.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender
.SYSTEM_OUT
));
105 fBot
= new SWTWorkbenchBot();
107 /* Close welcome view */
108 SWTBotUtils
.closeView("Welcome", fBot
);
110 /* Switch perspectives */
111 SWTBotUtils
.switchToTracingPerspective();
113 /* Finish waiting for eclipse to load */
114 SWTBotUtils
.waitForJobs();
115 SWTBotUtils
.createProject(TRACE_PROJECT_NAME
);
119 * Test class tear down method.
122 public static void tearDown() {
123 SWTBotUtils
.deleteProject(TRACE_PROJECT_NAME
, fBot
);
124 fLogger
.removeAllAppenders();
128 * Test that the expected context menu items are there
130 * Action : Trace menu
132 * Procedure :Select an LTTng trace and open its context menu
134 * Expected Results: Correct menu opens (Open , Copy, Rename, …)
138 public void test4_01ContextMenuPresence() {
139 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
140 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
142 final List
<String
> EXPECTED_MENU_LABELS
= ImmutableList
.of(
143 "&Open\tShift+Ctrl+R", "Open With", "&Copy...\tCtrl+C", "Rena&me...\tF2", "&Delete\tDelete", "Delete &Supplementary Files...", "&Export Trace Package...", "Select &Trace Type...", "Apply Time Offset...", "Clear Time Offset",
146 // TODO: SWTBot needs a better way to do this
147 ContextMenuFinder finder
= new ContextMenuFinder(fBot
.tree().widget
);
148 List
<MenuItem
> menuItems
= finder
.findMenus(traceItem
.contextMenu().widget
, new IsAnything
<>(), false);
150 List
<String
> menuLabels
= menuItems
.stream().map((item
) -> {
151 return UIThreadRunnable
.syncExec(() -> item
.getText());
152 }).collect(Collectors
.toList());
153 assertEquals(EXPECTED_MENU_LABELS
, menuLabels
);
155 fBot
.closeAllEditors();
159 * Test that the trace opens with the context menu
161 * Action : Open trace
163 * Procedure :Select the Open menu
165 * Expected Results: Trace is opened and views are populated
169 public void test4_02Open() {
170 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
171 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
173 traceItem
.contextMenu().menu("Open").click();
174 testEventsTable(TRACE_NAME
);
175 testStatisticsView();
176 fBot
.closeAllEditors();
180 * Test that the trace can be copied with the context menu
182 * Action : Copy trace
184 * Procedure :Select the Copy menu and provide a new name. Open.
186 * Expected Results: Trace is replicated under the new name
190 public void test4_03Copy() {
191 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
192 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
194 createCopy(traceItem
);
196 fBot
.closeAllEditors();
197 SWTBotTreeItem copiedItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), RENAMED_TRACE_NAME
);
198 copiedItem
.contextMenu().menu("Open").click();
199 testEventsTable(RENAMED_TRACE_NAME
);
200 fBot
.closeAllEditors();
201 SWTBotUtils
.clearTracesFolder(fBot
, TRACE_PROJECT_NAME
);
205 * Test that the trace can be renamed with the context menu
207 * Action : Rename trace
209 * Procedure :Select the Rename menu and provide a new name. Reopen.
211 * Expected Results: Trace is renamed. The trace editor is closed.
214 public void test4_04Rename() {
215 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
216 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
218 traceItem
.contextMenu().menu("Rename...").click();
219 final String RENAME_TRACE_DIALOG_TITLE
= "Rename Trace";
220 fBot
.waitUntil(Conditions
.shellIsActive(RENAME_TRACE_DIALOG_TITLE
));
221 SWTBotShell shell
= fBot
.shell(RENAME_TRACE_DIALOG_TITLE
);
222 SWTBotText text
= shell
.bot().textWithLabel("New Trace name:");
223 text
.setText(RENAMED_TRACE_NAME
);
224 shell
.bot().button("OK").click();
225 fBot
.waitUntil(Conditions
.shellCloses(shell
));
226 fBot
.waitWhile(new ConditionHelpers
.ActiveEventsEditor(fBot
, null));
228 SWTBotTreeItem copiedItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), RENAMED_TRACE_NAME
);
229 copiedItem
.contextMenu().menu("Open").click();
230 testEventsTable(RENAMED_TRACE_NAME
);
231 fBot
.closeAllEditors();
232 SWTBotUtils
.clearTracesFolder(fBot
, TRACE_PROJECT_NAME
);
236 * Test that the trace can be deleted with the context menu
238 * Action : Delete trace
240 * Procedure :Select the Delete menu and confirm deletion
242 * Expected Results: Trace is deleted. The trace editor is closed.
246 public void test4_05Delete() {
247 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
248 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
250 traceItem
.contextMenu().menu("Delete").click();
251 final String DELETE_TRACE_DIALOG_TITLE
= "Confirm Delete";
252 fBot
.waitUntil(Conditions
.shellIsActive(DELETE_TRACE_DIALOG_TITLE
));
253 SWTBotShell shell
= fBot
.shell(DELETE_TRACE_DIALOG_TITLE
);
254 shell
.bot().button("Yes").click();
255 fBot
.waitUntil(Conditions
.shellCloses(shell
));
256 fBot
.waitWhile(new ConditionHelpers
.ActiveEventsEditor(fBot
, null));
260 * Test that the trace opens with the keyboard
262 * Action : Open Trace (Accelerator)
264 * Procedure :Select trace and press Enter
266 * Expected Results: Trace is opened
269 * @throws WidgetNotFoundException
270 * when a widget is not found
273 public void test4_06OpenKeyboard() throws WidgetNotFoundException
{
274 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
275 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
277 fBot
.activeShell().pressShortcut(Keystrokes
.CR
);
279 testEventsTable(TRACE_NAME
);
280 testStatisticsView();
281 fBot
.closeAllEditors();
285 * Test that the trace can be deleted with the keyboard
287 * Action : Delete Trace (Accelerator)
289 * Procedure :Select trace and press Delete and confirm deletion
291 * Expected Results: Trace is deleted. The trace editor is closed.
294 public void test4_07DeleteKeyboard() {
295 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
296 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
298 fBot
.activeShell().pressShortcut(Keystrokes
.DELETE
);
299 final String DELETE_TRACE_DIALOG_TITLE
= "Confirm Delete";
300 fBot
.waitUntil(Conditions
.shellIsActive(DELETE_TRACE_DIALOG_TITLE
));
301 SWTBotShell shell
= fBot
.shell(DELETE_TRACE_DIALOG_TITLE
);
302 shell
.bot().button("Yes").click();
303 fBot
.waitUntil(Conditions
.shellCloses(shell
));
304 fBot
.waitWhile(new ConditionHelpers
.ActiveEventsEditor(fBot
, null));
308 * Test that the trace opens with double-click
310 * Action : Open Trace (double click)
312 * Procedure :Double-click a trace
314 * Expected Results: Trace is opened
316 * @throws WidgetNotFoundException
317 * when a widget is not found
320 public void test4_08OpenDoubleClick() throws WidgetNotFoundException
{
321 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
322 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
324 traceItem
.doubleClick();
326 testEventsTable(TRACE_NAME
);
327 testStatisticsView();
328 fBot
.closeAllEditors();
332 * Test that the trace is brought to top if already opened
334 * Action : Open Trace (already open)
336 * Procedure :Open two traces. Open the first trace again.
338 * Expected Results: The first trace editor is simply brought to front.
341 public void test4_09BringToTop() {
342 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
343 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
345 traceItem
.doubleClick();
346 fBot
.waitUntil(new ConditionHelpers
.ActiveEventsEditor(fBot
, TRACE_NAME
));
347 IEditorReference originalEditor
= fBot
.activeEditor().getReference();
349 createCopy(traceItem
);
351 SWTBotTreeItem copiedItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), RENAMED_TRACE_NAME
);
353 copiedItem
.doubleClick();
354 copiedItem
.doubleClick();
355 fBot
.waitUntil(new ConditionHelpers
.ActiveEventsEditor(fBot
, RENAMED_TRACE_NAME
));
356 SWTBotUtils
.delay(1000);
358 traceItem
.doubleClick();
359 fBot
.waitUntil(new ConditionHelpers
.ActiveEventsEditor(fBot
, TRACE_NAME
));
360 assertTrue(originalEditor
== fBot
.activeEditor().getReference());
362 fBot
.closeAllEditors();
363 SWTBotUtils
.clearTracesFolder(fBot
, TRACE_PROJECT_NAME
);
366 private static void createCopy(SWTBotTreeItem traceItem
) {
367 traceItem
.contextMenu().menu("Copy...").click();
368 final String COPY_TRACE_DIALOG_TITLE
= "Copy Trace";
369 fBot
.waitUntil(Conditions
.shellIsActive(COPY_TRACE_DIALOG_TITLE
));
370 SWTBotShell shell
= fBot
.shell(COPY_TRACE_DIALOG_TITLE
);
371 SWTBotText text
= shell
.bot().textWithLabel("New Trace name:");
372 text
.setText(RENAMED_TRACE_NAME
);
373 shell
.bot().button("OK").click();
374 fBot
.waitUntil(Conditions
.shellCloses(shell
));
377 private static void testEventsTable(String editorName
) {
378 SWTBotEditor editor
= SWTBotUtils
.activeEventsEditor(fBot
, editorName
);
379 fBot
.waitUntil(ConditionHelpers
.numberOfEventsInTrace(TmfTraceManager
.getInstance().getActiveTrace(), NB_EVENTS
));
381 SWTBotTable table
= editor
.bot().table();
382 fBot
.waitUntil(new DefaultCondition() {
384 public boolean test() throws Exception
{
385 return table
.rowCount() > 1;
389 public String
getFailureMessage() {
390 return "No items in table";
393 // Select first event (skip filter/search row)
394 table
.getTableItem(1).select();
396 editor
.bot().waitUntil(new DefaultCondition() {
398 public boolean test() throws Exception
{
399 return table
.selection().rowCount() == 1 && table
.selection().get(0).toString().contains("01:01");
403 public String
getFailureMessage() {
404 return "First event not selected";
409 private static void testStatisticsView() {
410 SWTBotUtils
.openView(TmfStatisticsView
.ID
);
411 SWTBotView view
= fBot
.viewById(TmfStatisticsView
.ID
);
412 assertTrue(view
.bot().tree().hasItems());
413 view
.bot().tree().cell(0, 1).equals(Long
.toString(NB_EVENTS
));