Better handling ‘NoSuchElementException’ using simple remote web driver wrapper

While implementing test scenarios, I often write some element selectors wrong and finally get ‘NoSuchElementException’ when run the test. Unfortunately it does not specify, which selector caused the problem. Its message only says the following:

OpenQA.Selenium.NoSuchElementException: no such element
(Session info: chrome=45.0.2454.99)
(Driver info: chromedriver=2.10.267521,platform=Windows NT 6.3 x86_64)

So I need to waste time to locate exact failed selector using debugging…
Wouldn’t be nicer to have not found selector specified right in exception message? So it would be possible to troubleshoot the problems easily.
Ok, let’s  add it!

First prepare the environment. I use Visual studio 2013, update 5.
1. Create test project. Ensure that you have NUnit runner extension installed in VS.
2. Install following packages:

<packages>
  <package id="CuttingEdge.Conditions" version="1.2.0.0" targetFramework="net45" />
  <package id="NUnit" version="2.6.4" targetFramework="net45" />
  <package id="Selenium.WebDriver" version="2.47.0" targetFramework="net45" />
  <package id="WebDriverChromeDriver" version="2.10" targetFramework="net45" />
</packages>

3. Modify UnitTest1 class to use NUnit.

 [TestFixture]
    public class UnitTest1
    {
        [Test]
        public void TestMethod1()
        {
            using (var myDriver = new ExceptioHandleDriver(new ChromeDriver(new ChromeOptions())))
            {
               var element = myDriver
                    .GoTo("https://wordpress.com/wp-login.php")
                    .FindElement(By.Id("unique-id"));

                Assert.IsTrue(element != null);
            }
        }
    }

4. Add driver implementation. Driver is wrapper around RemoteWebDriver and implements only few functionality, just to fit the demonstration purpose:

 public class ExceptioHandleDriver : IDisposable
    {
        private readonly RemoteWebDriver _innerDriver;

        public ExceptioHandleDriver(RemoteWebDriver innerDriver)
        {
            Condition.Requires(innerDriver).IsNotNull();
            _innerDriver = innerDriver;
        }

        public ExceptioHandleDriver GoTo(string url)
        {
            _innerDriver.Navigate().GoToUrl(url);
            return this;
        }

        public IWebElement FindElement(By by)
        {
            try
            {
                return _innerDriver.FindElement(@by);
            }
            catch (NoSuchElementException e)
            {
                throw new NoSuchElementException(string.Format("Element '{0}' was found.", @by), e);
            }
        }

        #region Dispose pattern implementation

        ~ExceptioHandleDriver()
        {
            Dispose(false);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        public void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_innerDriver != null)
                {
                    _innerDriver.Dispose();
                }
            }
        }

        #endregion
    }

Now when we run the test (it assumes to be failed, do not worry), we could happily see better error representation:

Result Message:
OpenQA.Selenium.NoSuchElementException : Element ‘By.Id: unique-id’ was found.
—-> OpenQA.Selenium.NoSuchElementException : no such element
(Session info: chrome=45.0.2454.99)
(Driver info: chromedriver=2.10.267521,platform=Windows NT 6.3 x86_64)
Result StackTrace:
….

This entry was posted in Selenium and tagged . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.