5

I'm getting timeouts when executing scripts with Selenium no matter what I try and do to avoid them.

I first set the timeouts to something ridiculously long:

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

Later, I run a script which is expected to take a long time (it's doing a long running POST request). No mater whether I use ExecuteScript or ExecuteAsyncScript, the request times out at 60 seconds.

Is there anything I can do to avoid this? Even a hack or workaround would be good at this point.

MgSam
  • 12,139
  • 19
  • 64
  • 95

3 Answers3

3

The connection to the driver has a 60 second timeout. On way to change it is to edit the protected field RemoteWebDriver.DefaultCommandTimeout:

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

Another way would be to set a variable once the request returns and then wait for it:

((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;"));
Florent B.
  • 41,537
  • 7
  • 86
  • 101
  • Unfortunately neither of these worked for me. Despite changing the timeout, it still throws an exception at 60 seconds. In addition, I'm POSTing a form, which for whatever reason doesn't seem to work from `XMLHttpRequest`. I'm using this method http://stackoverflow.com/a/133997/1195036. – MgSam Aug 15 '16 at 18:11
  • Ok, I see the problem now. You need to change the DefaultCommandTimeout before creating a WebDriver. In fact, CommandTimeout is one of the constructor parameters for the WebDriver. Just setting it there is a better solution, but I'll upvote this for pointing me in the right direction. – MgSam Aug 15 '16 at 19:14
3

Your favorite RemoteWebDriver (FireFoxDriver or ChromeDriver) takes a commandTimeout parameter in some of its constructor overloads.

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

There appears to be no way to change this after the instance is constructed, so you need to make sure to set it this way. This will prevent the timeouts.

MgSam
  • 12,139
  • 19
  • 64
  • 95
  • This doesn't work for me. I still get a 60s time out exception from `IJavaScriptExecutor.ExecuteAsyncScript` – Jack May 30 '19 at 00:56
  • hi @Jack I"m getting this error when i also use the ExecuteAsyncScript method even though the script has executed. U use to use the other method of ExecuteScript but that doesn't seem to work anymore. Did you find a way around this. Thanks – skinnyWill Sep 20 '19 at 17:07
  • @skinnyWill: I switch to using Firefox driver for some reason (not for timeout specifically) but on Firefox, I did initiliaze it like this: https://pastebin.com/nPVuH4k0 Hope it helps – Jack Sep 20 '19 at 17:57
0

I would try waiting for the whole document to be in the ready state:

  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;
                }
            });
marwaha.ks
  • 540
  • 1
  • 7
  • 19