2017-05-16 2 views
1

Ich verwende Selenium 3.4 mit Java. Mit Chrome funktioniert alles einwandfrei. Aber ich muss Firefox benutzen, und da bricht etwas."Kann nicht auf totes Objekt zugreifen" in geckodriver

Ich automatisiere das Testen einer Dojo-Benutzeroberfläche und muss warten, während die Dojo-Benutzeroberfläche eine Menge Rendering durchführt. Also, hier ist, was ich tue, und es funktioniert gut in Chrome. Beachten Sie, dass normalerweise eine implizite Wartezeit von 20 Sekunden in meinem Code festgelegt ist.

Ich habe den Code vereinfacht, damit Sie nicht sehen, wie die implizite Wartezeit auf 20 Sekunden zurückgesetzt wird. Wenn das Problem auftritt, kommt es sowieso nicht dorthin. Der WebDriverWait verursacht eine Ausnahme. Die Ausnahme, sagt TypeError: can't access dead object

Es gibt eine entsprechende Meldung aus dem Inneren der Wartezeit ist:

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 

Es gibt auch einige Ausgangs JavaScript-Fehler, anscheinend von 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: [email protected]://marionette/content/element.js:284:7 
element.find/</findElements<@chrome://marionette/content/element.js:255:15 
implicitlyWaitFor/</[email protected]://marionette/content/element.js:600:15 
implicitlyWaitFor/<@chrome://marionette/content/element.js:627:5 
[email protected]://marionette/content/element.js:593:10 
element.find/<@chrome://marionette/content/element.js:254:24 
[email protected]://marionette/content/element.js:253:10 
[email protected]://marionette/content/listener.js:1314:19 
[email protected]://gre/modules/Task.jsm:319:42 
[email protected]://gre/modules/Task.jsm:277:3 
createAsyncFunction/[email protected]://gre/modules/Task.jsm:252:14 
[email protected]://gre/modules/Task.jsm:166:12 
[email protected]://gre/modules/Task.jsm:389:16 
[email protected]://gre/modules/Task.jsm:327:15 
[email protected]://gre/modules/Task.jsm:277:3 
createAsyncFunction/[email protected]://gre/modules/Task.jsm:252:14 
[email protected]://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: [email protected]://marionette/content/element.js:284:7 
element.find/</findElements<@chrome://marionette/content/element.js:255:15 
implicitlyWaitFor/</[email protected]://marionette/content/element.js:600:15 
implicitlyWaitFor/<@chrome://marionette/content/element.js:627:5 
[email protected]://marionette/content/element.js:593:10 
element.find/<@chrome://marionette/content/element.js:254:24 
[email protected]://marionette/content/element.js:253:10 
[email protected]://marionette/content/listener.js:1314:19 
[email protected]://gre/modules/Task.jsm:319:42 
[email protected]://gre/modules/Task.jsm:277:3 
createAsyncFunction/[email protected]://gre/modules/Task.jsm:252:14 
[email protected]://gre/modules/Task.jsm:166:12 
[email protected]://gre/modules/Task.jsm:389:16 
[email protected]://gre/modules/Task.jsm:327:15 
[email protected]://gre/modules/Task.jsm:277:3 
createAsyncFunction/[email protected]://gre/modules/Task.jsm:252:14 
[email protected]://gre/modules/Task.jsm:166:12 
dispatch/<@chrome://marionette/content/listener.js:186:15 

Außerdem meine automatische Ausnahme Verarbeitung versucht, einen Screenshot zu machen, aber das scheitert mit dem gleichen Fehler. Die Codezeile lautet:

File snapshotTempFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); Und dieses Mal die Ausgabe von geckodriver ist:

A coding exception was thrown and uncaught in a Task. 

Full message: TypeError: can't access dead object 
Full stack: [email protected]://marionette/content/capture.js:65:7 
[email protected]://marionette/content/listener.js:1782:14 
dispatch/</req<@chrome://marionette/content/listener.js:188:22 
[email protected]://gre/modules/Task.jsm:319:42 
[email protected]://gre/modules/Task.jsm:277:3 
createAsyncFunction/[email protected]://gre/modules/Task.jsm:252:14 
[email protected]://gre/modules/Task.jsm:166:12 
dispatch/<@chrome://marionette/content/listener.js:186:15 

So kann ich alles tun, diese Arbeit richtig zu machen? Und ist das etwas, was ich als Geckodriver Bug aufbringen muss?

Das einzige, was ich googlen konnte ist: https://github.com/mozilla/geckodriver/issues/614 und die einzige vorgeschlagene Lösung ist driver.switchTo().defaultContent(). Dies könnte meine Screenshot-Routine beheben, aber das Element, auf das ich warte, befindet sich innerhalb des Inhaltsrahmens, weshalb ich diesen Fix nicht für die Wartezeit verwenden kann.

Antwort

1

Es sieht so aus, als ob der Rahmen mit einer neuen Referenz neu geladen wird, während Sie auf das Element some_id warten. Ich würde dieses Problem als Fehler klassifizieren, da der vom Treiber zurückgegebene Fehler nicht durch das Protokoll WebDriver definiert ist.

Ihre beste Chance, es Arbeit zu machen, ist wahrscheinlich einen benutzerdefinierten Kellner zu implementieren, um den Rahmen/Element zu lokalisieren und Ausnahmen überspringen unhandled:

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; 
    } 
    }; 
} 
+0

Dank! Das hat funktioniert. (Ich habe es geändert, um eine separate Klassendefinition anstelle einer Klammerinitialisierung zu verwenden). Ich habe schließlich das Problem auf dem Geckodriver Tracker gefunden, und mit dieser Antwort wusste ich, wie man einen Kommentar eingibt. Ich habe getan. Problem ist https://github.com/mozilla/geckodriver/issues/614 –

Verwandte Themen