I, also, need to know whether this is a valid implementation of the factory pattern.
The amount of effort which goes into configuring DriverFactory
to simply get a WebDriver
instance seems disproportionate to the point where I ask: "is there not a better way?"
The main class code:
package dur.bounceme.net.SeleniumBase;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Logger;
import org.openqa.selenium.WebDriver;
public class App {
private static final Logger LOG = Logger.getLogger(App.class.getName());
private Properties properties = new Properties();
public static void main(String[] args) throws IOException {
new App().initSelenium();
}
private void initSelenium() throws IOException {
properties.loadFromXML(App.class.getResourceAsStream("/selenium.xml"));
WebDriver webDriver = DriverFactory.getWebDriver(properties); //is this factory and usage correct?
HomePage homePage = new HomePage(webDriver);
homePage.populateCatalogue();
}
}
And my factory:
package dur.bounceme.net.SeleniumBase;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
public class DriverFactory {
private static final Logger LOG = Logger.getLogger(DriverFactory.class.getName());
private Properties properties = new Properties();
private FirefoxBinary firefoxBinary = null;
private FirefoxOptions firefoxOptions = null;
private WebDriver webDriver = null;
private URL url = null;
private String driver = null;
private String gecko = null;
private final List<String> commandLineOptions = new ArrayList<>();
private DriverFactory() {
}
private DriverFactory(Properties properties) throws MalformedURLException {
this.properties = properties;
loadProps();
init();
}
static WebDriver getWebDriver(Properties properties) throws MalformedURLException {
DriverFactory driverFactory = new DriverFactory(properties);
return driverFactory.webDriver;
}
private void loadProps() throws MalformedURLException {
LOG.fine(properties.toString());
url = new URL(properties.getProperty("url"));
driver = properties.getProperty("driver");
gecko = properties.getProperty("gecko");
String commandLineOption = properties.getProperty("option01");
commandLineOptions.add(commandLineOption);
}
private void init() throws MalformedURLException {
firefoxBinary = new FirefoxBinary();
commandLineOptions.forEach((commandLineOption) -> {
LOG.fine(commandLineOption.toString());
firefoxBinary.addCommandLineOptions(commandLineOption);
});
System.setProperty(driver, gecko);
firefoxOptions = new FirefoxOptions();
firefoxOptions.setBinary(firefoxBinary);
webDriver = new FirefoxDriver(firefoxOptions);
webDriver.get(url.toString());
LOG.fine(webDriver.getTitle());
LOG.fine(webDriver.getCurrentUrl().toLowerCase());
}
void close() {
webDriver.close();
}
}
There seems no nice way to get around loading configuration from a file, which is then loaded. But, it strikes me that I'm re-inventing the wheel of loading a props file for the purpose of configuring a Selenium WebDriver
when I expect there's a tried-and-true approach.
Or, at least, more re-usable.
Although, what possible use there would be for multiple WebDriver
instances is beyond me. It would seem Selenium Grid would handle that question quite differently.