2016-08-11 2 views
2

Ich bekomme Timeouts bei der Ausführung von Skripten mit Selenium, egal was ich versuche und tue, um sie zu vermeiden.Selenium Timeout auf ExecuteScript

Ich habe zuerst die Timeouts zu etwas lächerlich lange:

_driver.Manage().Timeouts().SetScriptTimeout(TimeSpan.FromMinutes(30));    
_driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromMinutes(30)); 

Später habe ich ein Skript, das eine lange Zeit in Anspruch nehmen zu erwarten ist (es ist eine lange Lauf POST-Anforderung tun). Keine Frage, ob ich ExecuteScript oder ExecuteAsyncScript verwende, die Zeitüberschreitung bei 60 Sekunden.

Kann ich irgendetwas tun, um dies zu vermeiden? Selbst ein Hack oder Workaround wäre an dieser Stelle gut.

+0

Wenn dies Firefox ist, können Sie versuchen, Profil zu ändern: 'profile.setPreference (" dom.max_script_run_time ", 0);' 0 bedeutet warten für immer –

+0

Ich verwende Chrome. Hat es etwas ähnliches? – MgSam

+0

Ich fand das hilfreich: https://stackoverflow.com/questions/15268255/selenium-webdriver-throws-timeout-exceptions-sporadisch – caznew

Antwort

0

Lieblings RemoteWebDriver (FireFoxDriver oder ChromeDriver) nimmt einen commandTimeout Parameter in einigen seiner Konstruktoren Überladungen.

_driver = new ChromeDriver(ChromeDriverService.CreateDefaultService(), new ChromeOptions(), TimeSpan.FromMinutes(30)) 

Es scheint kein Weg, dies zu ändern, nachdem die Instanz aufgebaut ist, so dass Sie müssen sicherstellen, dass es auf diese Weise zu setzen. Dies verhindert die Timeouts.

1

Die Verbindung zum Treiber hat eine Zeitüberschreitung von 60 Sekunden. Auf Art und Weise ist, es zu ändern das Schutzfeld RemoteWebDriver.DefaultCommandTimeout zu bearbeiten:

typeof(RemoteWebDriver) 
    .GetField("DefaultCommandTimeout", BindingFlags.NonPublic | BindingFlags.Static) 
    .SetValue(null, TimeSpan.FromMinutes(5)); 

Eine andere Möglichkeit wäre, eine Variable, sobald die Anforderung zurückkehrt und dann warten, bis es:

((IJavaScriptExecutor)driver).ExecuteScript(@" 
    window._result = null; 
    var req = new XMLHttpRequest(); 
    req.onreadystatechange = function(){ 
     if(req.readyState == XMLHttpRequest.DONE) { 
      window._result = this.responseText); 
     } 
    }; 
    req.open('GET', '...'); 
    req.send(); 
"); 

var response = new WebDriverWait(driver, TimeSpan.FromMinutes(5)) 
    .Until(_ => ((IJavaScriptExecutor)_).ExecuteScript("return window._result;")); 
+0

Leider funktionierte keiner von diesen für mich. Trotz Änderung des Timeouts wird nach 60 Sekunden immer noch eine Ausnahme ausgelöst. Außerdem sende ich ein Formular, das aus welchem ​​Grund auch immer nicht von "XMLHttpRequest" zu funktionieren scheint. Ich verwende diese Methode http://stackoverflow.com/a/133997/1195036. – MgSam

+0

Ok, ich sehe das Problem jetzt. Sie müssen das DefaultCommandTimeout vor dem Erstellen eines WebDrivers ändern. Tatsächlich ist CommandTimeout einer der Konstruktorparameter für den WebDriver. Es ist einfach eine bessere Lösung, aber ich werde dafür sorgen, dass ich in die richtige Richtung gelenkt werde. – MgSam

0

ich gewartet versuchen würde, das gesamte Dokument in den Bereitschaftszustand zu sein:

var driverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(180)); 
    driverWait.Until(
      driverA => 
      { 
       try 
       { 
        var browserStatus = (string)((IJavaScriptExecutor)driverA). 
ExecuteScript("return document.readyState"); 
        return string.Compare("complete", browserStatus, 
StringComparison.OrdinalIgnoreCase) == 0; 
       } 
       catch (NoSuchWindowException) 
       { 
        return true; 
       } 
       catch (Exception) 
       { 
        return false; 
       } 
      }); 
Verwandte Themen