For the past few months I’ve been working on a JavaFX based product that has lots of bells and whistles. Last week we succeeded in setting up functional tests using TestFX. While everything was working fine on a developer’s machine (see this for more information) we were experiencing trouble with our CI environment.
At first we thought it was a faulty configuration related to xvfb on the server but as it turns out xvfb was working correctly. We even ssh’ed into the server, exported the DISPLAY to a different machine and saw the test run. Kind of. The following is the basic test code that was causing us trouble:
Clicking on #optionsMenu (a button) should bring a popup menu; clicking on #preferencesActionTarget then selects an item from the popup menu. The button is placed at the top right corner of the window.
When running the test on a local machine we can clearly see the robot clicking on all items we told it to, however the execution on the server always left the pointer at the center of the window. Aha! the problem was that the mouse pointer froze completely. The Robot was unable to move it to the right point on the screen and the click on the expected element.
Searching for clues to fix this problem led us to this thread at the TestFX Google Group. The problem discussed there was of a different nature, nevertheless the thread contained a small nugget of information:
The DragAndDropBug occurs when the GlassRobot is used without Monocle. Automatic mouse movement will freeze. — Benjamin
So we had to enable Monocle on the server. As far as we can tell there’s only one release of Monocle available at JCenter/Maven Central: 1.8.0_20. This version worked well for us although we’re running JDK8u72. Please follow the instructions laid out here if you require another version; or point that repository to jitpack.io and let it serve the binaries for you.
Assuming you’re building projects with Gradle (if not, what are you waiting for? Maven is so old school now) you only need to configure the following dependencies to have Monocle in your build
The last bit found in this file allow us to enable/disable headless mode in our tests. In this way we can use the real Glass Robot when running locally or the Monocle Robot when running on CI. Headless mode is disabled by default; it can be enabled by invoking
$ gradle -Pheadless=true test
Of course, one could tweak the build file and have the value of the headless property be set according to the current environment, that is, if the build is being executed inside the CI server or not. Once we’re done with the setup the only thing left to do is update the tests so that the correct robot is used. You’ll typically use a static initializer block to perform this feat, such as
And that’s it. There’s nothing much to it once you know what to tweak.