Hello Folks,
Selenium automates browser and to achieve this, Selenium people have provided many classes and interfaces.
During learning selenium, many times we will use up-casting and down-casting concepts of JAVA. Many people know how to perform some operations like opening any desired browser through single method, running java script etc but they are not able to answer why did they do up-casting and down-casting.
In this post, I will explain hierarchy of Selenium classes and interfaces.
Let’s start with some basic concepts of java:
- We can not create an object of interface, i.e. we can not instantiate an interface.
- Interface has abstract methods means they do not have body, only declaration.
- We can pass reference of any super class or interface to a sub class object.
- When we do up-casting, we restrict object from using sub class methods. To use sub class methods, we must down cast the object to sub class object.
- When we up cast an object and try to access a method of sub class, and that method is overridden in sub class, remember overridden method of sub class will be called without down casting object. It is major concept on which selenium works.
WebDriver hierarchy:
Let’s understand above diagram in details:
- 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.
- 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.
- RemoteWebDriver is a fully implemented class which implements Webdriver, JavascriptExecutor and TakesScreenshot. Fully implemented class means it defined body for all inherited methods.
- 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:
- You can launch any browser through single browser factory method. (We will see soon how)
- It is a good programming practice to upcast the object to maximum level possible keeping in mind that you should not loose important functionalities.
- If we upcast object to SearchContext, it will not be so feasible as it has only two methods. To use other important methods, we need to do down casting.
- 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.
- 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 object execute javascript?
A: We do not downcast always to run javascript until 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.
WebElement hierachy:
- WebElement is an interface which extends SearchContext and TakesScreenshot interfaces. It has many useful abstarct methids like click(), sendKeys(), isSelected() etc.
- RemoteWebELement is a fully implemented class as it implements WebElement interface. In fact, findElement() and findElements() of SearchContext interface have been defined properly in this class only.
- 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 RemoteWebElemnt class will be executed because of overriding concept.
I hope, This post will be very useful as it clears why we do up casting and down casting while creating script. Now you must be able to answer.
#HappyLearning
Thanks. Bye.
Can u please explain findElement and By Class in the same manner and demystify it.. Thanks for the help
thnaks, it was quick and useful.
Thank you Thank you Thank you for such a lovely post. Maaza aa gaya 🙂 Keep it up bro!.
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 ?
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.
Thanks for the wonderful post Amod. It is very well written and thoroughly explained!!
Thank you very much for nice explanation for understanding in-depth.
Thanks Harish.
Very Useful explanation !!!
Keep posting …Thank you so much!!
Thanks Prateek.
Very well explained. Thanks a lot.
Thanks a lot very basic thinks explanations
Thanks Surabhi.
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
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
Extremely useful !! Very Thankful to you
Thanks Tirath.
Really an very useful information.it clears many doubts…please keep on sharing your knowledge which helps the people like us..
Thank Amod..
Sure Mallikarjun.
Could you please explain this point in little detail sir. I did not understand in above section:
RemoteWebDriver driver= new FirefoxDriver();
why this is not preferable: RemoteWebDriver driver= new FirefoxDriver();
Hi Pavan,
I will publish a post soon on this.
ok thank you.
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 .
Well explained concept.Great Job.
It would be very helpful if you could add code snippet for the explanation for better/easy understanding.
Thanks Siva. Will take care of your feedback.
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
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
thanx for such clear explanation
Thansk.
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.
Hi Kavya,
There is java concept called Runtime polymorphism which is achieved when you upcast to WebDriver. RemoteWebDriver is a class.
I dont understand the above comment sir. Runtime polymorphism can be achieved using classes also. Not require an Interface always. please clarify me.
Upcasting browser driver class object to WebDriver is example of achieving run time polymorphism.
Really it’s an amazing explanation. It’s one of the best blogs I’ve ever seen.
Thanks Reddy.
Really appreciate for the information provided. Thanks a lot.
Thanks Vinit
Thanks..its good overview…
Thanks Mohan.
Really Helpful Contents. This post has Clarified many doubts .Thank you So much Amod.
Thanks Gaurav. 🙂
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!!!!
Thanks for great compliments.
Truly said Gaurav. Thanks Amod sir for sharing the knowledge