1

I am using https://github.com/TestFX/TestFX for gui tests of a javafx client. With a testfx query I get the comboBox but I cannot get its text for verification. The comboBox displays enum values whose text is resolved by a converter and a given resource bundle. The scene graph for the comboBox looks like that:

javafx.scene.control.ComboBox
    javafx.scene.layout.StackPane:arrow-button
        javafx.scene.layout.Region:arrow
    com.sun.javafx.scene.control.skin.ComboBoxListViewSkin$4$1:null
        com.sun.javafx.scene.control.skin.LabeledText:null

comboBox.getValue() gives me only the enum value but not the text (I could verify the enum value but since it is a gui test the displayed text should be verified). By trying out I found out that comboBox.getChildrenUnmodifiable().toString() prints

[StackPane[id=arrow-button, styleClass=arrow-button], ComboBoxListViewSkin$5[id=list-view, styleClass=list-view], ComboBoxListViewSkin$4$1@4f65f1d7[styleClass=cell indexed-cell list-cell]'StringOfInterest']

The string 'StringOfInterest' at the end is exactly what I need but it is unclear where it comes from. By looking into the source code of javafx it seems that Node#toString is being used. However, it is unclear where the last part ('StringOfInterest') comes from. I tried to get the text of all children of the ComboBox but the string in question is not part of it.

How can I extract the string?

Konter
  • 11
  • 3
  • Why don't you use the converter and the value to see what the string is? – matt Mar 07 '16 at 07:28
  • Because it is a test and the converter itself could contain an error. In that case I would not detect the problem. – Konter Mar 07 '16 at 07:44
  • If the converter contained an error, then comparing the expected value to the converter value is what you should be comparing. Otherwise it sounds like you are testing whether the converter is actually being used to create the String. – matt Mar 07 '16 at 07:51
  • Yes, the converter is in fact part of the gui and as such I would like to know whether the **displayed** values match the expected ones. I could use the converter to convert the enum to a text and compare it with the expected value. But that would mean testing the converter which would be (and is) a separate unit test. – Konter Mar 07 '16 at 08:00
  • Did you try `Combobox#getEditor`? It should return the `TextField` used to enter text (and presumably display it too) – Itai Mar 07 '16 at 08:01
  • I tried that and it works for editable comboBoxes but not for not-editable ones. – Konter Mar 07 '16 at 08:14
  • If you have tested the converter independently to verify it works correctly, and you have tested the value returned by the combo box to verify it is equal to the expected value, then the only source of error would be that the combo box isn't using the converter. So you're effectively trying to test the JavaFX library classes, not your own code, which isn't really the point of a test framework. That said, and I haven't tried this, can you do `comboBox.getButtonCell().getText()`? – James_D Mar 07 '16 at 14:08
  • Sorry for the late response. `comboBox.getButtonCell().getText()` does return an empty string. Even with separate tests for the converter and CombBox it could still be that the developer forgot to add the converter to the comboBox. That would not be an javaFx issue. – Konter Mar 08 '16 at 16:07

1 Answers1

2

I found a way to get the text on the combobox using TestFX 4 and JavaFX 12. Not sure if the below works on other versions as well. Admittedly, it feels a bit hacky and brittle, but it gives me the desired result.

ComboBox<String> comboBox = robot.lookup("#comboBox").queryComboBox();
ListCell<String> listCell = robot
    .from(comboBox)
    .lookup((Node node) -> node.getStyleClass().contains("list-cell") 
        && node.getParent() instanceof ComboBox)
    .<ListCell<String>>query();

I first tried to just lookup(".list-cell"), but that actually gave me two results, one with null as text and one with the desired text. The one with null is nested somewhere in the scene graph, but the one we are interested in has the combobox as parent. And that's what the lookup checks.

You can now verify the text of your combobox:

assertThat(listCell.getText()).isEqualTo("expected text");
Lienhart Woitok
  • 426
  • 3
  • 10