Thursday, November 7, 2013

C#: Avoiding the WebDriverException: No response from server for url


When it comes to automated testing, there’s not much worse than intermittent failures, especially when they stem from the driver itself. The current version of the C# WebDriver bindings has such a failure, but I worked out a reasonable way to avoid it happening. Basically it involves creating a WebDriver extension method that I use instead of Driver.FindElement, which tries a number of times to find the element, ignoring the exception that is intermittently raised.

I hope you find this useful if you’re consuming WebDriver in C#.
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
namespace Extensions
{
    public static class WebDriverExtensions
    {
        public static SelectElement GetSelectElement(this IWebDriver driver, By by)
        {
            return new SelectElement(driver.GetElement(by));
        }
        public static IWebElement GetElement(this IWebDriver driver, By by)
        {
            for (int i = 1; i <= 5; i++ )
            {
                try
                {
                    return driver.FindElement(by);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception was raised on locating element: " + e.Message);
                }
            }
            throw new ElementNotVisibleException(by.ToString());
        }
    }
}


=====================
I think this is what the WebDriverWait class in the WebDriver.Support library is for, isn’t it? We have an extension method that wraps this:
public static T WaitUntil(this IWebDriver browser, Func condition,
string failMessage, int timeoutSeconds = 15)
{
// helper for inserting browser name in failure messages
failMessage = failMessage.Replace(“@Browser”, string.Format(“{0} browser”, browser.GetName()));
try
{
// if the condition does not become true within timeoutSeconds, an exception will be thrown.
return new WebDriverWait(browser, new TimeSpan(0, 0, 0, timeoutSeconds, 0))
.Until(condition);
}
catch (Exception ex)
{
// if an exception was thrown, fail the test and return
Assert.Fail(string.Format(“{0} ({1})”, failMessage, ex.Message));
}
return default(T);
}
Usage:
// this example returns an IWebElement, but you can also do conditions that evaluate
// to true/false. If condition does not become true within timeoutSeconds, test fails
var webElement = driver.WaitUntil(d => d.FindElement(By.CssSelector("h1:first")), "error message to display on fail", 5);
However, we do get intermittent no response from session during Click, SendKeys, Clear, etc, at times. For these we have taken similar approach — just keep trying and catching WebDriverException until the session responds.
 public static void ClickWebElement(this IWebElement webElement)
{
if (webElement == null)
throw new ArgumentNullException(“webElement”);

bool exceptionCaught;
do
{
exceptionCaught = false;
try
{
webElement.Click();
}
catch (WebDriverException)
{
exceptionCaught = true;
}

} while (exceptionCaught);
}
Taken from here : http://watirmelon.com/2011/10/04/c-avoiding-the-webdriverexception-no-response-from-server-for-url/