Skip to content

Commit 97698c4

Browse files
committed
Wait for UI to load
Signed-off-by: Adam Wisniewski <awisniew@us.ibm.com>
1 parent 7fa4694 commit 97698c4

File tree

1 file changed

+118
-41
lines changed

1 file changed

+118
-41
lines changed

tests/src/main/java/io/openliberty/tools/eclipse/test/it/utils/SWTBotPluginOperations.java

Lines changed: 118 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,17 @@ public void run() {
135135
*/
136136
public static SWTBotMenu getDebuggerConnectMenuForDebugObject(Object debugObject) {
137137
openDebugPerspective();
138-
Object windowMenu = findGlobal("Window", Option.factory().widgetClass(MenuItem.class).build());
139-
goMenuItem(windowMenu, "Show View", "Debug");
138+
// Open Debug view using Eclipse API instead of menu navigation
139+
// This is more reliable in headless CI environments
140+
showDebugView();
140141

141142
SWTBotTreeItem obj = new SWTBotTreeItem((TreeItem) debugObject);
143+
144+
// Ensure the tree item is properly selected and focused before accessing context menu
145+
// This is critical for headless CI environments where context menus can hang
146+
obj.select();
147+
obj.setFocus();
148+
MagicWidgetFinder.pause(500);
142149

143150
return obj.contextMenu("Connect Liberty Debugger");
144151
}
@@ -152,8 +159,15 @@ public static SWTBotMenu getDebuggerConnectMenuForDebugObject(Object debugObject
152159
*/
153160
public static void disconnectDebugTarget(Object debugTarget) {
154161
openDebugPerspective();
155-
Object windowMenu = findGlobal("Window", Option.factory().widgetClass(MenuItem.class).build());
156-
goMenuItem(windowMenu, "Show View", "Debug");
162+
// Open Debug view using Eclipse API instead of menu navigation
163+
// This is more reliable in headless CI environments
164+
showDebugView();
165+
166+
// Ensure proper selection before accessing context menu
167+
SWTBotTreeItem obj = new SWTBotTreeItem((TreeItem) debugTarget);
168+
obj.select();
169+
obj.setFocus();
170+
MagicWidgetFinder.pause(500);
157171

158172
MagicWidgetFinder.context(debugTarget, "Disconnect");
159173

@@ -164,34 +178,30 @@ public static void disconnectDebugTarget(Object debugTarget) {
164178
* Terminate the launch
165179
*/
166180
public static void terminateLaunch() {
167-
Display.getDefault().syncExec(new Runnable() {
168-
@Override
169-
public void run() {
170-
openDebugPerspective();
171-
Object windowMenu = findGlobal("Window", Option.factory().widgetClass(MenuItem.class).build());
172-
goMenuItem(windowMenu, "Show View", "Debug");
181+
// Don't wrap in syncExec - MagicWidgetFinder methods already handle thread synchronization
182+
// Nested syncExec calls can cause deadlocks in headless CI environments
183+
openDebugPerspective();
184+
showDebugView();
173185

174-
Object debugView = MagicWidgetFinder.findGlobal("Debug");
186+
Object debugView = MagicWidgetFinder.findGlobal("Debug");
175187

176-
Object launch = MagicWidgetFinder.find("[Liberty]", debugView,
177-
Option.factory().useContains(true).setThrowExceptionOnNotFound(false).build());
188+
Object launch = MagicWidgetFinder.find("[Liberty]", debugView,
189+
Option.factory().useContains(true).setThrowExceptionOnNotFound(false).build());
178190

179-
// Only attempt to terminate if launch exists
180-
if (launch != null) {
181-
MagicWidgetFinder.context(launch, "Terminate and Remove");
191+
// Only attempt to terminate if launch exists
192+
if (launch != null) {
193+
MagicWidgetFinder.context(launch, "Terminate and Remove");
182194

183-
try {
184-
Shell confirm = (Shell) findGlobal("Terminate and Remove", Option.factory().widgetClass(Shell.class).build());
195+
try {
196+
Shell confirm = (Shell) findGlobal("Terminate and Remove", Option.factory().widgetClass(Shell.class).build());
185197

186-
MagicWidgetFinder.go("Yes", confirm);
187-
MagicWidgetFinder.pause(3000);
188-
} catch (Exception e) {
189-
// The configrmation pop up window only shows if the launch has not yet been terminated.
190-
// If it has been terminated (or stopped), there is no confirmation.
191-
}
192-
}
198+
MagicWidgetFinder.go("Yes", confirm);
199+
MagicWidgetFinder.pause(3000);
200+
} catch (Exception e) {
201+
// The configrmation pop up window only shows if the launch has not yet been terminated.
202+
// If it has been terminated (or stopped), there is no confirmation.
193203
}
194-
});
204+
}
195205
}
196206

197207
/**
@@ -203,21 +213,37 @@ public void run() {
203213
* @return
204214
*/
205215
public static Object getObjectInDebugView(final String objectName) {
206-
final Object[] result = new Object[1];
207-
Display.getDefault().syncExec(new Runnable() {
208-
@Override
209-
public void run() {
210-
openDebugPerspective();
211-
Object windowMenu = findGlobal("Window", Option.factory().widgetClass(MenuItem.class).build());
212-
goMenuItem(windowMenu, "Show View", "Debug");
216+
// Don't wrap in syncExec - MagicWidgetFinder methods already handle thread synchronization
217+
// Nested syncExec calls can cause deadlocks in headless CI environments
218+
openDebugPerspective();
219+
showDebugView();
213220

214-
Object debugView = MagicWidgetFinder.findGlobal("Debug");
221+
Object debugView = MagicWidgetFinder.findGlobal("Debug");
215222

216-
result[0] = MagicWidgetFinder.find(objectName, debugView,
217-
Option.factory().useContains(true).setThrowExceptionOnNotFound(false).widgetClass(TreeItem.class).build());
218-
}
219-
});
220-
return result[0];
223+
// Explicitly activate the Debug view to ensure widgets are properly rendered
224+
// This is critical for headless CI environments
225+
if (debugView instanceof ViewPart) {
226+
final ViewPart vp = (ViewPart) debugView;
227+
Display.getDefault().syncExec(new Runnable() {
228+
@Override
229+
public void run() {
230+
try {
231+
IWorkbench wb = PlatformUI.getWorkbench();
232+
IWorkbenchWindow window = wb.getActiveWorkbenchWindow();
233+
if (window != null && window.getActivePage() != null) {
234+
window.getActivePage().activate(vp);
235+
}
236+
} catch (Exception e) {
237+
System.err.println("Failed to activate Debug view: " + e.getMessage());
238+
}
239+
}
240+
});
241+
// Give the view time to activate
242+
MagicWidgetFinder.pause(500);
243+
}
244+
245+
return MagicWidgetFinder.find(objectName, debugView,
246+
Option.factory().useContains(true).setThrowExceptionOnNotFound(false).widgetClass(TreeItem.class).build());
221247
}
222248

223249
/**
@@ -240,6 +266,31 @@ public void run() {
240266
Display.getDefault().syncExec(runnable);
241267
}
242268

269+
/**
270+
* Opens the Debug view using Eclipse API directly.
271+
* This is more reliable than menu navigation in headless CI environments.
272+
*/
273+
private static void showDebugView() {
274+
Display.getDefault().syncExec(new Runnable() {
275+
@Override
276+
public void run() {
277+
try {
278+
IWorkbench wb = PlatformUI.getWorkbench();
279+
IWorkbenchWindow window = wb.getActiveWorkbenchWindow();
280+
if (window != null && window.getActivePage() != null) {
281+
// Show the Debug view using its ID
282+
window.getActivePage().showView("org.eclipse.debug.ui.DebugView");
283+
}
284+
} catch (Exception e) {
285+
System.err.println("Failed to open Debug view: " + e.getMessage());
286+
e.printStackTrace();
287+
}
288+
}
289+
});
290+
// Give the view time to open
291+
MagicWidgetFinder.pause(500);
292+
}
293+
243294
public static void openJavaPerspectiveViaMenu() {
244295
Object windowMenu = findGlobal("Window", Option.factory().widgetClass(MenuItem.class).build());
245296

@@ -723,8 +774,9 @@ public static void checkRunCleanProjectCheckBox(Shell shell, String runDebugConf
723774

724775
public static Object getAppInPackageExplorerTree(String appName) {
725776
openJavaPerspectiveViaMenu();
726-
Object windowMenu = findGlobal("Window", Option.factory().widgetClass(MenuItem.class).build());
727-
goMenuItem(windowMenu, "Show View", "Package Explorer");
777+
// Open Package Explorer view using Eclipse API instead of menu navigation
778+
// This is more reliable in headless CI environments
779+
showPackageExplorerView();
728780
Object peView = MagicWidgetFinder.findGlobal("Package Explorer");
729781

730782
Object project = MagicWidgetFinder.find(appName, peView, Option.factory().useContains(true).widgetClass(TreeItem.class).build());
@@ -988,6 +1040,31 @@ public static void closeDashboardView(SWTWorkbenchBot bot) {
9881040
}
9891041
}
9901042

1043+
/**
1044+
* Opens the Package Explorer view using Eclipse API directly.
1045+
* This is more reliable than menu navigation in headless CI environments.
1046+
*/
1047+
private static void showPackageExplorerView() {
1048+
Display.getDefault().syncExec(new Runnable() {
1049+
@Override
1050+
public void run() {
1051+
try {
1052+
IWorkbench wb = PlatformUI.getWorkbench();
1053+
IWorkbenchWindow window = wb.getActiveWorkbenchWindow();
1054+
if (window != null && window.getActivePage() != null) {
1055+
// Show the Package Explorer view using its ID
1056+
window.getActivePage().showView("org.eclipse.jdt.ui.PackageExplorer");
1057+
}
1058+
} catch (Exception e) {
1059+
System.err.println("Failed to open Package Explorer view: " + e.getMessage());
1060+
e.printStackTrace();
1061+
}
1062+
}
1063+
});
1064+
// Give the view time to open
1065+
MagicWidgetFinder.pause(500);
1066+
}
1067+
9911068
/**
9921069
* Switches the Liberty run configuration main tab to the JRE Tab. A Liberty configuration must be opened prior to calling this
9931070
* method.

0 commit comments

Comments
 (0)