Merge remote-tracking branch 'origin/GP-0-dragonmacher-splash-screen-test-fix'

This commit is contained in:
ghidra1
2021-03-03 18:41:51 -05:00
2 changed files with 49 additions and 80 deletions
@@ -1765,8 +1765,11 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
} }
if (bestParent == null) { if (bestParent == null) {
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); bestParent = getJavaActiveWindow();
bestParent = kfm.getActiveWindow(); }
if (bestParent != null && !bestParent.isShowing()) {
bestParent = null; // don't let non-showing windows be parents
} }
return bestParent; return bestParent;
@@ -1775,8 +1778,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
private static Window getBestNonModalParent(DialogComponentProvider newProvider, private static Window getBestNonModalParent(DialogComponentProvider newProvider,
Window bestParent) { Window bestParent) {
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); Window activeWindow = getJavaActiveWindow();
Window activeWindow = kfm.getActiveWindow();
if (!(activeWindow instanceof DockingDialog)) { if (!(activeWindow instanceof DockingDialog)) {
return bestParent; return bestParent;
} }
@@ -1937,13 +1939,19 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
private static Window getJavaActiveWindow() { private static Window getJavaActiveWindow() {
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
return kfm.getActiveWindow(); Window activeWindow = kfm.getActiveWindow();
if (activeWindow == null) {
return null;
}
if (!activeWindow.isShowing()) {
return null; // don't let non-showing windows be considered active
}
return activeWindow;
} }
private static Window getActiveNonTransientWindow() { private static Window getActiveNonTransientWindow() {
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); Window bestWindow = getJavaActiveWindow();
Window bestWindow = kfm.getActiveWindow();
if (bestWindow instanceof DockingDialog) { if (bestWindow instanceof DockingDialog) {
// We do not want Task Dialogs becoming parents, as they will get closed when the // We do not want Task Dialogs becoming parents, as they will get closed when the
// task is finished, closing any other child dialogs, which means that dialogs such // task is finished, closing any other child dialogs, which means that dialogs such
@@ -30,71 +30,43 @@ import docking.*;
import docking.test.AbstractDockingTest; import docking.test.AbstractDockingTest;
import docking.widgets.PasswordDialog; import docking.widgets.PasswordDialog;
import generic.test.category.NightlyCategory; import generic.test.category.NightlyCategory;
import ghidra.util.Msg;
// The splash screen is sensitive to windows being activated/deactivated, so don't run // The splash screen is sensitive to windows being activated/deactivated, so don't run
// when other test windows may be open // when other test windows may be open
@Category(NightlyCategory.class) @Category(NightlyCategory.class)
public class SplashScreenTest extends AbstractDockingTest { public class SplashScreenTest extends AbstractDockingTest {
private AboutDialog aboutDialog;
@After @After
public void tearDown() { public void tearDown() {
Msg.debug(this, "tearDown() - open windows before closing");
printOpenWindows();
runSwing(() -> SplashScreen.disposeSplashScreen()); runSwing(() -> SplashScreen.disposeSplashScreen());
disposeAllWindows();
closeAllWindows();
printOpenWindows();
Msg.debug(this, "tearDown() - open windows after closing");
} }
@Test private void disposeAllWindows() {
public void testShowInfoWindow() throws Exception { for (Window window : getAllWindows()) {
// no parent runSwing(window::dispose);
showModalInfoWindow(null); }
ensureInfoWindowVisible();
hideInfoWindow();
// not visible parent
JFrame parentFrame = new JFrame("InfoWindowTest.testShowInfoWindow Frame");
parentFrame.setBounds(-100, -100, 0, 0);
showModalInfoWindow(parentFrame);
ensureInfoWindowVisible();
hideInfoWindow();
// visible parent
parentFrame.setVisible(true);
showModalInfoWindow(parentFrame);
ensureInfoWindowVisible();
hideInfoWindow();
} }
@Test @Test
public void testShowAndHideSplashScreen() { public void testShowAndHideSplashScreen() {
showSplashScreen(true); showSplashScreen(true);
ensureSpashScreenVisible(true); assertSpashScreenVisible(true);
showSplashScreen(false); showSplashScreen(false);
ensureSpashScreenVisible(false); assertSpashScreenVisible(false);
showSplashScreen(true); showSplashScreen(true);
ensureSpashScreenVisible(true); assertSpashScreenVisible(true);
showSplashScreen(false); showSplashScreen(false);
ensureSpashScreenVisible(false); assertSpashScreenVisible(false);
} }
@Test @Test
public void testUpdateSplashScreenStatus() { public void testUpdateSplashScreenStatus() {
showSplashScreen(true); showSplashScreen(true);
ensureSpashScreenVisible(true); assertSpashScreenVisible(true);
JLabel statusLabel = (JLabel) getInstanceField("statusLabel", SplashScreen.class); JLabel statusLabel = (JLabel) getInstanceField("statusLabel", SplashScreen.class);
@@ -120,24 +92,24 @@ public class SplashScreenTest extends AbstractDockingTest {
public void testSplashScreenPasswordModality_SharedParent() throws Exception { public void testSplashScreenPasswordModality_SharedParent() throws Exception {
showSplashScreen(true); showSplashScreen(true);
ensureSpashScreenVisible(true); assertSpashScreenVisible(true);
// show a modal dialog with no parent (this will use the Splash Screen's parent) // show a modal dialog with no parent (this will use the Splash Screen's parent)
showModalPasswordDialog(null); showModalPasswordDialog(null);
// When the splash screen and the dialog share a parent, then the dialog should NOT // When the splash screen and the dialog share a parent, then the dialog should NOT
// cause the splash screen to go away // cause the splash screen to go away
ensureSpashScreenVisible(true); assertSpashScreenVisible(true);
} }
@Test @Test
public void testSplashScreenPasswordModality_UnsharedParent() throws Exception { public void testSplashScreenPasswordModality_UnsharedParent() throws Exception {
// show the splash screen // show the splash screen
showSplashScreen(true); showSplashScreen(true);
ensureSpashScreenVisible(true); assertSpashScreenVisible(true);
DockingFrame frame = new DockingFrame("Modal Parent Frame"); DockingFrame frame = new DockingFrame("Modal Parent Frame");
frame.setVisible(true); show(frame);
showModalPasswordDialog(frame); showModalPasswordDialog(frame);
ensureSplashScreenWillClose(); ensureSplashScreenWillClose();
@@ -147,6 +119,10 @@ public class SplashScreenTest extends AbstractDockingTest {
// Private Methods // Private Methods
//================================================================================================== //==================================================================================================
private void show(JFrame frame) {
runSwing(() -> frame.setVisible(true));
}
private void ensureSplashScreenWillClose() { private void ensureSplashScreenWillClose() {
waitForCondition(() -> { waitForCondition(() -> {
SplashScreen splash = getSplash(); SplashScreen splash = getSplash();
@@ -155,42 +131,44 @@ public class SplashScreenTest extends AbstractDockingTest {
} }
private DockingDialog showModalPasswordDialog(Frame parentFrame) throws Exception { private DockingDialog showModalPasswordDialog(Frame parentFrame) throws Exception {
String dialogTitle = "InfoWindowTest.testSplashScreenPasswordModality() Dialog"; String dialogTitle = "InfoWindowTest.testSplashScreenPasswordModality() Dialog";
DialogComponentProvider passwordDialog = runSwing(() -> new PasswordDialog(dialogTitle, DialogComponentProvider passwordDialog = runSwing(() -> new PasswordDialog(dialogTitle,
"Server Type", "Server Name", "Prompt", null, null)); "Server Type", "Server Name", "Prompt", null, null));
if (parentFrame == null) {
// null means to share the parent
Object splashParent = getInstanceField("hiddenFrame", SplashScreen.class);
parentFrame = (Frame) splashParent;
}
Frame finalParent = parentFrame;
executeOnSwingWithoutBlocking( executeOnSwingWithoutBlocking(
() -> DockingWindowManager.showDialog(parentFrame, passwordDialog)); () -> {
DockingDialog dialog =
DockingDialog.createDialog(finalParent, passwordDialog, finalParent);
dialog.setVisible(true);
});
JDialog dialog = waitForJDialog(dialogTitle); JDialog dialog = waitForJDialog(dialogTitle);
assertNotNull(dialog); assertNotNull(dialog);
Window dialogWindow = SwingUtilities.windowForComponent(dialog);
Msg.debug(this, "Created modal dialog with parent: " + getTitleForWindow(dialogWindow) +
" - id: " + System.identityHashCode(dialogWindow));
return (DockingDialog) dialog; return (DockingDialog) dialog;
} }
// handles showing the modal info window, which must be done from a thread outside of the
// test thread
private void showModalInfoWindow(final JFrame parentFrame) {
// create a thread to show the modal dialog so that the current thread doesn't block
aboutDialog = runSwing(() -> new AboutDialog());
executeOnSwingWithoutBlocking(() -> DockingWindowManager.showDialog(null, aboutDialog));
}
private void showSplashScreen(final boolean makeVisible) { private void showSplashScreen(final boolean makeVisible) {
if (makeVisible) { if (makeVisible) {
SplashScreen splash = runSwing(() -> SplashScreen.showSplashScreen()); SplashScreen splash = runSwing(() -> SplashScreen.showSplashScreen());
assertNotNull("Failed showing splash screen", splash); assertNotNull("Failed showing splash screen", splash);
waitForSwing();
return; return;
} }
SplashScreen.disposeSplashScreen(); SplashScreen.disposeSplashScreen();
waitForSwing();
} }
private void ensureSpashScreenVisible(boolean visible) { private void assertSpashScreenVisible(boolean visible) {
// get the 'splashWindow' and make sure that it is not null and that it is visible // get the 'splashWindow' and make sure that it is not null and that it is visible
SplashScreen splashScreen = getSplash(); SplashScreen splashScreen = getSplash();
@@ -206,23 +184,6 @@ public class SplashScreenTest extends AbstractDockingTest {
// timing issue debug // timing issue debug
waitForCondition(() -> splashScreen.isVisible()); waitForCondition(() -> splashScreen.isVisible());
if (!splashScreen.isVisible()) {
// this can happen if other OS windows trigger the splash window to be hidden
printOpenWindows();
fail("The splash screen is not visible when expected to be so - " + splashScreen);
}
}
private void ensureInfoWindowVisible() {
// get the 'infoDialog' and make sure that it is not null and that it is visible
assertTrue("The info dialog is not visible after it was supposed to " + "have been shown.",
aboutDialog.isVisible());
}
private void hideInfoWindow() throws Exception {
runSwing(() -> aboutDialog.close());
} }
private SplashScreen getSplash() { private SplashScreen getSplash() {