![](/img/trans.png)
[英]Selenium JavaScript Executor returns null for .checked but works for .click()?
[英]Selenium JavaScript executor returning null when JS works fine on Chrome console
我正在尝试使用Selenium + ChromeDriver(Java驱动)将一些文本添加到iframe的文本框中,并且在堆栈跟踪中遇到以下错误:
org.openqa.selenium.WebDriverException: unknown error: Cannot read property 'contentWindow' of null
我使用断点来确保整个DOM都已加载,因此这似乎不是问题。 我还在js.executeScript
行的断点处在Chrome控制台中测试了我的JS,它工作正常。 但是,一旦我一步步完成测试,它就会失败并显示相同的错误。 JS在Selenium中的运行方式与在Chrome控制台中的运行方式之间似乎有些差异。
这是我正在查看的DOM的一部分:
<div class="container">
<iframe class="rich-text-area" id="EmailMessage">
#document
<html>
<head>
<link rel="stylesheet" type="text/css" href="/static/css/rich-text-editor.css">
<link rel="stylesheet" type="text/css" href="/rest/email/css">
</head>
<body contenteditable="true"></body>
</html>
</iframe>
<textarea class="code" aria-hidden="true" id="emailSource" style="display: none;"> </textarea>
</div>
在Chrome控制台中运行我的JS时,它是:
document.getElementById('EmailMessage').contentWindow.document.body.appendChild(document.createTextNode('testText'));
我得到的期望结果是在body标签之间的内部HTML,例如:
<body contenteditable="true">testText</body>
但是,使用以下代码运行它时,它崩溃了,并给了我上面提到的错误。 这是运行此代码的Java代码的一部分:
JavascriptExecutor js = (JavascriptExecutor) driver;
driver.switchTo().frame(emailBodyID);
wait.until(ExpectedConditions.visibilityOfElementLocated(emailBodyTag));
wait.until(ExpectedConditions.elementToBeClickable(emailBodyTag));
js.executeScript("document.getElementById('EmailMessage').contentWindow.document.body.appendChild(document.createTextNode('testText'));");
driver.switchTo().defaultContent();
知道这里发生了什么吗? 我也尝试过contentDocument.body
。 Chrome和Selenium中的结果相同。 我将其用作sendKeys()
的替代方法,因为我被迫为此测试运行较旧版本的ChromeDriver,因为它破坏了iframe中对sendKeys()
支持。 我已经在本地计算机上使用最新的ChromeDriver尝试了此代码,但该代码仍然失败,因此似乎不是环境问题。
干杯,达尔文。
经过更多调查,看来我已经找到了答案。 问题出在driver.switchTo()
命令上。 Chrome控制台在默认页面级别解释代码,而Selenium仅从'EmailMessage'
开始查看DOM。 由于先前使用SendKeys()
这些都留在了那里。
将行重新排序为以下内容,可以使用明确的等待时间检查iframe中的元素,然后在页面级运行JS。 另一个解决方案是将JS字符串更改为从document.body...
级别开始。 我的解决方法如下:
JavascriptExecutor js = (JavascriptExecutor) driver;
driver.switchTo().frame(emailBodyID);
wait.until(ExpectedConditions.visibilityOfElementLocated(emailBodyTag));
wait.until(ExpectedConditions.elementToBeClickable(emailBodyTag));
driver.switchTo().defaultContent();
js.executeScript("document.getElementById('EmailMessage').contentWindow.document.body.appendChild(document.createTextNode('testText'));");
看起来很简单,但回头看得很明显(虽然不是全部),但是对于任何想要在iframe中切换带有某些JS的SendKeys()
的人(或执行其他任何涉及JS并在Selenium中使用iframe更改范围的操作),这可能是一个偷偷摸摸的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.