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
.integration
.swtbot
.tests
.projectexplorer
;
12 import static org
.junit
.Assert
.assertEquals
;
13 import static org
.junit
.Assert
.assertTrue
;
16 import java
.io
.IOException
;
17 import java
.util
.List
;
19 import org
.apache
.log4j
.ConsoleAppender
;
20 import org
.apache
.log4j
.Logger
;
21 import org
.apache
.log4j
.SimpleLayout
;
22 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
23 import org
.eclipse
.core
.runtime
.Path
;
24 import org
.eclipse
.jdt
.annotation
.NonNull
;
25 import org
.eclipse
.swtbot
.eclipse
.finder
.SWTWorkbenchBot
;
26 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotEditor
;
27 import org
.eclipse
.swtbot
.eclipse
.finder
.widgets
.SWTBotView
;
28 import org
.eclipse
.swtbot
.swt
.finder
.exceptions
.WidgetNotFoundException
;
29 import org
.eclipse
.swtbot
.swt
.finder
.junit
.SWTBotJunit4ClassRunner
;
30 import org
.eclipse
.swtbot
.swt
.finder
.keyboard
.Keystrokes
;
31 import org
.eclipse
.swtbot
.swt
.finder
.utils
.SWTBotPreferences
;
32 import org
.eclipse
.swtbot
.swt
.finder
.waits
.Conditions
;
33 import org
.eclipse
.swtbot
.swt
.finder
.waits
.DefaultCondition
;
34 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotShell
;
35 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTable
;
36 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotText
;
37 import org
.eclipse
.swtbot
.swt
.finder
.widgets
.SWTBotTreeItem
;
38 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomTxtTraceDefinition
;
39 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
40 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.ConditionHelpers
;
41 import org
.eclipse
.tracecompass
.tmf
.ui
.swtbot
.tests
.shared
.SWTBotUtils
;
42 import org
.eclipse
.tracecompass
.tmf
.ui
.views
.statistics
.TmfStatisticsView
;
43 import org
.eclipse
.ui
.IEditorReference
;
44 import org
.junit
.AfterClass
;
45 import org
.junit
.BeforeClass
;
46 import org
.junit
.Test
;
47 import org
.junit
.runner
.RunWith
;
49 import com
.google
.common
.collect
.ImmutableList
;
52 * SWTBot test for testing Project Explorer Trace actions (context-menus,
55 @RunWith(SWTBotJunit4ClassRunner
.class)
56 public class ProjectExplorerTraceActionsTest
{
57 private static @NonNull TestTraceInfo CUSTOM_TEXT_LOG
= new TestTraceInfo("ExampleCustomTxt.log", "Custom Text : TmfGeneric", 10, "29:52.034");
58 private static final String TRACE_PROJECT_NAME
= "test";
59 private static final String TRACE_NAME
= CUSTOM_TEXT_LOG
.getTraceName();
60 private static final String RENAMED_TRACE_NAME
= TRACE_NAME
+ 2;
62 private static File fTestFile
= null;
64 private static SWTWorkbenchBot fBot
;
66 /** The Log4j logger instance. */
67 private static final Logger fLogger
= Logger
.getRootLogger();
69 private static final File TEST_TRACES_PATH
= new File(new Path(TmfTraceManager
.getTemporaryDirPath()).append("testtraces").toOSString());
70 private static String
getPath(String relativePath
) {
71 return new Path(TEST_TRACES_PATH
.getAbsolutePath()).append(relativePath
).toOSString();
81 public static void init() throws IOException
{
82 TestDirectoryStructureUtil
.generateTraceStructure(TEST_TRACES_PATH
);
84 SWTBotUtils
.initialize();
86 // FIXME: We can't use Manage Custom Parsers > Import because it uses a native dialog. We'll still check that they show up in the dialog
87 CustomTxtTraceDefinition
[] txtDefinitions
= CustomTxtTraceDefinition
.loadAll(getPath("customParsers/ExampleCustomTxtParser.xml"));
88 txtDefinitions
[0].save();
89 /* set up test trace */
90 fTestFile
= new File(getPath(new Path("import").append(CUSTOM_TEXT_LOG
.getTracePath()).toString()));
92 assertTrue(fTestFile
.exists());
94 /* Set up for swtbot */
95 SWTBotPreferences
.TIMEOUT
= 20000; /* 20 second timeout */
96 SWTBotPreferences
.KEYBOARD_LAYOUT
= "EN_US";
97 fLogger
.removeAllAppenders();
98 fLogger
.addAppender(new ConsoleAppender(new SimpleLayout(), ConsoleAppender
.SYSTEM_OUT
));
99 fBot
= new SWTWorkbenchBot();
101 /* Close welcome view */
102 SWTBotUtils
.closeView("Welcome", fBot
);
104 /* Switch perspectives */
105 SWTBotUtils
.switchToTracingPerspective();
107 /* Finish waiting for eclipse to load */
108 SWTBotUtils
.waitForJobs();
109 SWTBotUtils
.createProject(TRACE_PROJECT_NAME
);
113 * Test class tear down method.
116 public static void tearDown() {
117 SWTBotUtils
.deleteProject(TRACE_PROJECT_NAME
, fBot
);
118 fLogger
.removeAllAppenders();
122 * Test that the expected context menu items are there
124 * Action : Trace menu
126 * Procedure :Select an LTTng trace and open its context menu
128 * Expected Results: Correct menu opens (Open , Copy, Rename, …)
132 public void test4_01ContextMenuPresence() {
133 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), CUSTOM_TEXT_LOG
.getTraceType());
134 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
136 final List
<String
> EXPECTED_MENU_LABELS
= ImmutableList
.of("Open", "Open With", "", "Copy...", "Rename...", "Delete", "", "Delete Supplementary Files...", "", "Export Trace Package...", "", "Select Trace Type...", "", "Apply Time Offset...",
137 "Clear Time Offset", "", "Refresh");
138 List
<String
> menuItems
= traceItem
.contextMenu().menuItems();
139 assertEquals(EXPECTED_MENU_LABELS
, menuItems
);
141 fBot
.closeAllEditors();
145 * Test that the trace opens with the context menu
147 * Action : Open trace
149 * Procedure :Select the Open menu
151 * Expected Results: Trace is opened and views are populated
155 public void test4_02Open() {
156 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), CUSTOM_TEXT_LOG
.getTraceType());
157 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
159 traceItem
.contextMenu().menu("Open").click();
160 testEventsTable(TRACE_NAME
);
161 testStatisticsView();
162 fBot
.closeAllEditors();
166 * Test that the trace can be copied with the context menu
168 * Action : Copy trace
170 * Procedure :Select the Copy menu and provide a new name. Open.
172 * Expected Results: Trace is replicated under the new name
176 public void test4_03Copy() {
177 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), CUSTOM_TEXT_LOG
.getTraceType());
178 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
180 createCopy(traceItem
);
182 fBot
.closeAllEditors();
183 SWTBotTreeItem copiedItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), RENAMED_TRACE_NAME
);
184 copiedItem
.contextMenu().menu("Open").click();
185 testEventsTable(RENAMED_TRACE_NAME
);
186 fBot
.closeAllEditors();
187 SWTBotUtils
.clearTracesFolderUI(fBot
, TRACE_PROJECT_NAME
);
191 * Test that the trace can be renamed with the context menu
193 * Action : Rename trace
195 * Procedure :Select the Rename menu and provide a new name. Reopen.
197 * Expected Results: Trace is renamed. The trace editor is closed.
200 public void test4_04Rename() {
201 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), CUSTOM_TEXT_LOG
.getTraceType());
202 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
204 traceItem
.contextMenu().menu("Rename...").click();
205 final String RENAME_TRACE_DIALOG_TITLE
= "Rename Trace";
206 fBot
.waitUntil(Conditions
.shellIsActive(RENAME_TRACE_DIALOG_TITLE
));
207 SWTBotShell shell
= fBot
.shell(RENAME_TRACE_DIALOG_TITLE
);
208 SWTBotText text
= shell
.bot().textWithLabel("New Trace name:");
209 text
.setText(RENAMED_TRACE_NAME
);
210 shell
.bot().button("OK").click();
211 fBot
.waitUntil(Conditions
.shellCloses(shell
));
212 fBot
.waitWhile(new ConditionHelpers
.ActiveEventsEditor(fBot
, null));
214 SWTBotTreeItem copiedItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), RENAMED_TRACE_NAME
);
215 copiedItem
.contextMenu().menu("Open").click();
216 testEventsTable(RENAMED_TRACE_NAME
);
217 fBot
.closeAllEditors();
218 SWTBotUtils
.clearTracesFolderUI(fBot
, TRACE_PROJECT_NAME
);
222 * Test that the trace can be deleted with the context menu
224 * Action : Delete trace
226 * Procedure :Select the Delete menu and confirm deletion
228 * Expected Results: Trace is deleted. The trace editor is closed.
232 public void test4_05Delete() {
233 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), CUSTOM_TEXT_LOG
.getTraceType());
234 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
236 traceItem
.contextMenu().menu("Delete").click();
237 final String DELETE_TRACE_DIALOG_TITLE
= "Confirm Delete";
238 fBot
.waitUntil(Conditions
.shellIsActive(DELETE_TRACE_DIALOG_TITLE
));
239 SWTBotShell shell
= fBot
.shell(DELETE_TRACE_DIALOG_TITLE
);
240 shell
.bot().button("Yes").click();
241 fBot
.waitUntil(Conditions
.shellCloses(shell
));
242 fBot
.waitWhile(new ConditionHelpers
.ActiveEventsEditor(fBot
, null));
243 fBot
.waitUntil(new TraceDeletedCondition());
247 * Test that the trace opens with the keyboard
249 * Action : Open Trace (Accelerator)
251 * Procedure :Select trace and press Enter
253 * Expected Results: Trace is opened
256 * @throws WidgetNotFoundException
257 * when a widget is not found
260 public void test4_06OpenKeyboard() throws WidgetNotFoundException
{
261 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), CUSTOM_TEXT_LOG
.getTraceType());
262 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
264 fBot
.activeShell().pressShortcut(Keystrokes
.CR
);
266 testEventsTable(TRACE_NAME
);
267 testStatisticsView();
268 fBot
.closeAllEditors();
272 * Test that the trace can be deleted with the keyboard
274 * Action : Delete Trace (Accelerator)
276 * Procedure :Select trace and press Delete and confirm deletion
278 * Expected Results: Trace is deleted. The trace editor is closed.
281 public void test4_07DeleteKeyboard() {
282 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), CUSTOM_TEXT_LOG
.getTraceType());
283 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
285 fBot
.activeShell().pressShortcut(Keystrokes
.DELETE
);
286 final String DELETE_TRACE_DIALOG_TITLE
= "Confirm Delete";
287 fBot
.waitUntil(Conditions
.shellIsActive(DELETE_TRACE_DIALOG_TITLE
));
288 SWTBotShell shell
= fBot
.shell(DELETE_TRACE_DIALOG_TITLE
);
289 shell
.bot().button("Yes").click();
290 fBot
.waitUntil(Conditions
.shellCloses(shell
));
291 fBot
.waitWhile(new ConditionHelpers
.ActiveEventsEditor(fBot
, null));
292 fBot
.waitUntil(new TraceDeletedCondition());
296 * Test that the trace opens with double-click
298 * Action : Open Trace (double click)
300 * Procedure :Double-click a trace
302 * Expected Results: Trace is opened
304 * @throws WidgetNotFoundException
305 * when a widget is not found
308 public void test4_08OpenDoubleClick() throws WidgetNotFoundException
{
309 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), CUSTOM_TEXT_LOG
.getTraceType());
310 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
312 traceItem
.doubleClick();
314 testEventsTable(TRACE_NAME
);
315 testStatisticsView();
316 fBot
.closeAllEditors();
320 * Test that the trace is brought to top if already opened
322 * Action : Open Trace (already open)
324 * Procedure :Open two traces. Open the first trace again.
326 * Expected Results: The first trace editor is simply brought to front.
329 public void test4_09BringToTop() {
330 SWTBotUtils
.openTrace(TRACE_PROJECT_NAME
, fTestFile
.getAbsolutePath(), CUSTOM_TEXT_LOG
.getTraceType());
331 SWTBotTreeItem traceItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), TRACE_NAME
);
333 traceItem
.doubleClick();
334 fBot
.waitUntil(new ConditionHelpers
.ActiveEventsEditor(fBot
, TRACE_NAME
));
335 IEditorReference originalEditor
= fBot
.activeEditor().getReference();
337 createCopy(traceItem
);
339 SWTBotTreeItem copiedItem
= SWTBotUtils
.getTraceProjectItem(fBot
, SWTBotUtils
.selectTracesFolder(fBot
, TRACE_PROJECT_NAME
), RENAMED_TRACE_NAME
);
341 copiedItem
.doubleClick();
342 copiedItem
.doubleClick();
343 fBot
.waitUntil(new ConditionHelpers
.ActiveEventsEditor(fBot
, RENAMED_TRACE_NAME
));
344 SWTBotUtils
.delay(1000);
346 traceItem
.doubleClick();
347 fBot
.waitUntil(new ConditionHelpers
.ActiveEventsEditor(fBot
, TRACE_NAME
));
348 assertTrue(originalEditor
== fBot
.activeEditor().getReference());
350 fBot
.closeAllEditors();
351 SWTBotUtils
.clearTracesFolderUI(fBot
, TRACE_PROJECT_NAME
);
354 private static void createCopy(SWTBotTreeItem traceItem
) {
355 traceItem
.contextMenu().menu("Copy...").click();
356 final String COPY_TRACE_DIALOG_TITLE
= "Copy Trace";
357 fBot
.waitUntil(Conditions
.shellIsActive(COPY_TRACE_DIALOG_TITLE
));
358 SWTBotShell shell
= fBot
.shell(COPY_TRACE_DIALOG_TITLE
);
359 SWTBotText text
= shell
.bot().textWithLabel("New Trace name:");
360 text
.setText(RENAMED_TRACE_NAME
);
361 shell
.bot().button("OK").click();
362 fBot
.waitUntil(Conditions
.shellCloses(shell
));
365 private static void testEventsTable(String editorName
) {
366 SWTBotEditor editor
= SWTBotUtils
.activeEventsEditor(fBot
, editorName
);
367 fBot
.waitUntil(ConditionHelpers
.numberOfEventsInTrace(TmfTraceManager
.getInstance().getActiveTrace(), CUSTOM_TEXT_LOG
.getNbEvents()));
369 SWTBotTable table
= editor
.bot().table();
370 fBot
.waitUntil(new DefaultCondition() {
372 public boolean test() throws Exception
{
373 return table
.rowCount() > 1;
377 public String
getFailureMessage() {
378 return "No items in table";
381 // Select first event (skip filter/search row)
382 table
.getTableItem(1).select();
384 editor
.bot().waitUntil(new DefaultCondition() {
386 public boolean test() throws Exception
{
387 return table
.selection().rowCount() == 1 && table
.selection().get(0).toString().contains(CUSTOM_TEXT_LOG
.getFirstEventTimestamp());
391 public String
getFailureMessage() {
392 return "First event not selected";
397 private static void testStatisticsView() {
398 SWTBotUtils
.openView(TmfStatisticsView
.ID
);
399 SWTBotView view
= fBot
.viewById(TmfStatisticsView
.ID
);
400 assertTrue(view
.bot().tree().hasItems());
401 view
.bot().tree().cell(0, 1).equals(Long
.toString(CUSTOM_TEXT_LOG
.getNbEvents()));
404 private final class TraceDeletedCondition
extends DefaultCondition
{
406 public boolean test() throws Exception
{
407 return ResourcesPlugin
.getWorkspace().getRoot().getProject(TRACE_PROJECT_NAME
).findMember(new Path("Traces/" + TRACE_NAME
)) == null;
411 public String
getFailureMessage() {
412 return TRACE_NAME
+ " was not deleted successfully.";