Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX to monitor/record events performed on a web page

Tags:

java

javafx

I have a requirement to record events performed on a web page.

Eg. Filling registration form.

Recorder should capture the keyword entries and clicks performed on the page and play back when requested. At time same time recorder should also capture the actual element that generates the event. Say when i key in the firstName in

<input type="text" id="f_name"/>

recorder should be able to capture the id 'f_name'

I was wondering if I could use JavaFX for that!?. JavaFX is allowing me to load a page and I could detect various operations performed on the page by registering the appropriate event listeners. But it is not giving me any useful information about which element in the page has created that event.

   package test1;

import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.scene.Scene;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

public class JSTEst2 extends Application{

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        WebView webView = new WebView();
        WebEngine engine = webView.getEngine();

        engine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
            if (newState == Worker.State.SUCCEEDED) {
                //if the page is loaded

                JSObject window = (JSObject) engine.executeScript("window");
                window.setMember("app", this);
                //System.out.println(engine.executeScript("document.querySelector('body').innerHTML"));
                //engine.executeScript("document.querySelector('body').addEventListener('click', function(event) { alert(event.target.id); app.getCallBack(event.target.id);}, false);");
                engine.executeScript("document.addEventListener('click', function(event) { alert(event.target.id); app.getCallBack(event.target.id);}, false);");
            }
        });



        /*engine.loadContent(
                "<html><body>"
                + " <ul class=\"ct\">"
                + "<li id=\"first\">first</li>"
                + "<li id=\"second\">second</li>"
                + " <li id=\"third\">third</li>"
                + "</ul>"
                + "<input type=\"button\" value=\"Add <li>\" />"
                + "</body>"
                + "</html>"
        );*/

        engine.load("<my_url>");


        //String javascript = "document.querySelector('body').addEventListener('click', function(event) {  if (event.target.tagName.toLowerCase() === 'li') { console.log(event.target.id);   alert(event.target.id); }});";


        engine.setOnAlert(event -> showAlert(event.getData()));
        engine.setConfirmHandler(message -> showConfirm(message));



        //engine.executeScript(javascript);


        VBox root = new VBox();

        root.getChildren().add(webView);

        root.setStyle("-fx-padding: 10;" +

                "-fx-border-style: solid inside;" +

                "-fx-border-width: 2;" +

                "-fx-border-insets: 5;" +

                "-fx-border-radius: 5;" +

                "-fx-border-color: blue;");

        Scene scene = new Scene(root);

        primaryStage.setScene(scene);

        primaryStage.show();

    }


      private void showAlert(String message) {
            Dialog<Void> alert = new Dialog<>();
            alert.getDialogPane().setContentText(message);
            alert.getDialogPane().getButtonTypes().add(ButtonType.OK);
            alert.showAndWait();
        }

        private boolean showConfirm(String message) {
            Dialog<ButtonType> confirm = new Dialog<>();
            confirm.getDialogPane().setContentText(message);
            confirm.getDialogPane().getButtonTypes().addAll(ButtonType.YES, ButtonType.NO);
            boolean result = confirm.showAndWait().filter(ButtonType.YES::equals).isPresent();

            // for debugging:
            System.out.println(result);

            return result ;
        }

private void getCallBack(String data) {
    System.out.println("---->" + data);
}



}

When i clicked on 'firstname' input field, enter image description here

the sys out in the listener printed something like this,

WebView@90e64cf[styleClass=web-view]
javafx.scene.Scene@52fca713

which I can hardly interpret.

Is JavaFX he right approach is this case? If Yes, how do i get the required information using JavaFX?

##################UPDATE##################

I have updated the code to use executeScript() method. Now it shows the target element id in alert box, but i need to communicate it back to my java application. The logic I have in the code is not working. Any thoughts!!?

like image 621
Renjith Avatar asked Oct 28 '25 09:10

Renjith


1 Answers

To get informations about events from website, you can call methods from Javascript to your WebEngine:

WebView webView = new WebView();
WebEngine engine = webView.getEngine();

Engine.executeScript("document.cookie");

To have a 2-way communication between Javascript and Java. You have to set member for window and create method to call it in Javascript. Full working script:

import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.scene.Scene;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

public class JSTEst2 extends Application{

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        WebView webView = new WebView();
        WebEngine engine = webView.getEngine();

        engine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
            if (newState == Worker.State.SUCCEEDED) {
                //if the page is loaded

                JSObject window = (JSObject) engine.executeScript("window");
                window.setMember("app", this);
                engine.executeScript("document.addEventListener('click', function(event) { alert(event.target.id); app.getCallBack(event.target.id);}, false);");
            }
        });

        engine.load("<my_url>");
        engine.setOnAlert(event -> showAlert(event.getData()));
        engine.setConfirmHandler(message -> showConfirm(message));

        VBox root = new VBox();

        root.getChildren().add(webView);

        root.setStyle("-fx-padding: 10;" +

                "-fx-border-style: solid inside;" +

                "-fx-border-width: 2;" +

                "-fx-border-insets: 5;" +

                "-fx-border-radius: 5;" +

                "-fx-border-color: blue;");

        Scene scene = new Scene(root);

        primaryStage.setScene(scene);

        primaryStage.show();

    }


        private void showAlert(String message) {
            Dialog<Void> alert = new Dialog<>();
            alert.getDialogPane().setContentText(message);
            alert.getDialogPane().getButtonTypes().add(ButtonType.OK);
            alert.showAndWait();
        }

        private boolean showConfirm(String message) {
            Dialog<ButtonType> confirm = new Dialog<>();
            confirm.getDialogPane().setContentText(message);
            confirm.getDialogPane().getButtonTypes().addAll(ButtonType.YES, ButtonType.NO);
            boolean result = confirm.showAndWait().filter(ButtonType.YES::equals).isPresent();

            // for debugging:
            System.out.println(result);

            return result ;
        }

        public void getCallBack(String data) {
            System.out.println("---->" + data);
        }

    }

}
like image 88
Maciej Pulikowski Avatar answered Oct 29 '25 23:10

Maciej Pulikowski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!