How to get testfx to find the root's fx:id in testing (the root is a custom control)

I know the way I'm loading my app is probably weird but I don't understand why the testfx suite returns an EmptyNodeQueryException for the root pane

org.testfx.service.query.EmptyNodeQueryException: there is no node in the scene-graph matching the query: NodeQuery: from nodes: [MainPane[id=mainPane, styleClass=root]],
lookup by function: "org.testfx.util.NodeQueryUtils$$Lambda$245/968514068@57829d67",
lookup by selector: "#removeScriptButton"

Some of my view components (not all, most don't have fxml documents attached to them) are made with this method:

https://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm

Though I don't use the fxml loader in the constructor, I have it in a 'createView()' method that I call from a parent class after instantiation

The root class looks like this

public class MainPane extends BorderPane implements etc{

    //declarations ...

    public MainPane(String fxmlName) {
        this.fxmlName = fxmlName;
    }

    @Override
    public void createView() {

        fxmlLoader.assign(this, fxmlName); //<-----------

        this.setCenter(mainScrollPane);
        this.setTop(mainMenuBar);
    }
}

Loader:

public class ExtendedFxmlLoader implements IFxmlLoader {
    @Override
    public void assign(Parent parent, String fileName) {

        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/" + fileName));
        fxmlLoader.setRoot(parent);
        fxmlLoader.setController(parent);

        try {
            fxmlLoader.load();
            int bp =234;
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }
}

Root's fxml doc

<fx:root fx:id="mainPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="128.0" minWidth="128.0" prefHeight="720.0" prefWidth="1280.0" type="javafx.scene.layout.BorderPane" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
   <opaqueInsets>
      <Insets />
   </opaqueInsets>
</fx:root>

The failed test (for another component)

public class RemoveScriptButtonTest extends ApplicationTest{
    private Button button;
    private RemoveScriptButton removeScriptButton;

    @Before
    public void setUpApp() throws Exception {
        ApplicationTest.launch(App.class);
    }

    @Override
    public void start(Stage stage) {
        stage.show();
    }

    @Test
    public void just_click(){

        removeScriptButton = new RemoveScriptButton(new ExtendedFxmlLoader(), "removeScriptButton.fxml");
        removeScriptButton.createView();

        button = find("#removeScriptButton");
        clickOn(button);
    }

    public <T extends Node> T find(final String query) {
        /** TestFX provides many operations to retrieve elements from the loaded GUI. */
        return lookup(query).query();
    }

    @After
    public void tearDown() throws TimeoutException {
        FxToolkit.hideStage();
        release(new KeyCode[] {});
        release(new MouseButton[] {});
    }
}

The RemoveScriptButton is also a custom control like MainPane

So I'm not sure what's going on here, should I try to change the root to a normal controller class that implements Initializable and then load it the standard way eg

Parent root = FXMLLoader.load(getClass().getResource("mainPane.fxml"));

Upvotes: 3

Views: 2104

Answers (0)

Related Questions