繁体   English   中英

当JS在Chrome控制台上正常运行时,Selenium JavaScript执行程序返回null

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM