将带有 html/Javascript 的字符串放入 selenium webdriver

Posted

技术标签:

【中文标题】将带有 html/Javascript 的字符串放入 selenium webdriver【英文标题】:put a string with html/Javascript into selenium webdriver 【发布时间】:2014-04-27 14:55:39 【问题描述】:

我在内存中有一个 html 文档作为字符串。它包含一个<script> 标记和一个操纵dom 的小脚本。我现在想将该 html 页面加载到 selenium webdriver 并在脚本操作后取回页面。由于我的 html 已经在内存中,我不太喜欢将 html 写入文件并将其加载为带有driver.get("file://path/to/file") 的文件的想法。所以问题是,是否有可能实现我想要的。

如果webdriver做不到,或许还有其他的可能?

这里有一个例子:

<html><head>
<script type="text/javascript">
function fill()
    var i = "secret"
    document.forms[0].elements[1].value=i

</script>
</head><body onload="fill()">
<form method="POST"><input type="hidden" name="he1" value="">
<input type="hidden" name="he2" value="">
</form></body></html>

显然,我希望 webdriver 执行 dom 操作并根据脚本更改表单。

注意这只是一个例子。我需要运行的实际脚本做的事情要复杂得多。

【问题讨论】:

【参考方案1】:

如果您不想在能够替换页面内容之前创建文件或加载 URL,您可以随时利用支持 HTML、CSS 和 JavaScript 的Data URLs 功能:

ChromeDriver driver = new ChromeDriver();
html_content = """
<html>
     <head></head>
     <body>
         <div>
             Hello World =)
         </div>
     </body>
</html>
"""

driver.get("data:text/html;charset=utf-8," + html_content)

【讨论】:

太酷了!超过 4 年之后,终于有人给出了一个可以解决问题的答案!谢谢:) Javascript 不会运行。 我没有验证这是否有效。范瑾能详细说一下吗? 这很聪明!在这里回答其他问题,它会失败,因为如果你有任何特殊字符,比如 ' 它会中断。 @moyang 的 base64 版本修复了这个问题。【参考方案2】:

您可以加载一个空白页面,例如:

<html></html>

然后设置为innerHTML

ChromeDriver driver = new ChromeDriver();
driver.get("file://empty-page.html");
String innerHtml = "<head>...</head><body onload="...">...</body>";
driver.executeScript("document.innerHTML = " + innerHtml);

然后在 body 上触发 load 事件

driver.executeScript("$(document.body).trigger('load');");

然后得到生成的 HTML

String result = driver.executeScript("document.body.innerHTML;");

【讨论】:

太棒了……好主意。我会尽快尝试的。 这不能保证与 IE 一起使用。 IE 对本地 HTML 文件非常情绪化,把它的玩具扔出婴儿车(因为它是安全区域,本地站点有一个特定区域) IE 有一个目的...下载 chrome ;) 它不起作用 - 我现在写入文件并再次读取它。至少有效 所有现代浏览器都支持 about:blank URI 模式。只需调用 driver.get('about:blank'); 即可加载一个空的 HTML 页面。【参考方案3】:

这段代码可以加载任何html字符串,包括js和css。

html_bs64 = base64.b64encode(innerHtml.encode('utf-8')).decode()
driver.get("data:text/html;base64," + html_bs64)

【讨论】:

感谢您的回答。我目前无法测试这个。它看起来类似于 jolancornevin 在 2 年前的回答中提出的解决方案。任何阅读本文并愿意对其进行测试的人,请报告这是否真的按预期执行了 Javascript。 嘿@luksch 我刚刚测试过,它确实有效,而且比以前的答案更好。【参考方案4】:

使用 Java Selenium 2.4.2 我使用以下内容替换现有元素的内部 html。我使用 Apache StringEscapeUtils.escapeJavaScript 来转义 HTML,因为这是内部 html 的 JavaScript 替换。

    public void replaceHTML(By by, String html) 
      WebElement e = driver.findElement(by);
      ((JavascriptExecutor) driver).executeScript("arguments[0].innerHTML='" + StringEscapeUtils.escapeJavaScript(html) + "'", e);
    

我传入的示例 html 字符串。

&lt;button type="button" onclick="alert('Hello world!')"&gt;Click Me!&lt;/button&gt;

注意事项:

由于无效,我无法使用“Lance Java”的方法 转义字符。在等号固定后添加单引号 这个问题。

我测试了“Kenneth Baltrinic”的使用建议 driver.get('about:blank');但我无法写到屏幕上 与基础文档交互。在java中我不得不使用双 引用 driver.get("about:blank")。我用 Chrome 对此进行了测试。

【讨论】:

我将对此进行测试。感谢您的回复。【参考方案5】:

只是一个小更新:escapeEcmaScrip() 在 2015 年取代了 escapeJavaScript()。

public static void main(String[] args) throws InterruptedException 
    driver = new FirefoxDriver();
    driver.get("http://dhtmlx.com/docs/products/dhtmlxTree/");
    replaceHTML(By.xpath("//*/span[text()='Supported browsers:']"), "<button type=\"button\"  onclick=\"alert('Hello World!!')\">Click Me!</button>");


 private static void replaceHTML(By by, String html) 
      WebElement e = driver.findElement(by);
     ((JavascriptExecutor) driver).executeScript("arguments[0].innerHTML='" + StringEscapeUtils.escapeEcmaScript(html) + "'", e);


【讨论】:

【参考方案6】:

你可以启动jetty embedded。然后,jetty 实例可以通过 Servlet / Handler 在内存中作为网页提供 html 字符串。

【讨论】:

没有像杀戮一样的杀戮:)

以上是关于将带有 html/Javascript 的字符串放入 selenium webdriver的主要内容,如果未能解决你的问题,请参考以下文章

发送带有希腊字符的电子邮件无法正确显示(使用HTML,Javascript,PHP)

发送带有数字的帖子数据

WebView 不加载 javascript 代码

如何将 HTML/JavaScript 从嵌入式资源加载到 winform Web 浏览器

HTML/Javascript:如何访问在带有 src 集的脚本标签中加载的 JSON 数据

istringstream将字符串放回输入并再次读取