I am helping to build an automation framework to test our website. Since the test cases must run against Chrome, Firefox and IE, we are currently passing around a WebDriver object for our driver. This object will in reality be either a ChromeDriver, FirefoxDriver, or InternetExplorerDriver, as the case may be.
The problem I'm having is that I want to have this driver open up a new window in order to validate a test. The only method I've found to do this involves executing javascript - see here.
In order to execute javascript, a driver must implement the JavascriptExecutor interface. All of the drivers we will use are in fact JavascriptExecutors, but since we are using the WebDriver interface, this is not guaranteed. I am trying to get the javascript running, at least as a proof of concept, but I also want to know how to properly organize our driver object so that it can execute javascript without having to explicitly state which of the three drivers it is.
Here is something that I tried just to test the javascript method of opening a new window. It did not work:
if (ChromeDriver.class.isInstance(driver)) {
ChromeDriver chrome = (ChromeDriver)driver;
chrome.executeScript("window.open()");
}
for (String handle : driver.getWindowHandles()) {
System.out.println(handle);
}
In the above case, I was using Chrome for testing so I knew that the driver was in fact a ChromeDriver. I am guessing that the code failed to open a new window because I was instantiating a new driver object and I assume this doesn't really work with Selenium. Had it worked, I would've moved on to try to identify the windows (using driver.getWindowHandles) and load a URL in the new window.
So - is the reason the code failed to open a new window that I was creating/casting a new driver object which Selenium disliked? If so, what is the proper solution? Do I need to create a new interface sandwiched between the Chrome, Firefox, and IE drivers and the JavascriptExecutor interface - something like this?
public interface SpecialDriver extends WebDriver, JavascriptExecutor {
}
This doesn't seem to work - at least, I cannot assign a ChromeDriver to a SpecialDriver, because ChromeDriver does not explicitly implement my new combined interface, even though it implements both WebDriver and JavascriptExecutor. Am I barking up the wrong tree entirely with this approach? Thanks in advance.