2016-07-27 4 views
0

Ich verwende Selen, um AngularJS-Anwendung zu testen. Ich habe das Problem, dass ich keine Aktionen auf der Seite ausführen kann, bis sie vollständig geladen ist. Ich kann Thread.sleep() setzen, aber das ist keine gute Lösung, wie ich weiß. Es gibt viele Möglichkeiten zu warten, bis die Seite geladen wird (ich google es), aber ich denke, ich habe sie alle ausprobiert und immer noch kein Glück. In meinen Anwendungen, wenn ich auf die Webseite gehe, sieht alles (aus visueller Sicht) geladen aus, aber ich kann keine Aktivitäten machen, bis die ganze Seite geladen ist (ungefähr 1 Sekunde). Können Sie Kerle Ihre Implementierung teilen, wie Sie es getan haben, die tatsächlichSelen und Angularjs warten, bis einige Aktionen ausgeführt werden

Danke

Mein Code funktioniert:

public By ngWait(final By by) { 
    return new FluentBy() { 
     @Override 
     public void beforeFindElement(WebDriver driver) { 
      driver.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS); 
      ((JavascriptExecutor) driver).executeAsyncScript("var callback = arguments[arguments.length - 1];" + 
        "angular.element(document.body).injector().get('$browser').notifyWhenNoOutstandingRequests(callback);"); 
      super.beforeFindElement(driver); 
     } 

     @Override 
     public List<WebElement> findElements(SearchContext context) { 
      return by.findElements(context); 
     } 

     @Override 
     public WebElement findElement(SearchContext context) { 
      return by.findElement(context); 
     } 

     @Override 
     public String toString() { 
      return "ngWait(" + by.toString() + ")"; 
     } 
    }; 
} 

enter image description here

enter image description here

+0

Was haben Sie versucht und was war das Ergebnis? Bitte lesen Sie die Hilfethemen zu [fragen]. Sie müssen Ihr eigenes Problem recherchieren, Codebeispiele finden usw. und Ihren eigenen Code schreiben, um das Problem zu lösen. Wenn Sie all das tun und es immer noch nicht herausfinden können, dann kommen Sie zurück und editieren Sie Ihre Frage und fügen Sie Notizen aus der Forschung hinzu, die Sie gemacht haben. Der Code, den Sie versucht haben, wurde reduziert auf [mcve] und was das Ergebnis war ... Alle Fehlermeldungen usw. Es ist auch sehr wichtig, dass Sie alle relevanten HTML-Dateien einfügen und HTML und Code korrekt formatieren. – JeffC

+0

Der Status "voll geladen" ist subjektiv, insbesondere wenn der Inhalt dynamisch erstellt wird. Sie müssen also zuerst definieren, was Ihre Seite vollständig geladen hat, und dann auf das zuletzt erstellte Element oder den Status eines Elements warten. –

+0

@FlorentB., Ich habe Bild mit dem hinzugefügt, was ich glaube, ich muss warten, bis ich in der Lage bin, an der App zu arbeiten. Weißt du, wie kann ich warten, bis dieses Element vollständig geladen ist? Ich fügte Code hinzu, den ich versuchte zu tun. –

Antwort

2

ich konfrontiert ähnliche Situation beim Schreiben von Tests mit Selen gegen eckige App. Tatsächlich, in angular app das Skelett oder die Ansicht der Seite lädt sofort, aber es ruft $http Anfrage im Hintergrund, um die Daten zu holen. Sobald die eckige App den $http Aufruf beendet, rendert sie die Ansicht mit der Antwort von $ http call.So mit einer klassischen Wartezeit von Selen wie waitUntilPageToBeLoad, waitUntilElementToBeClickable funktionieren hier überhaupt nicht. Die andere Lösung ist, Thread.Sleep() zu haben, aber wie Sie erwähnten, ist das kein intelligentes Warten.

Also warum nicht warten Methode, um sicherzustellen, dass $http Anrufe im Hintergrund abgeschlossen sind. Sie können versuchen, unten warten Methode, es hat für mich funktioniert. Ich hoffe, es funktioniert auch für Sie!

public void untilAngularFinishHttpCalls() { 
     final String javaScriptToLoadAngular = 
       "var injector = window.angular.element('body').injector();" + 
       "var $http = injector.get('$http');" + 
       "return ($http.pendingRequests.length === 0)"; 

     ExpectedCondition<Boolean> pendingHttpCallsCondition = new ExpectedCondition<Boolean>() { 
      public Boolean apply(WebDriver driver) { 
       return ((JavascriptExecutor) driver).executeScript(javaScriptToLoadAngular).equals(true); 
      } 
     }; 
     WebDriverWait wait = new WebDriverWait(driver, 20); // timeout = 20 secs 
     wait.until(pendingHttpCallsCondition); 
    } 
+1

Vielen Dank für Ihre Antwort. Ich habe Ihren Code ausprobiert und bekam eine Ausnahme: 'org.openqa.selenium.WebDriverException: unbekannter Fehler: [jqLite: nosel] Das Nachschlagen von Elementen über Selektoren wird von jqLite nicht unterstützt! Siehe: http://docs.angularjs.org/api/angular.element http: // errors.angularjs.org/1.5.8/jqLite/nosel', das auf diese Zeile verweist: 'return ((JavascriptExecutor) -Treiber) .executeScript (javaScriptToLoadAngular) .equals (true); 'Hast du irgendwelche Gedanken dazu? –

+0

Haben Sie Bibliotheken hinzugefügt? –

+0

Nein Ich habe keine Bibliothek benutzt. –

0

Entschuldigung, ich kann noch keinen Kommentar schreiben, also hier ist mein Stück Hilfe als Antwort.

Nach dem Fehler in den Kommentaren zu Priyanshu Shekhar's Antwort bedeutet das nur, dass jqLite (Angulars grundlegende jquery-Version) nicht genug ist, um das zu tun, was dieser Code versucht.

Die vollständige jquery-Version in Ihrer Seite sollte dieses Problem lösen.