Selenium - java - 与js代码交互

同样需要开启bidi交互功能

ChromeOptions co = new ChromeOptions();
co.setCapability("webSocketUrl", true);  //BiDi功能需要添加这个配置
WebDriver driver = new ChromeDriver(chromeOptions);

调用js函数并获取返回值

js测试代码如下

// test.js

async ()=>{
    // 使用await 等待获取一个Promise 兑现的值
    let data = await new Promise((resolve, reject)=>{
        // 用setTimeout模拟一个异步操作, 例如一个网络请求
        // resolve将兑现值复制给data
        setTimeout(()=>resolve(JSON.stringify({"data":"123"})), 3000)
    });
    // 返回兑现值, 传给java的数据, 一个json字符串 {"data": "123"}
    return data;
}

java 代码如下

        String id = driver.getWindowHandle();
        // 创建一个Script对象
        Script script = new Script(id, driver);
        // strCode 是 test.js文件中的代码
        EvaluateResult evaluateResult = script.callFunctionInBrowsingContext(id, strCode, true,
                Optional.empty(), Optional.empty(), Optional.empty());
        
        EvaluateResult.Type resultType = evaluateResult.getResultType();

        if(resultType == EvaluateResult.Type.SUCCESS){
            EvaluateResultSuccess res = (EvaluateResultSuccess) evaluateResult;
            // getValue返回的是一个Optional对象, 里面包着这 js返回的data数据
            return res.getResult().getValue().get().toString();
        }else{
            EvaluateResultExceptionValue res = (EvaluateResultExceptionValue) evaluateResult;
            throw new RuntimeException(res.getExceptionDetails().getText());
        }

在沙盒sandbox中调用js函数

sandbox是CSP安全策略的一种方式, 类似于iframe, 会阻止一些弹出窗和可执行的插件、脚本运行。下面用一个例子直观演示下

测试js脚本如下

// testpop.js

() =>{
    window.confirm("test");  // 弹出一个模态确认框
}

以下分别用sandbox方式和不用分别执行下这个脚本

用sandbox方式会抛出异常, 大家可以自行运行体会下

// 开启sandbox选项
EvaluateResult evaluateResult = script.callFunctionInBrowsingContext(id, "sandbox" str, true,
                Optional.empty(), Optional.empty(), Optional.empty());

// 不开启sandbox
EvaluateResult evaluateResult = script.callFunctionInBrowsingContext(id, str, true,
                Optional.empty(), Optional.empty(), Optional.empty())


//开启sandbox不允许执行有弹框这种js脚本, alert除外, 所以会报异常
//不开启sandbox 可以正常执行, 并且在页面中弹出一个“确认模态框”

执行js代码

使用evaluateFunctionInBrowsingContext执行js代码 和 callFunctionInBrowsingContext 不同的是, 这个是执行一段js代码, 不可传参数, 那个是调用某个js函数 , 可以传递参数

下面演示一段相似代码看下

// test2.js


async function test(){
    let data = await new Promise((resolve, reject)=>{
        setTimeout(()=>resolve(JSON.stringify({"data":"123"})), 3000)
    });
    return data;
}

// 这里需要调用一下, 否则上面声明的函数不会执行, java代码中也获取不到data值
test();

在java中执行上面的js代码

        String id = driver.getWindowHandle();
        // 创建一个Script对象
        Script script = new Script(id, driver);

        //执行test2.js脚本
        EvaluateResult evaluateResult = script.evaluateFunctionInBrowsingContext(id, str, true,
                Optional.of(ResultOwnership.ROOT));

        EvaluateResult.Type resultType = evaluateResult.getResultType();

        if(resultType == EvaluateResult.Type.SUCCESS){
            EvaluateResultSuccess res = (EvaluateResultSuccess) evaluateResult;
            // 返回js脚本中的data值
            return (String)res.getResult().getValue().orElseGet(()->"");
        }else{
            EvaluateResultExceptionValue res = (EvaluateResultExceptionValue) evaluateResult;
            throw new RuntimeException(res.getExceptionDetails().getText());
        }
  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值