Casting Object to an interface and accessing the interface methods implemented elsewhere

3k views Asked by At

We use the following code to take screenshots in selenium.

WebDriver driver = new FirefoxDriver();
File src = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(src, new File("D:\\TestNGScreenshots\\screenshot.png"));

Here is what I understood:

  • TakesScreenshot is an interface that provides a method getScreenshotAs() to get screenshots.
  • But WebDriver doesn't extend this interface.
  • FirexfoxDriver class also doesn't implement this interface
  • The getScreenshotAs() method is implemented in a separate class RemoteWebDriver which implements TakesScreenshot.

Here we are casting the driver object to another interface TakesScreenshot and we are using it's method getScreenshotAs() which is implemented in a completely different class.

So if we want to use an interface methods which were implemented in some classes can we use them by casting our object (which was created from a class implementing to another interface) to that interface?

Also, if we create the driver like

FirefoxDriver driver = new FirefoxDriver()

We can't cast the Interface to the driver here. We have to use it like TakesScreenshot ts = drvier and then we can use the method getScreenshotAs(). Here also not sure what exactly happening?

Can someone explain please?

Thank you.

2

There are 2 answers

0
Karol Dowbecki On

In your example you are casting from WebDriver interface to TakesScreenshot interface. You can always cast from one interface to another because the Java compiler can't tell if the reference defined by one interface doesn't hold an object that implements other interfaces. This check is deferred to runtime where you will get ClassCastException if it fails.

FirefoxDriver may not directly implement TakesScreenshot but it extends RemoteWebDriver which does. Because of that FirefoxDriver IS-A TakesScreenshot as per the class javadocs. You can write following:

FirefoxDriver driver = new FirefoxDriver();
File src = driver.getScreenshotAs(OutputType.FILE);
0
undetected Selenium On

TakesScreenshot

TakesScreenshot is the public interface that provides a method getScreenshotAs() to capture the screenshot and store it in the specified location and implements the following classes:

  • FirefoxDriver
  • ChromeDriver
  • InternetExplorerDriver
  • EdgeDriver
  • OperaDriver
  • SafariDriver
  • EventFiringWebDriver
  • RemoteWebDriver
  • RemoteWebElement

This implies that the driver that can capture a screenshot and store it and is achieved by casting the driver instance into TakesScreenshot type instance.

As an example:

public static void takeScreenShot() throws IOException{
    String path = "./ScreenShots/";
    File scrFile = ((TakesScreenshot)drive).getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(scrFile, new File(path + "Subbu" + ".jpg"));
    System.out.println("Screenshot Taken");
}