Headless UI Testing with TestFX and JavaFX 8

JavaFX is a great UI toolkit. TestFX is a great library for testing the user interfaces written in JavaFX. Writing graphical tests with TestFX is simple and fast, but one challenge remains when you build your software using a headless build machine: how can you perform your UI tests in headless mode during your build?

Luckily, JavaFX 8 Update 20 will contain Monocle, which should allow us to run these headless tests.

First analysis using the latest beta of JDK 8u20 indicates that these tests are feasible, but require some changes in the TestFX library. We used a simple standalone JavaFX application for which we wrote a basic TestFX test class. We ran this test using the following command line options:

-Dglass.platform=Monocle
-Dmonocle.platform=Headless
-Dprism.order=sw

Unfortunately, this was not enough to make the test work. So we took a deeper look at the inner workings of TestFX and found that a working solution required the following changes:

  1. refactor a part of the TestFX code such that different implementations of the org.loadui.testfx.framework.robot.ScreenRobot interface can be used. This allowed us to make test use an other robot implementation, in this case an adapter for MonocleRobot. The current TestFX implementation relies on java.awt.Robot, which uses the system event queue to move the system cursor. This, of course, does not integrate with Monocle in headless mode.
  2. implement a ScreenRobot adapter for MonocleRobot. MonocleRobot is in internal package and thus not available via public API. In order to obtain an instance of this class, we had to call:
    Platform.runLater(new Runnable() {
       @Override
       public void run() {
          robot = com.sun.glass.ui.Application.GetApplication().createRobot();
       }
    });
    

This setup gave us a green test eventually. 🙂

Advertisements

18 thoughts on “Headless UI Testing with TestFX and JavaFX 8

  1. Im really looking forward to get the headless tests running on jenkins an on the client pcs as well. Our UI tests are currently running around 25 minutes – the pain is getting real…

  2. Pingback: JavaFX links of the week, April 28 // JavaFX News, Demos and Insight // FX Experience

  3. I want to do the exact same thing and following your steps I get ClassNotFoundException for Monocle related classes.
    I have downloaded the source, but cannot find the Monocle classes. Have they changed their mind and removed Monocle?

  4. Pingback: JavaFX testen mit Monocle | Zentriere Dich

  5. Regarding the EXCEPTION_ACCESS_VIOLATION.

    I was successful with removing all

    -fx-effect:

    in css files. We also had problems with javafx.scene.text.Text

    • For anyone else:
      I solved this by “fixing” the “fx-effect” rendering in JavaFS, i.e. so that it doesn’t work

      if (System.getProperty(“glass.platform”, “”).equals(“Monocle”)) {
      //when we are running test headless (using Monocle), the whole vm process crash with a EXCEPTION_ACCESS_VIOLATION
      //it is some problem with -fx-effect in css files. We simply mess up how Node looks up what can be styleable
      //in java fx. i.e. javafx doesn’t think that -fx-effect is a valid css function
      try {
      final Class styleablePropertiesClass = Class.forName(“javafx.scene.Node$StyleableProperties”);
      final Class cssMetaDataClass = Class.forName(“javafx.css.CssMetaData”);
      final Field propertyField = cssMetaDataClass.getDeclaredField(“property”);
      propertyField.setAccessible(true);

      Field field = styleablePropertiesClass.getDeclaredField(“STYLEABLES”);
      field.setAccessible(true);
      List origStyleables = (List) field.get(null);
      for (Object styleable : origStyleables) {
      String propValue = (String) propertyField.get(styleable);
      if (propValue.equals(“-fx-effect”)) {
      propertyField.set(styleable, propValue + “sometexttomessup”);
      }
      }
      } catch (Exception e) {
      logger.warn(“Problem when messing with css handling, you may have problem when you run headless”,e);
      }
      }

  6. The EXCEPTION_ACCESS_VIOLATION problem is related to font smoothing, see https://javafx-jira.kenai.com/browse/RT-40087.

    A workaround for this problem (fixes both the issues with javafx.scene.text.Text and “-fx-effect: …”) is to set “-Dprism.text=t2k”. I am currently using this set of options:

    -Dglass.platform=Monocle -Dmonocle.platform=Headless -Dprism.order=sw -Dprism.text=t2k -Dprism.verbose=true

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s