2015-08-03 2 views
5

Code 1:"Stale Element Referenz" Fehlerverhalten undestanding

element(by.id('myButtonId')).click(); 
return element(by.id('myValidationSummaryId')).getText().then(function (val) { 
    return val; 
}); 

Above Code hat gut funktioniert oft und dann begann es unten Fehler geben

„Fehler: abgestanden Element Referenz: element ist nicht an die Seite angehängt Dokument "

Diese ID 'myValidationSum maryId 'ist noch nie zuvor verwendet worden, indem Sie auf das Formular "buttons posts" geklickt haben und auf der Seite "myValidationSummaryId" auf der Seite "service/side" eine Fehlermeldung angezeigt wurde.

Code 2:

return element(by.id('myButtonId')).click().then(function() { 
    return element(by.id('myValidationSummaryId')).getText().then(function (val) { 
     return val; 
    }); 
}); 

Fixing Code wie oben fest Erstausstellung und es funktionierte durchweg fein viele Male aber später begann es zufällig mit Original abgestanden Element Referenzfehler fehlschlägt.

Code 3:

return element(by.id('myButtonId')).click().then(function() { 
    return element(by.id('myValidationSummaryId')).waitReady().then(function (isReady) { 
     if (isReady) { 
      return element(by.id('myValidationSummaryId')).getText().then(function (val) { 
       return val; 
      }); 
     } else { 
      return 'Failed to check success/failure message'; 
     } 
    }); 
}); 

Dann befestigte ich Code wie oben, und jetzt funktioniert es konsequent in Ordnung, waitReady Funktion aktiv für ein Element warten vorhanden und angezeigt auf bestimmte Zeit.

Sollte Winkelmesser/WebdriverJS dies nicht behandeln, Probleme natürlich.

1> Könnten Sie bitte erklären, warum Code 1 und Code 2 irgendwann funktionierten und manchmal fehlgeschlagen sind?

2> Denkst du, Code 3 ist jetzt in Ordnung und sollte jedes Mal funktionieren?

Element 'myValidationSummaryId' wird nur einmal und nach dem Klick verwendet, wenn Seiten nicht vollständig geladen sind und wenn das Element noch nicht verfügbar ist, sollte es Kein Element gefunden werden, aber warum veraltete Elementverweis? Ich habe pageLoadTimeout als 5 Minuten verwendet und die Seite wird in wenigen Sekunden geladen. Dies ist keine AngularJS-Anwendung und browser.ignoreSynchronization = true.

überall wo es darüber sprach, welcher Code es beheben kann, aber nicht viel darüber gefunden, warum dieses Verhalten und warum WebdriverJS selbst nicht in der Lage ist, damit umzugehen.

+0

Ja, explizite Warte der üblicher Weg ist, um Probleme wie diese zu lösen. Aber, ich hatte genau die gleiche Frage, warum manchmal Wartezeiten tatsächlich notwendig sind und sollte Winkelmesser natürlich nicht behandeln. Eine Sache, die ein Winkelmesser in meinem Fall nicht erkannte, war eine Animation - wenn es eine Animation gäbe, die ein Element zeigt, das ich benutzen musste. Gute Frage! – alecxe

+0

Ich kann bestätigen, dass ich heute genau den gleichen Fehler hatte. Ohne Grund änderte sich der Code und Tests begannen zu versagen. Was das Verhalten des seltsamen Winkelmessers anbetrifft - ich kann ** async ** empfehlen, um es zu zähmen. Wenn ** async ** nicht hilft, dann werfe ich das Handtuch. –

Antwort

6

Ich glaube nicht, dass wir sicher sein können, warum das passiert, aber Sie sind definitiv nicht allein (1)(2). Dies kann daran liegen, wie Ihre Seite speziell gerendert wurde (z. B. wie Ihre App/Ihr Framework mit Rendering-DOM-Elementen umgeht) oder nur eine Selen/Treiber-Sache. Wenn Sie an einer genauen Erklärung interessiert sind, können Sie mehr Glück haben, wenn Sie das Protractor-Fehlerberichtsystem verwenden.

Eine gute Vermutung kann jedoch sein, dass es auf die Art und Weise Selen defines stale element verwendet ist:

Eine weniger häufige, aber immer noch häufige Ursache ist, wo eine JS-Bibliothek hat ein Element gelöscht und ersetzt es mit mit der gleichen ID oder Attributen

Einige Bibliotheken Selen zu glauben, ein Element täuschen können, ist aus dem DOM gegangen, aber es ist wirklich nur in einem Augenblick ersetzt. Hinzufügen eines engen, gebrechlichen Timings zwischen Klicken und Element im DOM (Race Condition im Grunde) - das könnte die Ursache sein. Sie könnten daran interessiert sein, ein wenig mehr darüber zu lesen here. Wenn Sie solche Probleme haben, würde ich Ihnen empfehlen, browser.wait und Expected Conditions zu verwenden.

Die erwarteten Bedingungen sind im Grunde Funktionen, die Wahr oder Falsch zurückgeben, und Sie können ein Zeitlimit angeben, das den Test fehlschlägt, wenn in dieser Zeit nicht true zurückgegeben wird - Sie können sehen, wie es in einem similar question verwendet wird.

Grundsätzlich sollten Sie es wie folgt tun:

var EC = protractor.ExpectedConditions; 
var summaryId = element(by.id('myValidationSummaryId')); 

browser.wait(EC.presenceOf(summaryId), 5000); 
//rest of your code 
+0

Vielen Dank für Ihre Vorschläge, WaitReady-Funktion verwendet browser.wait, und es funktioniert gut, ich hatte http://docs.seleniumhq.org/exceptions/stale_element_reference.jsp gegangen, aber in meinem Fall Element nicht entfernt, ersetzt oder seine Typ ändert sich nicht. – Morbia

+0

Dann müssten Sie wahrscheinlich Ihren genauen Code teilen oder selbst ein erweitertes Debugging durchführen. Die Ursache wird wahrscheinlich sehr schwer zu bestimmen sein, aber wenn Sie herausfinden, was das ist, wäre ich großartig, wenn Sie die Ursache hier teilen würden. – wap300

+0

Einverstanden, ich arbeite gerade an einem Projekt. Wenn ich Entwicklerwerkzeuge in Chrome F12 öffne und das DOM beobachte, kann ich tatsächlich Angulars asynchrone Puts sehen und bestimmte (und unbekannte) DOM-Elemente ändern. Dies macht das Testen dieser Seiten wegen offensichtlicher Timing-Probleme und der "Stale-Element-Referenz" unmöglich. –

Verwandte Themen