有没有办法在 HtmlUnit 开始执行 javascript 之前转换它加载的页面

Is there a way to transform a page loaded by HtmlUnit before it starts executing javascript?

本文关键字:转换 加载 javascript HtmlUnit 执行 开始 有没有      更新时间:2023-09-26

首先,我想描述一下我提问的动机。

我有一个复杂的网页要用Selenium + HtmlUnit进行测试,它启动了不同的javascript脚本。我描述的问题应该是很常见的。

在页面上有一个按钮,jQuery在加载页面后将单击回调(单击事件处理程序)绑定到该按钮。有一个明确的等待(这是一个硒术语)使按钮在测试代码中变得可单击。因此,一旦按钮变得可点击,它就会被硒点击。但是,这通常发生在jQuery设法将单击事件处理程序附加到按钮之前。在这种情况下,硒测试失败。

我想做的是在javascript开始在页面上执行之前预处理HtmlUnit访问的网页,在页面开头注入一些<script>myownscript()</script>(以便它在该页面上的任何其他脚本之前执行)。然后,我将能够知道,控制Selenium测试代码中的某些条件,何时发生了单击事件处理程序的附加(我究竟如何做到这一点,取决于应用程序的详细信息)。如果我让 Selenium 单击按钮,将保证单击事件处理程序的存在,并且测试将按计划进一步进行 - 不会因缺少单击事件处理程序而出现错误。

让我们撇开这个想法是好是坏的问题(当然,更简单的问题只是在尝试单击有问题的按钮之前在 Selenium 测试代码中引入足够大的延迟,但随后可能会出现测试的整体持续时间问题,因为我描述的问题存在于正在测试的应用程序的许多页面上)。Selenium/HtmlUnit中是否有一些钩子允许在javascript开始在页面上执行之前预处理从服务器获取的页面,注入我描述的脚本?

在这种情况下,您可以使用 JavaScriptExecutor。您可以添加一个函数来在String script中执行任何您想要的操作。

WebElement button = driver.findElement(By.id("my-button"));
JavascriptExecutor jsExe = ((JavascriptExecutor) driver);
String script = "console.log(arguments[0].id); return arguments[0].id";
Object oj = jsExe.executeScript(script, button);
String txt = oj.toString();
System.out.println(txt);

如果您想使用 aycn 如 setTimeout(),请小心,它会立即返回。在我的回答中查看异步方法的示例:方法execute_script不要等待脚本结束返回python中硒的值