How to write multiple tests for the same stage / scene that close the stage (ok / cancel dialog)

825 views
Skip to first unread message

Lane Feltis

unread,
Feb 26, 2014, 5:35:54 PM2/26/14
to testfx-...@googlegroups.com
Hey,

So I have this scene that allows a user to configure a timezone. For simplicity, let's say that the only controls on this view are a drop down with the possible timezones, an ok button and a cancel button. To test this class, I want to write 2 tests: one that changes the timezone and clicks ok and one that changes the timezone and clicks cancel. In my controller, I have a method "setStage(Stage stage)" so that when a controller needs to create this view, it can set a reference to the newly created stage so that the controller can call stage.close() in the ok and cancel handlers at the end (or I can use ((Stage)((Node)(event.getSource())).getScene().getWindow()).close();). The problem is that when I do this and use the protected stage variable in GuiTest, the view closes after the first test and then the second test does not open it again. I assume this scenario happens a lot and I am wondering how to handle this correctly? 

I have tried the following...

- Setup onCloseRequest and consume the event
- Setup onHiding and consume the event
- Put each test in it's own separate class
- Create a new scene using the parent after each test
- Set the stage to null

...and a few other attempts, but none of them work. I have resorted to having a global variable "isTesting" and checking that before closing my stage. This is awful and I'd like to figure out how to run several tests against a scene where some of the functionality of that scene causes the stage to close.

Thanks,
Lane

tbeernot

unread,
Feb 27, 2014, 1:06:46 AM2/27/14
to testfx-...@googlegroups.com
I've written several date pickers for JavaFX with tests on them. What I do not understand is why you would need to access the stage at all.

Tom
--
You received this message because you are subscribed to the Google Groups "TestFX" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testfx-discus...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Lane Feltis

unread,
Feb 27, 2014, 1:34:09 PM2/27/14
to testfx-...@googlegroups.com
When a user clicks the settings button, I open the dialog as follows...

onClick() {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(ResourceUtility.getInstance().getResource("views/TimeZoneDialog.fxml"));
fxmlLoader.load();

// Set background outside the new dialog to transparent black (modal UX)
stage.getScene().getRoot().setOpacity(0.2);
stage.getScene().setFill(Paint.valueOf("BLACK"));

// Create new stage to contain the dialog
Stage timeZoneDialogStage = new Stage();
timeZoneDialogStage.initModality(Modality.APPLICATION_MODAL);
timeZoneDialogStage.initStyle(StageStyle.UNDECORATED);
timeZoneDialogStage.initOwner(stage);
timeZoneDialogStage.centerOnScreen();
timeZoneDialogStage.setScene(new Scene(fxmlLoader.getRoot()));
timeZoneDialogStage.showAndWait();

// Set background back to what it was before
stage.getScene().getRoot().setOpacity(1);
stage.getScene().setFill(null);
}

...this is in a controller class (implements Initializable) and when we created the stage for its scene, we got the controller and called setStage on it so we can do things like have a button that causes it to go to / from full screen, etc. Are you suggesting to have only one instance of the stage for the modal dialog and use something like toFront and toBack instead?

Lane Feltis

unread,
Feb 27, 2014, 8:10:07 PM2/27/14
to testfx-...@googlegroups.com
Ok, so I figured this out myself. The problem was that in my dialog test class... in the getRootNode override... I was opening the dialog FXML file directly as the root (bypassing the main stage that is used to open the dialog). In general, it seems that Java FX does not expect you to call "close()" on the main stage because that essentially signals the end of the application (and this will happen naturally when a user exists the application or the test run ends). So, I still want and need to call "close()" on my dialog FXML. So what I did is keep my code as is below, creating a new stage every time I open the dialog, but now in all my tests I start with the same exact FXML file that my Application opens. Instead of starting to test the dialog immediately, I first need to "browse" to it from my main stage and now everything works!
Reply all
Reply to author
Forward
0 new messages