"Can't access dead object" 在壁虎驱动程序中
"Can't access dead object" in geckodriver
我在 Java 中使用 Selenium 3.4。使用 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")));
我已经简化了代码,所以您看不到隐式等待是如何设置回 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
还有一些 Java脚本错误输出,显然是 geckodriver:
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
此外,我的自动异常处理尝试截取屏幕截图,但由于同样的错误而失败。代码行是:
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
那么,我可以做些什么来让它正常工作吗?这是我需要作为 geckodriver 错误提出的问题吗?
我唯一能 google 的是:https://github.com/mozilla/geckodriver/issues/614 唯一提出的解决方案是 driver.switchTo().defaultContent()
。这可能会修复我的屏幕截图例程,但我正在等待的元素在内容框架内,所以我无法使用此修复来等待。
在您等待元素 some_id
时,框架似乎重新加载了新的引用。
我会将此问题归类为错误,因为驱动程序返回的错误未由 WebDriver
协议定义。
让它工作的最佳机会可能是实现一个自定义服务员来定位 frame/element 并跳过未处理的异常:
WebElement elem = waiter.Until(elementToBeClickableInFrame(By.id("contentframe"),
By.id("some_id")));
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;
}
};
}
不确定这是否对您有帮助,但是当我 运行 进入此错误消息时,我能够通过以下方式克服它:
driver.switchTo().defaultContent();
driver.switchTo().frame(0);
在与 iframe 中的元素的每次交互之间。
示例:
driver.switchTo().frame(0);
myPage.selectElement(getCycleSummary());
driver.switchTo().defaultContent();
driver.switchTo().frame(0);
myPage.selectDisplayedElement(this.getCycleBtn());
如果没有驱动程序开关,我会收到死对象错误。
看,
应该有我在下面给出的格式:
首先切换到框架。 (如果您已经在另一个框架中,请先切换到默认设置)。
执行您的操作(点击任何元素)
再次切换到默认内容。 (如果你不把它切换回来,就会产生问题)。
driver.switchTo().defaultContent();
driver.switchTo().frame(locator or name of the frame);
driver.click(your element locator);
driver.switchTo().defaultContent();
我在 Java 中使用 Selenium 3.4。使用 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")));
我已经简化了代码,所以您看不到隐式等待是如何设置回 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
还有一些 Java脚本错误输出,显然是 geckodriver:
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
此外,我的自动异常处理尝试截取屏幕截图,但由于同样的错误而失败。代码行是:
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
那么,我可以做些什么来让它正常工作吗?这是我需要作为 geckodriver 错误提出的问题吗?
我唯一能 google 的是:https://github.com/mozilla/geckodriver/issues/614 唯一提出的解决方案是 driver.switchTo().defaultContent()
。这可能会修复我的屏幕截图例程,但我正在等待的元素在内容框架内,所以我无法使用此修复来等待。
在您等待元素 some_id
时,框架似乎重新加载了新的引用。
我会将此问题归类为错误,因为驱动程序返回的错误未由 WebDriver
协议定义。
让它工作的最佳机会可能是实现一个自定义服务员来定位 frame/element 并跳过未处理的异常:
WebElement elem = waiter.Until(elementToBeClickableInFrame(By.id("contentframe"),
By.id("some_id")));
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;
}
};
}
不确定这是否对您有帮助,但是当我 运行 进入此错误消息时,我能够通过以下方式克服它:
driver.switchTo().defaultContent();
driver.switchTo().frame(0);
在与 iframe 中的元素的每次交互之间。
示例:
driver.switchTo().frame(0);
myPage.selectElement(getCycleSummary());
driver.switchTo().defaultContent();
driver.switchTo().frame(0);
myPage.selectDisplayedElement(this.getCycleBtn());
如果没有驱动程序开关,我会收到死对象错误。
看,
应该有我在下面给出的格式:
首先切换到框架。 (如果您已经在另一个框架中,请先切换到默认设置)。
执行您的操作(点击任何元素)
再次切换到默认内容。 (如果你不把它切换回来,就会产生问题)。
driver.switchTo().defaultContent(); driver.switchTo().frame(locator or name of the frame); driver.click(your element locator); driver.switchTo().defaultContent();