1

I need to hook JavaScript function calling using HtmlUnit. I have wrote something like:

var orgSetInterval = window.setInterval;
window.setInterval = function(p1, p2)
{
   myfunc(p1,p2);
   orgSetInterval(p1, p2);
}

So. All I need is to call some Java method (myfunc) within JavaScript code. Is it possible using HtmlUnit?

2
  • 1
    So let me see if I got this right. You want to call a Java method from a JavaScript function using HTMLUnit? I guess the obvious question at this point is: Do you have access to the server's code? Where are you hosting that piece of JavaScript? Commented Nov 3, 2013 at 22:18
  • No. Im developing client application using HtmlUnit. Target is to make automaticly actions on web site. Web site using setInterval func to updates it owns data. My application needed to hook to this event and process it (using pure Java code). that simple) Commented Nov 3, 2013 at 22:27

1 Answer 1

1
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.LoggerFactory;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.javascript.AbstractJavaScriptEngine;
import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
import com.gargoylesoftware.htmlunit.javascript.PostponedAction;
import com.gargoylesoftware.htmlunit.javascript.configuration.JavaScriptConfiguration;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import me.jc.amazing.core.util.ReflectUtil;
import me.jc.amazing.core.util.Strings;
import me.jc.amazing.web.util.RspMsgUtil;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
import net.sourceforge.htmlunit.corejs.javascript.annotations.JSConstructor;
import net.sourceforge.htmlunit.corejs.javascript.annotations.JSFunction;
import net.sourceforge.htmlunit.corejs.javascript.annotations.JSGetter;

public class TestHtmlUnitDriver {
    public static void main(String[] args) {
        HtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.CHROME, true);
        // WebDriver driver = new HtmlUnitDriver(BrowserVersion.CHROME,true);
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        loggerContext.getLogger("com.gargoylesoftware.htmlunit").setLevel(Level.valueOf("ERROR"));
        ((HtmlUnitDriver) driver).setJavascriptEnabled(true);

        try {



            driver.get("https://www.baidu.com");

            (new WebDriverWait(driver, 10, 500)).until(new ExpectedCondition<Boolean>() {
                public Boolean apply(WebDriver d) {

                    Context ctx = Context.getCurrentContext();
                    //Scriptable scope = ctx.initStandardObjects();
                    try {
                        WebWindow window = (WebWindow) ReflectUtil.invokeMethod(d, "getCurrentWindow");
                        Scriptable scope = window.getScriptableObject();
                        ScriptableObject.defineClass(scope, Counter.class);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    //Scriptable testCounter = ctx.newObject(scope, "Counter");
                    System.out.println(((JavascriptExecutor) driver).executeScript("return new Counter(123312).getCount()"));;
                    Object element = ((JavascriptExecutor) driver)
                            .executeScript("return document.getElementsByTagName(\"html\")");
                    System.out.println(element);
                    return element != null;
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }
        driver.quit();
        // JavascriptExecutor javascript = (JavascriptExecutor) driver;
        // Object obj = javascript.executeScript("return
        // document.getElementsByTagName(\"html\")");
        // Object obj =
        // ((HtmlUnitDriver)driver).executeScript("document.getElementsByTagName(\"html\")");
        // System.out.println(obj);
    }

    public static class Counter extends ScriptableObject {
        private static final long serialVersionUID = 438270592527335642L;

        // The zero-argument constructor used by Rhino runtime to create instances
        public Counter() {
        }

        // @JSConstructor annotation defines the JavaScript constructor
        @JSConstructor
        public Counter(int a) {
            count = a;
        }

        // The class name is defined by the getClassName method
        @Override
        public String getClassName() {
            return "Counter";
        }

        // The method getCount defines the count property.
        @JSGetter
        @JSFunction
        public int getCount() {
            return count++;
        }

        // Methods can be defined the @JSFunction annotation.
        // Here we define resetCount for JavaScript.
        @JSFunction
        public void resetCount() {
            count = 0;
        }

        private int count;
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.