In many instances, users will want to change the default behavior of the browser before the test starts, or on the fly when creating a new driver during the test run. We previously covered setting default preferences and options in the setDriver
method to keep the test environment static. Now, we can alter the default preferences using the varargs
parameter in Java, as an optional parameter to the setDriver
method. Here are the basics:
- The
varargs
parameter tosetDriver
will be aMap<String, Object>
type Map
can be passed into the driver when creating a new browser instance, or by setting a JVM argument of mapped preferences- JVM arguments used to pass in mapped preferences can be done in a TestNG XML file as a parameter, an IDE Run Configuration using a JVM arg, or as a
-Dswitch
to the command-line executable - Each browser type will need to process the map of Desired Capabilities, preferences, and options
The following example shows how to use the varargs
parameter in the setDriver
method, which is called optPreferences
. This is the setDriver
method so far, from what we have built:
@SafeVarargs public final void setDriver(String browser, String environment, String platform, Map<String, Object>... optPreferences) throws Exception { DesiredCapabilities caps = null; String localHub = "http://127.0.0.1:4723/wd/hub"; String getPlatform = null; switch (browser) { case "firefox": caps = DesiredCapabilities.firefox(); FirefoxProfile ffProfile = new FirefoxProfile(); ffProfile.setPreference("browser.autofocus", true); caps.setCapability(FirefoxDriver.PROFILE, ffProfile); caps.setCapability("marionette", true); System.setProperty("webdriver.gecko.driver", "gecko_driver_windows_path/geckodriver.exe"); if ( optPreferences.length > 0 ) { processFFProfile(ffProfile, optPreferences); } webDriver.set(new FirefoxDriver(caps)); break; case "chrome": caps = DesiredCapabilities.chrome(); ChromeOptions chOptions = new ChromeOptions(); Map<String, Object> chromePrefs = new HashMap<String, Object>(); chromePrefs.put("credentials_enable_service", false); chOptions.setExperimentalOption("prefs", chromePrefs); chOptions.addArguments("--disable-plugins", "--disable-extensions", "--disable-popup-blocking"); caps.setCapability(ChromeOptions.CAPABILITY, chOptions); caps.setCapability("applicationCacheEnabled", false); System.setProperty("webdriver.chrome.driver", "chrome_driver_windows_path/chromedriver.exe"); if ( optPreferences.length > 0 ) { processCHOptions(chOptions, optPreferences); } webDriver.set(new ChromeDriver(caps)); break; case "internet explorer": caps = DesiredCapabilities.internetExplorer(); InternetExplorerOptions ieOpts = new InternetExplorerOptions(); ieOpts.requireWindowFocus(); ieOpts.merge(caps); caps.setCapability("requireWindowFocus", true); System.setProperty("webdriver.ie.driver", "ie_driver_windows_path/IEDriverServer.exe"); if ( optPreferences.length > 0 ) { processDesiredCaps(caps, optPreferences); } webDriver.set(new InternetExplorerDriver(caps)); break; } // etc... }
Note
The Oracle Java doc for varargs
is located at https://docs.oracle.com/javase/8/docs/technotes/guides/language/varargs.html.
The next example shows how to pass Map
into the setDriver
method using the varargs
parameter:
// first, create a map for the key:value pairs to pass into the driver Map<String, Object> preferences = new HashMap<String, Object>; // then put the key:value pairs into the map preferences.put("applicationCacheEnabled",false); preferences.put("network.cookie.cookieBehavior", 0); // then, pass the map into the setDriver method CreateDriver.getInstance().setDriver("firefox", "Windows 10", "local", preferences);
Finally, the next example shows how to set the optional browser preferences as a JVM argument using the TestNG parameter attribute in the suite XML file:
// pass in the key:value pairs as a runtime argument -Dbrowserprefs=applicationCacheEnabled:false, network.cookie.cookieBehavior:0 // pass in the key:value pairs as a TestNG XML parameter <test name="Selenium TestNG Test Suite"> <parameter name="browser" value="chrome" /> <parameter name="platform" value="Windows 10" /> <parameter name="browserPrefs" value="intl.accept_languages:fr" /> <classes> <class name="com.myproject.MyTest" /> </classes> </test>
// for convenience, create a setPreferences method // to build the map to pass into the driver public Map<String, Object> setPreferences() { Map<String, Object> prefsMap = new HashMap<String, Object>(); List<String> allPrefs = Arrays.asList( System.getProperty("browserPrefs").split(",", -1)); // extract the key/value pairs and pass to map... for ( String getPref : allPrefs ) { prefsMap.put(getPref.split(":")[0], getPref.split(":")[1]); } return prefsMap; }
// set JVM arg, call this method on-the-fly, create new driver
if ( System.getProperty("browserPrefs") != null ) {
CreateDriver.getInstance().setDriver("firefox",
"Windows 10",
"local",
CreateDriver.getInstance().setBrowserPrefs()
);
}
Once the optional preferences are passed into the setDriver
method, the user then has to process those options. For instance, there may be DesiredCapabilities
, ChromeOptions
, or FirefoxProfile
preferences that need to be processed. First, for each driver-type instance, there needs to be a check to see if the options have been passed in, then if so, they have to be processed. Each type will be outlined as shown here:
/** * Process Desired Capabilities method to override default browser * or mobile driver behavior * * @param caps - the DesiredCapabilities object * @param options - the key: value pair map * @throws Exception */ private void processDesiredCaps(DesiredCapabilities caps, Map<String, Object>[] options) throws Exception { for ( int i = 0; i < options.length; i++ ) { Object[] keys = options[i].keySet().toArray(); Object[] values = options[i].values().toArray(); for ( int j = 0; j < keys.length; j++ ) { if ( values[j] instanceof Integer ) { caps.setCapability(keys[j].toString(), (int) values[j]); } else if ( values[j] instanceof Boolean) { caps.setCapability(keys[j].toString(), (boolean) values[j]); } else if ( isStringInt(values[j].toString()) ) { caps.setCapability(keys[j].toString(), Integer.valueOf(values[j].toString())); } else if ( Boolean.parseBoolean(values[j].toString()) ) { caps.setCapability(keys[j].toString(), Boolean.valueOf(values[j].toString())); } else { caps.setCapability(keys[j].toString(), values[j].toString()); } } } }
/** * Process Firefox Profile Preferences method to override default * browser driver behavior * * @param caps - the FirefoxProfile object * @param options - the key: value pair map * @throws Exception */ private void processFFProfile(FirefoxProfile profile, Map<String, Object>[] options) throws Exception { for (int i = 0; i < options.length; i++) { Object[] keys = options[i].keySet().toArray(); Object[] values = options[i].values().toArray(); // same as Desired Caps except the following difference for (int j = 0; j < keys.length; j++) { if (values[j] instanceof Integer) { profile.setPreference(keys[j].toString(), (int) values[j]); } // etc... } } }
/** * Process Chrome Options method to override default browser * driver behavior * * @param caps - the ChromeOptions object * @param options - the key: value pair map * @throws Exception */ private void processCHOptions(ChromeOptions chOptions, Map<String, Object>[] options) throws Exception { for (int i = 0; i < options.length; i++) { Object[] keys = options[i].keySet().toArray(); Object[] values = options[i].values().toArray(); // same as Desired Caps except the following difference for (int j = 0; j < keys.length; j++) { if (values[j] instanceof Integer) { values[j] = (int) values[j]; chOptions.setExperimentalOption("prefs", options[i]); } // etc... } } }