All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openqa.selenium.firefox.FirefoxOptions Maven / Gradle / Ivy

Go to download

Selenium automates browsers. That's it! What you do with that power is entirely up to you.

There is a newer version: 4.20.0
Show newest version
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package org.openqa.selenium.firefox;

import static java.util.Objects.requireNonNull;
import static org.openqa.selenium.firefox.FirefoxDriver.BINARY;
import static org.openqa.selenium.firefox.FirefoxDriver.MARIONETTE;
import static org.openqa.selenium.firefox.FirefoxDriver.PROFILE;
import static org.openqa.selenium.remote.CapabilityType.ACCEPT_INSECURE_CERTS;
import static org.openqa.selenium.remote.CapabilityType.PAGE_LOAD_STRATEGY;
import static org.openqa.selenium.remote.CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.MutableCapabilities;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.remote.BrowserType;
import org.openqa.selenium.remote.CapabilityType;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.TreeMap;
import java.util.logging.Level;

/**
 * Manage firefox specific settings in a way that geckodriver can understand.
 * 

* An example of usage: *

 *    FirefoxOptions options = new FirefoxOptions()
 *      .addPreference("browser.startup.page", 1)
 *      .addPreference("browser.startup.homepage", "https://www.google.co.uk");
 *    WebDriver driver = new FirefoxDriver(options);
 * 
*/ public class FirefoxOptions extends MutableCapabilities { public final static String FIREFOX_OPTIONS = "moz:firefoxOptions"; private List args = new ArrayList<>(); private Map booleanPrefs = new TreeMap<>(); private Map intPrefs = new TreeMap<>(); private Map stringPrefs = new TreeMap<>(); private FirefoxDriverLogLevel logLevel; private Binary binary; private boolean legacy; private FirefoxProfile profile; public FirefoxOptions() { // Read system properties and use those if they are set, allowing users to override them later // should they want to. String binary = System.getProperty(FirefoxDriver.SystemProperty.BROWSER_BINARY); if (binary != null) { setBinary(binary); } String profileName = System.getProperty(FirefoxDriver.SystemProperty.BROWSER_PROFILE); if (profileName != null) { FirefoxProfile profile = new ProfilesIni().getProfile(profileName); if (profile == null) { throw new WebDriverException(String.format( "Firefox profile '%s' named in system property '%s' not found", profileName, FirefoxDriver.SystemProperty.BROWSER_PROFILE)); } setProfile(profile); } String forceMarionette = System.getProperty(FirefoxDriver.SystemProperty.DRIVER_USE_MARIONETTE); if (forceMarionette != null) { setLegacy(!Boolean.getBoolean(FirefoxDriver.SystemProperty.DRIVER_USE_MARIONETTE)); } setCapability(CapabilityType.BROWSER_NAME, BrowserType.FIREFOX); setAcceptInsecureCerts(true); } public FirefoxOptions(Capabilities source) { // We need to initialize all our own fields before calling. super(); source.asMap().forEach((key, value)-> { if (value != null) { setCapability(key, value); } }); // If `source` has options, we need to mirror those into this instance. This may be either a // Map (if we're constructing from a serialized instance) or another FirefoxOptions. *sigh* Object raw = source.getCapability(FIREFOX_OPTIONS); if (raw == null) { return; } if (raw instanceof FirefoxOptions) { FirefoxOptions that = (FirefoxOptions) raw; addArguments(that.args); that.booleanPrefs.forEach(this::addPreference); that.intPrefs.forEach(this::addPreference); that.stringPrefs.forEach(this::addPreference); setLegacy(that.legacy); if (that.logLevel != null) { setLogLevel(that.logLevel); } if (that.binary != null) { setCapability(BINARY, that.binary.asCapability()); } if (that.profile != null) { setProfile(that.profile); } } else if (raw instanceof Map) { Map that = (Map) raw; if (that.containsKey("args")) { Object value = that.get("args"); if (value instanceof String) { addArguments((String) that.get("args")); } else if (value instanceof List) { addArguments((List) that.get("args")); } else { // last resort addArguments(that.get("args").toString()); } } if (that.containsKey("prefs")) { Map prefs = (Map) that.get("prefs"); prefs.forEach((k, v) -> { if (v instanceof String) { stringPrefs.put(k, (String) v); } else if (v instanceof Number) { intPrefs.put(k, ((Number) v).intValue()); } else if (v instanceof Boolean) { booleanPrefs.put(k, (Boolean) v); } }); } if (that.containsKey("binary")) { setBinary((String) that.get("binary")); } if (that.containsKey("log")) { Map logStruct = (Map) that.get("log"); Object rawLevel = logStruct.get("level"); if (rawLevel instanceof String) { setLogLevel(FirefoxDriverLogLevel.fromString((String) rawLevel)); } else if (rawLevel instanceof FirefoxDriverLogLevel) { setLogLevel((FirefoxDriverLogLevel) rawLevel); } } if (that.containsKey("profile")) { Object value = that.get("profile"); if (value instanceof String) { try { setProfile(FirefoxProfile.fromJson((String) value)); } catch (IOException e) { throw new WebDriverException(e); } } else if (value instanceof FirefoxProfile) { setProfile((FirefoxProfile) value); } else { throw new WebDriverException( "In FirefoxOptions, don't know how to convert profile: " + that); } } } } public FirefoxOptions setLegacy(boolean legacy) { setCapability(MARIONETTE, !legacy); return this; } public boolean isLegacy() { return legacy; } public FirefoxOptions setBinary(FirefoxBinary binary) { setCapability(BINARY, binary); return this; } public FirefoxOptions setBinary(Path path) { setCapability(BINARY, path); return this; } public FirefoxOptions setBinary(String path) { setCapability(BINARY, path); return this; } /** * Constructs a {@link FirefoxBinary} and returns that to be used, and because of this is only * useful when actually starting firefox. */ public FirefoxBinary getBinary() { return getBinaryOrNull().orElseGet(FirefoxBinary::new); } public Optional getBinaryOrNull() { return Optional.ofNullable(binary).map(Binary::asBinary); } public FirefoxOptions setProfile(FirefoxProfile profile) { setCapability(FirefoxDriver.PROFILE, profile); return this; } public FirefoxProfile getProfile() { return profile; } public FirefoxOptions addArguments(String... arguments) { addArguments(ImmutableList.copyOf(arguments)); return this; } public FirefoxOptions addArguments(List arguments) { args.addAll(arguments); return this; } public FirefoxOptions addPreference(String key, boolean value) { booleanPrefs.put(requireNonNull(key), value); return this; } public FirefoxOptions addPreference(String key, int value) { intPrefs.put(requireNonNull(key), value); return this; } public FirefoxOptions addPreference(String key, String value) { stringPrefs.put(requireNonNull(key), value); return this; } /** * @deprecated Use {@link #setLogLevel(FirefoxDriverLogLevel)} */ @Deprecated public FirefoxOptions setLogLevel(Level logLevel) { setLogLevel(FirefoxDriverLogLevel.fromLevel(logLevel)); return this; } public FirefoxOptions setLogLevel(FirefoxDriverLogLevel logLevel) { this.logLevel = Objects.requireNonNull(logLevel, "Log level must be set"); return this; } public FirefoxOptions setPageLoadStrategy(PageLoadStrategy strategy) { setCapability( PAGE_LOAD_STRATEGY, Objects.requireNonNull(strategy, "Page load strategy must be set")); return this; } public FirefoxOptions setUnhandledPromptBehaviour(UnexpectedAlertBehaviour behaviour) { setCapability( UNHANDLED_PROMPT_BEHAVIOUR, Objects.requireNonNull(behaviour, "Unhandled prompt behavior must be set")); return this; } public FirefoxOptions setAcceptInsecureCerts(boolean acceptInsecureCerts) { setCapability(ACCEPT_INSECURE_CERTS, acceptInsecureCerts); return this; } public FirefoxOptions setHeadless(boolean headless) { args.remove("-headless"); if (headless) { args.add("-headless"); } return this; } public FirefoxOptions setProxy(Proxy proxy) { setCapability(CapabilityType.PROXY, proxy); return this; } @Override public void setCapability(String key, Object value) { switch (key) { case BINARY: binary = new Binary(requireNonNull(value, "Binary value cannot be null")); value = binary.asCapability(); break; case MARIONETTE: if (value instanceof Boolean) { legacy = !(Boolean) value; } break; case PROFILE: if (value instanceof FirefoxProfile) { profile = (FirefoxProfile) value; } else if (value instanceof String) { try { profile = FirefoxProfile.fromJson((String) value); } catch (IOException e) { throw new WebDriverException(e); } value = profile; } else { throw new WebDriverException("Unexpected value for profile: " + value); } break; default: // Do nothing } super.setCapability(key, value); } @Override public Map asMap() { TreeMap toReturn = new TreeMap<>(super.asMap()); ImmutableSortedMap.Builder w3cOptions = ImmutableSortedMap.naturalOrder(); w3cOptions.put("args", args); if (binary != null) { w3cOptions.put("binary", binary.asPath()); } if (logLevel != null) { w3cOptions.put("log", ImmutableMap.of("level", logLevel)); } if (profile != null) { for (Map.Entry pref : booleanPrefs.entrySet()) { profile.setPreference(pref.getKey(), pref.getValue()); } for (Map.Entry pref : intPrefs.entrySet()) { profile.setPreference(pref.getKey(), pref.getValue()); } for (Map.Entry pref : stringPrefs.entrySet()) { profile.setPreference(pref.getKey(), pref.getValue()); } try { w3cOptions.put("profile", profile.toJson()); } catch (IOException e) { throw new WebDriverException(e); } } else { ImmutableMap.Builder allPrefs = ImmutableMap.builder(); allPrefs.putAll(booleanPrefs); allPrefs.putAll(intPrefs); allPrefs.putAll(stringPrefs); w3cOptions.put("prefs", allPrefs.build()); } toReturn.put(FIREFOX_OPTIONS, w3cOptions.build()); return toReturn; } @Override public FirefoxOptions merge(Capabilities capabilities) { super.merge(capabilities); return this; } @Override protected int amendHashCode() { return Objects.hash( args, booleanPrefs, intPrefs, stringPrefs, logLevel, binary, legacy, profile); } private class Binary { private String path; private FirefoxBinary binary; public Binary(Object value) { if (value instanceof FirefoxBinary) { this.binary = (FirefoxBinary) value; binary.amendOptions(FirefoxOptions.this); return; } if (value instanceof Path || value instanceof String) { this.path = value.toString().replace('\\', '/'); return; } throw new IllegalArgumentException("Unrecognised type for binary: " + value); } FirefoxBinary asBinary() { return binary == null ? new FirefoxBinary(new File(path)) : binary; } Object asCapability() { return binary == null ? path : binary; } String asPath() { return binary == null ? path : binary.getPath(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Binary)) { return false; } Binary that = (Binary) o; return Objects.equals(this.path, that.path) && Objects.equals(this.binary, that.binary); } @Override public int hashCode() { return Objects.hash(path, binary); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy