Hierarchy of Selenium Classes and Interfaces

Hello Folks,

Selenium automates browser and to achieve this, Selenium has provided many classes and interfaces.

We must need to understand hierarchy of Classes and Interfaces of Selenium WebDriver. It will help us to understand upcast and downcast codes which we generally do during writing automation scripts like capturing screenshot using TakesScreenshot interface and executing JavaScript using JavaScriptExecutor interface.

Let’s start with some basic concepts of java:

  1. We can not create an object of interface, i.e. we can not instantiate an interface.
  2. Interface has abstract methods means they do not have body, only declaration.
  3. We can pass reference of any superclass or super interface to its sub class object which is called Upcast.
  4. When we upcast a subclass object, we restrict that object from using sub class methods. To use subclass methods, we must downcast the object to subclass object.
  5. When we up cast a subclass object say SubObj and try to access a method say SuperClassMethod of superclass by that object, and that method is overridden in subclass, then method of subclass will be called without down casting subclass object. It is called runtime polymorphism. It is major concept on which selenium works.

WebDriver hierarchy:

IMG_8022

Let’s understand above diagram in details:

  1. SearchContext is a top most interface which has only two methods names findElement() and findElements(). These methods will be abstract as SearchContext is an interface.
  2. WebDriver is also an interface which extends SearchContext. WebDriver has many abstarct methods like get(String url), close(), quit() , getWindowHandle etc. WebDriver has nested interfaces names Window, Navigation, Timeouts etc. These nested interfaces are used to perform/group specific operation like getPosition(), back(), forward() etc.
  3. RemoteWebDriver is a fully implemented class which implements Webdriver, JavascriptExecutor and TakesScreenshot. Fully implemented class means it defined body for all inherited abstract methods.
  4. Then we have browser specific driver classes like ChromeDriver(), EdgeDriver(), FirefoxDriver() etc.

#InterviewQuestion:

Q 1: Why do we upcast any browser driver class object to WebDriver?
OR
Why do we not upcast to SearchContext or RemoteWebDriver?

A: In selenium, maximum time when we create an object of any browser driver class, we do upcast.

E.g. WebDriver driver= new FirefoxDriver();

Reasons are as below:

  1. It helps in launching any browser type using same instance of WebDriver. WebDriver is super interface for all browser classes like FirefoxDriver , ChromeDriver etc. So WebDriver instance can hold object of any browser class.

WebDriver driver= new FirefoxDriver();

WebDriver driver= new ChromeDriver();

It will be helpful if you want to perform cross browser testing.

2. It is a good programming practice to upcast the object to a level where you can be a in position to use maximum Types(Classes, Interface are called Type) down the hierarchy without much downcast and you should not lose important members of Types up in the hierarchy. If you are on Top of hierarchy, you can navigate anywhere down to hierarchy. Upcasted object can be downcasted.

So here we have tree options. Upcast to RemoteWebDriver or WebDriver or SearchContext. If we upcast browser class object to SearchContext, it will not be so good as it has only two methods and to use other types below in hierarchy, we need to do down cast.

If we upcast to WebDriver, we can use many useful methods of WebDriver without any explicit downcast. Upcast to WebDriver if you want to run scripts locally. Upcast to RemoteWebDriver, if want to run on remote machine.

Remember, there is no such mandatory rule that you need to upcast or downcast. It is just way of proper programming.

Q 2: Why do we downcast browser class object to execute javascript?

A: We do not downcast always to execute javascript until browser class object is upcasted to WebDriver.

i.e. no need to do downcasting in below case:

FirefoxDriver driver2= new FirefoxDriver();

We can run javascript directly because execute() method will be visible/accessible to driver2 object.

But, if we write as below:

WebDriver driver= new FirefoxDriver();

We must need to downcast it to JavaScriptExecutor to make execute() method visible to object. Refer the hierarchy above. JavaScriptExecutor is in between WebDriver and Browser driver classes.

WebElement hierarchy:

IMG_8024

  1. WebElement is an interface which extends SearchContext and TakesScreenshot interfaces. It has many useful abstract methods like click(), sendKeys(), isSelected() etc.
  2. RemoteWebElement is a fully implemented class of WebElement interface. In fact, findElement() and findElements() of SearchContext interface have been defined properly in this class only.
  3. When we search for some element using findElement or findElements() method, a type of RemoteWebElement class is up casted to WebElement. And when we perform any action on webelement like click(), method defined in RemoteWebElement class will be executed because of overriding concept.

I hope, This post will be very useful as it clears why we do upcast and downcast while creating script. Now you must be able to answer.

#HappyLearning

Thanks.

Author: Amod Mahajan

47 thoughts on “Hierarchy of Selenium Classes and Interfaces

  1. Can you please explain this

    “Keeping 2nd point in mind, We can upcast till WebDriver as we are not making it difficult to use important methods because of major concept of overriding in java. So, we do not upcast to RemoteWebDriver.”

    If we upcast to RemoteWebDriver its a fully implemented class which has access to all methods that are there even at WebDriver level. So why we did not upcasted only at RemoteWebDriver level.

    Anyhow WebDriver is an interface so it does not have any method implemented. If we could have upcasted til RemoteWebDriver. Was it not enough ?

    1. Yes you can do. There is no harm. Suppose if a new implemented class of WebDriver comes in to picture and has no connection from RemoteWebDriver. If you have upcasted till RemoteWebDriver, you can use the functionalities of new class. BUt if you would have upcasted till WebDriver, you can use functionalities of new class as well. Let me know if you get a point here.

    2. I’m late here, but I’ll throw an explanation I found online.

      Firstly, unfortunately what he said seems wrong (I mean, the “why” is wrong). Method Override has nothing to do with using WebDriver in place of RemoteWebDriver (and there also is no override involved, either).

      The whole explanation is this:

      1) we make an upcast to WebDriver so we can achieve cross-browser compatibility.

      In fact, if we instantiated a single browser object (which we can do, since those are classes too), we would then need to create a different object for any new browser we’d need to run our tests into.

      ChromeDriver driver = new ChromeDriver();

      InternetExplorerDriver driver2 = new InternetExplorerDriver();

      etc…

      Instead, using WebDriver we can achieve this purpose in a much simpler way:

      WebDriver driver = new ChromeDriver();

      driver.close();

      driver = new FirefoxDriver();

      This is an example of Polymorphysm. In fact, being WebDriver an interface, it has got, in form of signatures, all methods which are then implemented in their respective classes, like ChromeDriver, FirefoxDriver, and so on. Thus, whenever we create an object of one of these classes, the compiler automatically calls the right constructor to instantiate it.

      2) why the upcast is to WebDriver and not RemoteWebDriver:

      it seems that with WebDriver, we can simply run our tests on our Local Machine, while when we use RemoteWebDriver we run our tests on a Remote Machine, and we need to tell the new object created, where the Selenium Standalone Server is.

      example of RemoteWebDriver use:

      DesiredCapabilities capabilities = DesiredCapabilities.firefox();
      capabilities.setCapability(“marionette”, true);
      capabilities.setCapability(“networkConnectionEnabled”, true);
      capabilities.setCapability(“browserConnectionEnabled”, true);

      WebDriver driver = new RemoteWebDriver(new URL(“http://localhost:4444”), capabilities);

      I found these explanations online, but they make more sense to me than this one.

      A nice effort though, and the pictures were very useful to me. I’m writing my thesis on Selenium WebDriver.

  2. Hi Amod,

    You are doing a fabulous job. I am following each and every post of yours since you explained very basic things that are not readily available anywhere else.
    I wanted to understand the connection between WebDriver and WebElement interfaces as both contains findElement(s) methods which are implemented by their resp. classes, so why we need implementation twice and what is the difference. Please explain.

    Big Thanks,
    Sweta

    1. Hi Sweta,
      FindElement methods in both WebDriver and WebElement do the same thing but in different context. findElement of WebELement helps you to find with respect to current element.
      For ex: WebElement ele1= some locator
      WebElement ele2= ele1.findElement(….)
      Thanks
      Amod

  3. Really an very useful information.it clears many doubts…please keep on sharing your knowledge which helps the people like us..
    Thank Amod..

    1. Hi Pavan,
      RemoteWebDriver is super class of any browser class. So you can up cast a browser driver class object to its super class RemoteWebDriver .

  4. Well explained concept.Great Job.
    It would be very helpful if you could add code snippet for the explanation for better/easy understanding.

  5. I have a question here, as all the methods are implemented in remotewebdriver class, why cant we directly call methods from remote webdriver class itself??.Why are we accessing it through webdriver???……I tried accessing remotewebdriver class, but the error says, counstructors are not visible, Since it is a protected class. Could you please clarify me on that??.

    Thanks in advance

    1. Hi Divya,

      RemoteWebDriver works as a base class for all browser classes. RemoteWebDriver is mainly useful when you run your scripts in a grid. Default constructor of RemoteWebDriver is not visible outside package because it is protected. You need to use setup browser in a grid and pass statement as below:
      WebDriver driver = new RemoteWebDriver(new URL(“http://localhost:
      4444/wd/hub”), DesiredCapabilities.firefox());
      Thanks
      Amod

  6. Hi Amod Sir,
    I have a doubt that if we upcast only upto Remote WebDriver then there will be no need for downcasting again for Takescreenshot and JavaScript Executor as it is fully implemented class(methods from SearchContext and WebDriver interface)
    and also it is mentioned that upcast the object to maximum level possible keeping in mind that you should not loose important functionalities. But if we are upcasting to WebDriver then we are loosing some functionalities. Please help in understanding here if I am wrong.

    1. Hi Kavya,
      There is java concept called Runtime polymorphism which is achieved when you upcast to WebDriver. RemoteWebDriver is a class.

  7. i have read so many post online but the way you explain and depth you goes in is awesome.. One day your blog will be one of the best because of the content you have.

    Keep up the great work!!!!

Leave a Reply

Please wait...

Subscribe to new posts to become automation expert

Want to be notified when my new post is published? Get my posts in your inbox.
%d bloggers like this: