在geckodriver中"无法访问死对象"

Mik*_*dik 8 java selenium geckodriver

我正在使用Selenium 3.4和Java.使用Chrome,一切正常.但是我需要使用Firefox,并且有些东西会中断.

我正在自动测试Dojo UI,并且需要等待Dojo UI进行大量渲染.所以这就是我所做的,它在Chrome中运行得很好.请注意,通常在我的代码中设置隐式等待20秒.

driver.switchTo().defaultContent();
driver.switchTo().frame(driver.findElement(By.id("contentframe"))); // relying on implicit wait 
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
(new WebDriverWait(driver, 120)).
     until(ExpectedConditions.elementToBeClickable(By.id("some_id")));
Run Code Online (Sandbox Code Playgroud)

我已经简化了代码,因此您不会看到隐式等待如何设置回20秒.当问题发生时,无论如何它都无法到达那里.WebDriverWait导致异常.例外说TypeError: can't access dead object

等待中有相应的消息:

May 16, 2017 3:36:11 PM org.openqa.selenium.support.ui.ExpectedConditions findElement
WARNING: WebDriverException thrown by findElement(By.id: 
some_id)
org.openqa.selenium.WebDriverException: TypeError: can't access dead object
Run Code Online (Sandbox Code Playgroud)

显然,geckodriver还有一些JavaScript错误输出:

JavaScript error: chrome://marionette/content/listener.js, line 1555: TypeError: can't access dead object
*************************
A coding exception was thrown and uncaught in a Task.

Full message: TypeError: can't access dead object
Full stack: find_@chrome://marionette/content/element.js:284:7
element.find/</findElements<@chrome://marionette/content/element.js:255:15
implicitlyWaitFor/</elementSearch@chrome://marionette/content/element.js:600:15
implicitlyWaitFor/<@chrome://marionette/content/element.js:627:5
implicitlyWaitFor@chrome://marionette/content/element.js:593:10
element.find/<@chrome://marionette/content/element.js:254:24
element.find@chrome://marionette/content/element.js:253:10
findElementsContent@chrome://marionette/content/listener.js:1314:19
TaskImpl_run@resource://gre/modules/Task.jsm:319:42
TaskImpl@resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction@resource://gre/modules/Task.jsm:252:14
Task_spawn@resource://gre/modules/Task.jsm:166:12
TaskImpl_handleResultValue@resource://gre/modules/Task.jsm:389:16
TaskImpl_run@resource://gre/modules/Task.jsm:327:15
TaskImpl@resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction@resource://gre/modules/Task.jsm:252:14
Task_spawn@resource://gre/modules/Task.jsm:166:12
dispatch/<@chrome://marionette/content/listener.js:186:15

*************************
*************************
A coding exception was thrown and uncaught in a Task.

Full message: TypeError: can't access dead object
Full stack: find_@chrome://marionette/content/element.js:284:7
element.find/</findElements<@chrome://marionette/content/element.js:255:15
implicitlyWaitFor/</elementSearch@chrome://marionette/content/element.js:600:15
implicitlyWaitFor/<@chrome://marionette/content/element.js:627:5
implicitlyWaitFor@chrome://marionette/content/element.js:593:10
element.find/<@chrome://marionette/content/element.js:254:24
element.find@chrome://marionette/content/element.js:253:10
findElementsContent@chrome://marionette/content/listener.js:1314:19
TaskImpl_run@resource://gre/modules/Task.jsm:319:42
TaskImpl@resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction@resource://gre/modules/Task.jsm:252:14
Task_spawn@resource://gre/modules/Task.jsm:166:12
TaskImpl_handleResultValue@resource://gre/modules/Task.jsm:389:16
TaskImpl_run@resource://gre/modules/Task.jsm:327:15
TaskImpl@resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction@resource://gre/modules/Task.jsm:252:14
Task_spawn@resource://gre/modules/Task.jsm:166:12
dispatch/<@chrome://marionette/content/listener.js:186:15
Run Code Online (Sandbox Code Playgroud)

此外,我的自动异常处理试图截取屏幕截图,但失败时出现同样的错误.代码行是:

File snapshotTempFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); 而这次geckodriver的输出是:

A coding exception was thrown and uncaught in a Task.

Full message: TypeError: can't access dead object
Full stack: capture.viewport@chrome://marionette/content/capture.js:65:7
takeScreenshot@chrome://marionette/content/listener.js:1782:14
dispatch/</req<@chrome://marionette/content/listener.js:188:22
TaskImpl_run@resource://gre/modules/Task.jsm:319:42
TaskImpl@resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction@resource://gre/modules/Task.jsm:252:14
Task_spawn@resource://gre/modules/Task.jsm:166:12
dispatch/<@chrome://marionette/content/listener.js:186:15
Run Code Online (Sandbox Code Playgroud)

那么,我可以做任何事情来使这项工作正常吗?这是我需要提出的作为geckodriver bug的东西吗?

我唯一可以谷歌出来的是:https://github.com/mozilla/geckodriver/issues/614,这是唯一提出的解决方案driver.switchTo().defaultContent().这可能会修复我的截图例程,但我正在等待的元素在内容框架内,所以我不能使用此修复程序进行等待.

Flo*_* B. 3

当您等待元素时,框架似乎已使用新引用重新加载some_id。我将此问题归类为错误,因为驱动程序返回的错误不是由WebDriver协议定义的。

让它工作的最好机会可能是实现一个自定义服务员来定位框架/元素并跳过未处理的异常:

WebElement elem = waiter.Until(elementToBeClickableInFrame(By.id("contentframe"),
                                                           By.id("some_id")));
Run Code Online (Sandbox Code Playgroud)
public static ExpectedCondition<WebElement> elementToBeClickableInFrame(final By locatorFrame, final By locator) {
  return new ExpectedCondition<WebElement>() {

    @Override
    public WebElement apply(WebDriver driver) {
      try {

        driver.switchTo().defaultContent();
        driver.switchTo().frame(driver.findElement(locatorFrame));

        WebElement elem = driver.findElement(locator);
        return elem.isDisplayed() && elem.isEnabled() ? elem : null;

      } catch (Exception e) {
        return null;
      }
    }

    @Override
    public String toString() {
      return "element located by: " + locator + " in " + locatorFrame;
    }
  };
}
Run Code Online (Sandbox Code Playgroud)