在geckodriver中“无法访问死对象”

时间:2017-05-16 15:00:27

标签: 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")));

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

wait中有相应的消息:

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

显然,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

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

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错误吗?

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

3 个答案:

答案 0 :(得分:2)

在等待元素** describe('LoginComponent', () => { let component: LoginComponent; let UserService:UserService; let fixture: ComponentFixture<LoginComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ LoginComponent ], providers: [ { provide: UserService, useValue: UserService }, ] }) it('should call the login method from the UserService', inject([TestBed, UserService], fakeAsync((tcb: TestBed, mockUserService: UserService) => { spyOn(mockUserService, 'login'); tcb .createComponent(LoginComponent) .then((fixture: ComponentFixture<LoginComponent>) => { tick(); fixture.detectChanges(); expect(mockUserService.login).toHaveBeenCalled(); }); })) ); }); ** 时,看起来框架会重新加载新引用。 我会将此问题归类为错误,因为驱动程序返回的错误未由some_id协议定义。

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

WebDriver
WebElement elem = waiter.Until(elementToBeClickableInFrame(By.id("contentframe"),
                                                           By.id("some_id")));

答案 1 :(得分:1)

不确定这是否对您有帮助,但是当我遇到此错误消息时,我可以通过以下方法克服它:

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());

没有驱动程序开关,我将收到死对象错误。

答案 2 :(得分:0)

看到,

我应该在下面提供一种格式:

  1. 首先切换到框架。 (如果您已经在另一帧中,请先切换到默认设置。)

  2. 执行操作(单击任何元素)

  3. 再次切换到默认内容。 (如果不将其切换回,则会产生问题)。

         driver.switchTo().defaultContent();
    
         driver.switchTo().frame(locator or name of the frame);
    
    
         driver.click(your element locator);
    
    
         driver.switchTo().defaultContent();