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
.resources
.ResourcesPlugin
;
28 import org
.eclipse
.core
.runtime
.FileLocator
;
29 import org
.eclipse
.core
.runtime
.Path
;
30 import org
.eclipse
.jdt
.annotation
.NonNull
;
31 import org
.eclipse
.swt
.widgets
.MenuItem
;
32 import org
.eclipse
.swtbot
.eclipse
.finder
.SWTWorkbenchBot
;
33 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotEditor
;
34 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotView
;
35 import org
.eclipse
.swtbot
.swt
.finder
.exceptions
.WidgetNotFoundException
;
36 import org
.eclipse
.swtbot
.swt
.finder
.finders
.ContextMenuFinder
;
37 import org
.eclipse
.swtbot
.swt
.finder
.finders
.UIThreadRunnable
;
38 import org
.eclipse
.swtbot
.swt
.finder
.junit
.SWTBotJunit4ClassRunner
;
39 import org
.eclipse
.swtbot
.swt
.finder
.keyboard
.Keystrokes
;
40 import org
.eclipse
.swtbot
.swt
.finder
.utils
.SWTBotPreferences
;
41 import org
.eclipse
.swtbot
.swt
.finder
.waits
.Conditions
;
42 import org
.eclipse
.swtbot
.swt
.finder
.waits
.DefaultCondition
;
43 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotShell
;
44 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTable
;
45 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotText
;
46 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeItem
;
47 import org
.eclipse
.tracecompass
.tmf
.core
.tests
.TmfCoreTestPlugin
;
48 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
49 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.ConditionHelpers
;
50 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.SWTBotUtils
;
51 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.statistics
.TmfStatisticsView
;
52 import org
.eclipse
.ui
.IEditorReference
;
53 import org
.hamcrest
.core
.IsAnything
;
54 import org
.junit
.AfterClass
;
55 import org
.junit
.BeforeClass
;
56 import org
.junit
.Test
;
57 import org
.junit
.runner
.RunWith
;
59 import com
.google
.common
.collect
.ImmutableList
;
62 * SWTBot test for testing Project Explorer Trace actions (context-menus,
65 @RunWith(SWTBotJunit4ClassRunner
.class)
66 public class ProjectExplorerTraceActionsTest
{
67 private static final String TRACE_PROJECT_NAME
= "test";
68 private static final String TRACE_NAME
= "syslog_collapse";
69 private static final String RENAMED_TRACE_NAME
= TRACE_NAME
+ 2;
70 private static final String TRACE_PATH
= "testfiles/" + TRACE_NAME
;
71 private static final String TRACE_TYPE
= "org.eclipse.linuxtools.tmf.tests.stubs.trace.text.testsyslog";
73 private static File fTestFile
= null;
75 private static SWTWorkbenchBot fBot
;
77 /** The Log4j logger instance. */
78 private static final Logger fLogger
= Logger
.getRootLogger();
79 private static final long NB_EVENTS
= 22;
85 public static void init() {
86 SWTBotUtils
.initialize();
88 /* set up test trace */
89 URL location
= FileLocator
.find(TmfCoreTestPlugin
.getDefault().getBundle(), new Path(TRACE_PATH
), null);
92 uri
= FileLocator
.toFileURL(location
).toURI();
93 fTestFile
= new File(uri
);
94 } catch (URISyntaxException
| IOException e
) {
99 assertTrue(fTestFile
.exists());
101 /* Set up for swtbot */
102 SWTBotPreferences
.TIMEOUT
= 20000; /* 20 second timeout */
103 SWTBotPreferences
.KEYBOARD_LAYOUT
= "EN_US";
104 fLogger
.removeAllAppenders();
105 fLogger
.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender
.SYSTEM_OUT
));
106 fBot
= new SWTWorkbenchBot();
108 /* Close welcome view */
109 SWTBotUtils
.closeView("Welcome", fBot
);
111 /* Switch perspectives */
112 SWTBotUtils
.switchToTracingPerspective();
114 /* Finish waiting for eclipse to load */
115 SWTBotUtils
.waitForJobs();
116 SWTBotUtils
.createProject(TRACE_PROJECT_NAME
);
120 * Test class tear down method.
123 public static void tearDown() {
124 SWTBotUtils
.deleteProject(TRACE_PROJECT_NAME
, fBot
);
125 fLogger
.removeAllAppenders();
129 * Test that the expected context menu items are there
131 * Action : Trace menu
133 * Procedure :Select an LTTng trace and open its context menu
135 * Expected Results: Correct menu opens (Open , Copy, Rename, …)
139 public void test4_01ContextMenuPresence() {
140 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
141 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
143 final List
<String
> EXPECTED_MENU_LABELS
= ImmutableList
.of(
144 "&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",
147 // TODO: SWTBot needs a better way to do this
148 ContextMenuFinder finder
= new ContextMenuFinder(fBot
.tree().widget
);
149 List
<MenuItem
> menuItems
= finder
.findMenus(traceItem
.contextMenu().widget
, new IsAnything
<>(), false);
151 List
<String
> menuLabels
= menuItems
.stream().map((item
) -> {
152 return UIThreadRunnable
.syncExec(() -> item
.getText());
153 }).collect(Collectors
.toList());
154 assertEquals(EXPECTED_MENU_LABELS
, menuLabels
);
156 fBot
.closeAllEditors();
160 * Test that the trace opens with the context menu
162 * Action : Open trace
164 * Procedure :Select the Open menu
166 * Expected Results: Trace is opened and views are populated
170 public void test4_02Open() {
171 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
172 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
174 traceItem
.contextMenu().menu("Open").click();
175 testEventsTable(TRACE_NAME
);
176 testStatisticsView();
177 fBot
.closeAllEditors();
181 * Test that the trace can be copied with the context menu
183 * Action : Copy trace
185 * Procedure :Select the Copy menu and provide a new name. Open.
187 * Expected Results: Trace is replicated under the new name
191 public void test4_03Copy() {
192 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
193 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
195 createCopy(traceItem
);
197 fBot
.closeAllEditors();
198 SWTBotTreeItem copiedItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), RENAMED_TRACE_NAME
);
199 copiedItem
.contextMenu().menu("Open").click();
200 testEventsTable(RENAMED_TRACE_NAME
);
201 fBot
.closeAllEditors();
202 SWTBotUtils
.clearTracesFolder(fBot
, TRACE_PROJECT_NAME
);
206 * Test that the trace can be renamed with the context menu
208 * Action : Rename trace
210 * Procedure :Select the Rename menu and provide a new name. Reopen.
212 * Expected Results: Trace is renamed. The trace editor is closed.
215 public void test4_04Rename() {
216 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
217 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
219 traceItem
.contextMenu().menu("Rename...").click();
220 final String RENAME_TRACE_DIALOG_TITLE
= "Rename Trace";
221 fBot
.waitUntil(Conditions
.shellIsActive(RENAME_TRACE_DIALOG_TITLE
));
222 SWTBotShell shell
= fBot
.shell(RENAME_TRACE_DIALOG_TITLE
);
223 SWTBotText text
= shell
.bot().textWithLabel("New Trace name:");
224 text
.setText(RENAMED_TRACE_NAME
);
225 shell
.bot().button("OK").click();
226 fBot
.waitUntil(Conditions
.shellCloses(shell
));
227 fBot
.waitWhile(new ConditionHelpers
.ActiveEventsEditor(fBot
, null));
229 SWTBotTreeItem copiedItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), RENAMED_TRACE_NAME
);
230 copiedItem
.contextMenu().menu("Open").click();
231 testEventsTable(RENAMED_TRACE_NAME
);
232 fBot
.closeAllEditors();
233 SWTBotUtils
.clearTracesFolder(fBot
, TRACE_PROJECT_NAME
);
237 * Test that the trace can be deleted with the context menu
239 * Action : Delete trace
241 * Procedure :Select the Delete menu and confirm deletion
243 * Expected Results: Trace is deleted. The trace editor is closed.
247 public void test4_05Delete() {
248 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
249 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
251 traceItem
.contextMenu().menu("Delete").click();
252 final String DELETE_TRACE_DIALOG_TITLE
= "Confirm Delete";
253 fBot
.waitUntil(Conditions
.shellIsActive(DELETE_TRACE_DIALOG_TITLE
));
254 SWTBotShell shell
= fBot
.shell(DELETE_TRACE_DIALOG_TITLE
);
255 shell
.bot().button("Yes").click();
256 fBot
.waitUntil(Conditions
.shellCloses(shell
));
257 fBot
.waitWhile(new ConditionHelpers
.ActiveEventsEditor(fBot
, null));
258 fBot
.waitUntil(new TraceDeletedCondition());
262 * Test that the trace opens with the keyboard
264 * Action : Open Trace (Accelerator)
266 * Procedure :Select trace and press Enter
268 * Expected Results: Trace is opened
271 * @throws WidgetNotFoundException
272 * when a widget is not found
275 public void test4_06OpenKeyboard() throws WidgetNotFoundException
{
276 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
277 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
279 fBot
.activeShell().pressShortcut(Keystrokes
.CR
);
281 testEventsTable(TRACE_NAME
);
282 testStatisticsView();
283 fBot
.closeAllEditors();
287 * Test that the trace can be deleted with the keyboard
289 * Action : Delete Trace (Accelerator)
291 * Procedure :Select trace and press Delete and confirm deletion
293 * Expected Results: Trace is deleted. The trace editor is closed.
296 public void test4_07DeleteKeyboard() {
297 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
298 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
300 fBot
.activeShell().pressShortcut(Keystrokes
.DELETE
);
301 final String DELETE_TRACE_DIALOG_TITLE
= "Confirm Delete";
302 fBot
.waitUntil(Conditions
.shellIsActive(DELETE_TRACE_DIALOG_TITLE
));
303 SWTBotShell shell
= fBot
.shell(DELETE_TRACE_DIALOG_TITLE
);
304 shell
.bot().button("Yes").click();
305 fBot
.waitUntil(Conditions
.shellCloses(shell
));
306 fBot
.waitWhile(new ConditionHelpers
.ActiveEventsEditor(fBot
, null));
307 fBot
.waitUntil(new TraceDeletedCondition());
311 * Test that the trace opens with double-click
313 * Action : Open Trace (double click)
315 * Procedure :Double-click a trace
317 * Expected Results: Trace is opened
319 * @throws WidgetNotFoundException
320 * when a widget is not found
323 public void test4_08OpenDoubleClick() throws WidgetNotFoundException
{
324 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
325 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
327 traceItem
.doubleClick();
329 testEventsTable(TRACE_NAME
);
330 testStatisticsView();
331 fBot
.closeAllEditors();
335 * Test that the trace is brought to top if already opened
337 * Action : Open Trace (already open)
339 * Procedure :Open two traces. Open the first trace again.
341 * Expected Results: The first trace editor is simply brought to front.
344 public void test4_09BringToTop() {
345 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), TRACE_TYPE
);
346 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
348 traceItem
.doubleClick();
349 fBot
.waitUntil(new ConditionHelpers
.ActiveEventsEditor(fBot
, TRACE_NAME
));
350 IEditorReference originalEditor
= fBot
.activeEditor().getReference();
352 createCopy(traceItem
);
354 SWTBotTreeItem copiedItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), RENAMED_TRACE_NAME
);
356 copiedItem
.doubleClick();
357 copiedItem
.doubleClick();
358 fBot
.waitUntil(new ConditionHelpers
.ActiveEventsEditor(fBot
, RENAMED_TRACE_NAME
));
359 SWTBotUtils
.delay(1000);
361 traceItem
.doubleClick();
362 fBot
.waitUntil(new ConditionHelpers
.ActiveEventsEditor(fBot
, TRACE_NAME
));
363 assertTrue(originalEditor
== fBot
.activeEditor().getReference());
365 fBot
.closeAllEditors();
366 SWTBotUtils
.clearTracesFolder(fBot
, TRACE_PROJECT_NAME
);
369 private static void createCopy(SWTBotTreeItem traceItem
) {
370 traceItem
.contextMenu().menu("Copy...").click();
371 final String COPY_TRACE_DIALOG_TITLE
= "Copy Trace";
372 fBot
.waitUntil(Conditions
.shellIsActive(COPY_TRACE_DIALOG_TITLE
));
373 SWTBotShell shell
= fBot
.shell(COPY_TRACE_DIALOG_TITLE
);
374 SWTBotText text
= shell
.bot().textWithLabel("New Trace name:");
375 text
.setText(RENAMED_TRACE_NAME
);
376 shell
.bot().button("OK").click();
377 fBot
.waitUntil(Conditions
.shellCloses(shell
));
380 private static void testEventsTable(String editorName
) {
381 SWTBotEditor editor
= SWTBotUtils
.activeEventsEditor(fBot
, editorName
);
382 fBot
.waitUntil(ConditionHelpers
.numberOfEventsInTrace(TmfTraceManager
.getInstance().getActiveTrace(), NB_EVENTS
));
384 SWTBotTable table
= editor
.bot().table();
385 fBot
.waitUntil(new DefaultCondition() {
387 public boolean test() throws Exception
{
388 return table
.rowCount() > 1;
392 public String
getFailureMessage() {
393 return "No items in table";
396 // Select first event (skip filter/search row)
397 table
.getTableItem(1).select();
399 editor
.bot().waitUntil(new DefaultCondition() {
401 public boolean test() throws Exception
{
402 return table
.selection().rowCount() == 1 && table
.selection().get(0).toString().contains("01:01");
406 public String
getFailureMessage() {
407 return "First event not selected";
412 private static void testStatisticsView() {
413 SWTBotUtils
.openView(TmfStatisticsView
.ID
);
414 SWTBotView view
= fBot
.viewById(TmfStatisticsView
.ID
);
415 assertTrue(view
.bot().tree().hasItems());
416 view
.bot().tree().cell(0, 1).equals(Long
.toString(NB_EVENTS
));
419 private final class TraceDeletedCondition
extends DefaultCondition
{
421 public boolean test() throws Exception
{
422 return ResourcesPlugin
.getWorkspace().getRoot().getProject(TRACE_PROJECT_NAME
).findMember(new Path("Traces/" + TRACE_NAME
)) == null;
426 public String
getFailureMessage() {
427 return TRACE_NAME
+ " was not deleted successfully.";