Why do we use WebDriver driver = new FirefoxDriver() in Selenium instead of WebDriver driver = new WebDriver ()?
Why do we need to create the driver object with
WebDriver driver = new FirefoxDriver();
WebDriver driver = new ChromeDriver();
and not with
WebDriver driver = new WebDriver();
Assuming that this line works (it doesn’t but lets assume it does)
WebDriver driver = new WebDriver();
what is the browser that the driver is created for?
Is it Chrome?
Is it Firefox?
Is it Internet Explorer?
There is nothing that is tied to a specific browser.
We cannot create a generic driver that works for all browsers.
Each browser has its own driver:
Chrome uses the driver from chromedriver.exe file
Firefox uses the driver from a Firefox extension included in the Selenium jar files
IE uses the driver from the IEDriverServer.exe file
So, when creating the driver, you have to specify somehow which driver you need (for which browser).
Going back to
WebDriver driver = new WebDriver();
this line of code does not work because WebDriver is not a class but an interface.
What is the difference between a class and an interface?
A Java class contains fields (variables) and methods (with code).
A Java interface contains only methods signatures (names, parameters, exceptions, no code).
A Java interface is implemented by a class (see below) and it defines the methods that the class implements.
For example, the Animal interface only declares methods signatures:
interface Animal {
public void eat();
public void move();
}
There is no code for the eat() and move() methods because the Animal interface is generic and works for all animals.
It cannot have code for the eat() method because
dogs eat different than cats and
cats eat different than giraffes
An interface is implemented by a class.
This means that the class will have all methods of the interface.
The class is usually about a specific concept (dog, cat, etc).
Lets take the Dog class.
Since we know how dogs eat and move, we can specify the code for the eat() and move() methods.
The Dog class may have additional methods that are valid only for dogs but not for other animals:
public class Dog implements Animal {
public void eat() {
System.out.println("dog eats");
}
public void move() {
System.out.println("dog moves");
}
public void bark() {
System.out.println("dog barks");
}
public void wagTail() {
System.out.println("dog wags tail");
}
}
The same interface can be implemented by other classes such as Cat:
public class Cat implements Animal {
public void eat() {
System.out.println("cat eats");
}
public void move() {
System.out.println("cat moves");
}
public void meow() {
System.out.println("cat meows");
}
public void purr() {
System.out.println("cat purrs");
}
}
How do we create objects for the interface and classes that implement it?
Animal animal = new Animal();
animal.eat();
animal.move();
will not work because Animal is an interface.
animal.eat() or animal.move() cannot work since these methods are not implemented in the Animal interface.
Dog sparky = new Dog();
sparky.eat();
sparky.move();
sparky.wagsTail();
sparky.bark();
works because all these methods are implemented (have code) in the Dog class.
Cat chic = new Cat();
chic.eat();
chic.move();
chic.meow();
chic.purr();
works because all these methods are implemented in the Cat class.
Interestingly, the following code works as well:
Animal sparky = new Dog();
sparky.eat();
sparky.move();
Animal chic = new Cat();
chic.eat();
chic.move();
Why does it work?
To put it simply, a dog is an animal and so is a cat.
What you saw is called polymorphism.
What about the driver object?
It should be clear now why
WebDriver driver = new WebDriver();
does not work.
WebDriver is an interface with the following method signatures:
public interface WebDriver extends SearchContext {
void get(String url);
String getCurrentUrl();
String getTitle();
List<WebElement> findElements(By by);
WebElement findElement(By by);
String getPageSource();
void close();
void quit();
Set<String> getWindowHandles();
String getWindowHandle();
TargetLocator switchTo();
Navigation navigate();
Options manage();
interface Options {
void addCookie(Cookie cookie);
void deleteCookieNamed(String name);
void deleteCookie(Cookie cookie);
void deleteAllCookies();
Set<Cookie> getCookies();
Cookie getCookieNamed(String name);
Timeouts timeouts();
ImeHandler ime();
Window window();
Logs logs();
}
interface Timeouts {
Timeouts implicitlyWait(long time, TimeUnit unit);
Timeouts setScriptTimeout(long time, TimeUnit unit);
Timeouts pageLoadTimeout(long time, TimeUnit unit);
}
interface TargetLocator {
WebDriver frame(int index);
WebDriver frame(String nameOrId);
WebDriver frame(WebElement frameElement);
WebDriver parentFrame();
WebDriver window(String nameOrHandle);
WebDriver defaultContent();
WebElement activeElement();
Alert alert();
}
interface Navigation {
void back();
void forward();
void to(String url);
void to(URL url);
void refresh();
}
interface Window {
void setSize(Dimension targetSize);
void setPosition(Point targetPosition);
Dimension getSize();
Point getPosition();
void maximize();
void fullscreen();
}
}
To create a driver object, you need to use a specific class such as FirefoxDriver or ChromeDriver.
Do these classes implement the WebDriver interface?
They do not.
These are the signatures of the FirefoxDriver and ChromeDriver classes:
public class FirefoxDriver extends RemoteWebDriver
implements Killable
public class ChromeDriver extends RemoteWebDriver
implements LocationContext, WebStorage
They inherit from the RemoteWebDriver class which implements the WebDriver interface:
public class RemoteWebDriver implements WebDriver,
JavascriptExecutor,
FindsById,
FindsByClassName,
FindsByLinkText,
FindsByName,
FindsByCssSelector,
FindsByTagName,
FindsByXPath,
HasInputDevices,
HasCapabilities,
TakesScreenshot
So,
FirefoxDriver extends RemoteWebDriver implements WebDriver.
ChromeDriver extends RemoteWebDriver implements WebDriver.
Because of this
WebDriver driver = new FirefoxDriver();
WebDriver driver = new ChromeDriver();
works.
Once the driver object is created, it is a driver either for Firefox or Chrome so it will interact with that browser.
Thanks for reading.