HtmlUnit JavaScript 回调到 Java 方法

HtmlUnit JavaScript callback to Java method

本文关键字:Java 方法 回调 JavaScript HtmlUnit      更新时间:2023-09-26

我需要使用 HtmlUnit 钩住 JavaScript 函数调用。我写过这样的东西:

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

所以。我所需要的只是在JavaScript代码中调用一些Java方法(myfunc)。可以使用HtmlUnit吗?

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;
    }
}