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

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

There is a newer version: 4.31.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 org.openqa.selenium.firefox.FirefoxDriver.SystemProperty.BROWSER_LOGFILE;
import static org.openqa.selenium.firefox.FirefoxDriver.SystemProperty.DRIVER_USE_MARIONETTE;
import static org.openqa.selenium.firefox.FirefoxOptions.FIREFOX_OPTIONS;
import static org.openqa.selenium.remote.CapabilityType.PROXY;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.remote.CommandExecutor;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.FileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.service.DriverCommandExecutor;
import org.openqa.selenium.remote.service.DriverService;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

/**
 * An implementation of the {#link WebDriver} interface that drives Firefox.
 * 

* The best way to construct a {@code FirefoxDriver} with various options is to make use of the * {@link FirefoxOptions}, like so: * *

 *FirefoxOptions options = new FirefoxOptions()
 *    .setProfile(new FirefoxProfile());
 *WebDriver driver = new FirefoxDriver(options);
 * 
*/ public class FirefoxDriver extends RemoteWebDriver { public static final class SystemProperty { /** * System property that defines the location of the Firefox executable file. */ public static final String BROWSER_BINARY = "webdriver.firefox.bin"; /** * System property that defines the location of the file where Firefox log should be stored. */ public static final String BROWSER_LOGFILE = "webdriver.firefox.logfile"; /** * System property that defines the additional library path (Linux only). */ public static final String BROWSER_LIBRARY_PATH = "webdriver.firefox.library.path"; /** * System property that defines the profile that should be used as a template. * When the driver starts, it will make a copy of the profile it is using, * rather than using that profile directly. */ public static final String BROWSER_PROFILE = "webdriver.firefox.profile"; /** * System property that defines the location of the webdriver.xpi browser extension to install * in the browser. If not set, the prebuilt extension bundled with this class will be used. */ public static final String DRIVER_XPI_PROPERTY = "webdriver.firefox.driver"; /** * Boolean system property that instructs FirefoxDriver to use Marionette backend, * overrides any capabilities specified by the user */ public static final String DRIVER_USE_MARIONETTE = "webdriver.firefox.marionette"; } private static final Logger LOG = Logger.getLogger(FirefoxDriver.class.getName()); public static final String BINARY = "firefox_binary"; public static final String PROFILE = "firefox_profile"; public static final String MARIONETTE = "marionette"; protected FirefoxBinary binary; public FirefoxDriver() { this(new FirefoxOptions()); } public FirefoxDriver(FirefoxOptions options) { this(toExecutor(options), options.toCapabilities(), options.toCapabilities()); } /** * @deprecated Prefer {@link FirefoxOptions#setBinary(FirefoxBinary)}. */ @Deprecated public FirefoxDriver(FirefoxBinary binary) { this(new FirefoxOptions().setBinary(binary)); warnAboutDeprecatedConstructor("FirefoxBinary", "setBinary(binary)"); } public FirefoxDriver(FirefoxProfile profile) { this(new FirefoxOptions().setProfile(profile)); } /** * @deprecated Prefer {@link FirefoxOptions#setBinary(FirefoxBinary)}, and * {@link FirefoxOptions#setProfile(FirefoxProfile)}. */ @Deprecated public FirefoxDriver(FirefoxBinary binary, FirefoxProfile profile) { this(new FirefoxOptions().setBinary(binary).setProfile(profile)); warnAboutDeprecatedConstructor( "FirefoxBinary and FirefoxProfile", "setBinary(binary).setProfile(profile)"); } public FirefoxDriver(Capabilities desiredCapabilities) { this(getFirefoxOptions(desiredCapabilities).addCapabilities(desiredCapabilities)); } /** * @deprecated Prefer {@link FirefoxDriver#FirefoxDriver(FirefoxOptions)} */ @Deprecated public FirefoxDriver(Capabilities desiredCapabilities, Capabilities requiredCapabilities) { this(getFirefoxOptions(desiredCapabilities) .addCapabilities(desiredCapabilities) .addCapabilities(requiredCapabilities)); warnAboutDeprecatedConstructor( "Capabilities", "addCapabilities(capabilities)"); } /** * @deprecated Prefer {@link FirefoxOptions#setBinary(FirefoxBinary)}, * {@link FirefoxOptions#setProfile(FirefoxProfile)} */ @Deprecated public FirefoxDriver(FirefoxBinary binary, FirefoxProfile profile, Capabilities capabilities) { this(getFirefoxOptions(capabilities) .setBinary(binary) .setProfile(profile) .addCapabilities(capabilities)); warnAboutDeprecatedConstructor( "FirefoxBinary, FirefoxProfile, Capabilities", "setBinary(binary).setProfile(profile).addCapabilities(capabilities)"); } /** * @deprecated Prefer {@link FirefoxOptions#setBinary(FirefoxBinary)}, * {@link FirefoxOptions#setProfile(FirefoxProfile)} */ @Deprecated public FirefoxDriver( FirefoxBinary binary, FirefoxProfile profile, Capabilities desiredCapabilities, Capabilities requiredCapabilities) { this(getFirefoxOptions(desiredCapabilities) .setBinary(binary).setProfile(profile) .addCapabilities(desiredCapabilities) .addCapabilities(requiredCapabilities)); warnAboutDeprecatedConstructor( "FirefoxBinary, FirefoxProfile, Capabilities", "setBinary(binary).setProfile(profile).addCapabilities(capabilities)"); } private FirefoxDriver( CommandExecutor executor, Capabilities desiredCapabilities, Capabilities requiredCapabilities) { super(executor, dropCapabilities(desiredCapabilities).merge(dropCapabilities(requiredCapabilities))); } private static CommandExecutor toExecutor(FirefoxOptions options) { DriverService.Builder builder; if (options.isLegacy()) { builder = XpiDriverService.builder() .withBinary(options.getBinaryOrNull().orElseGet(FirefoxBinary::new)) .withProfile(options.getProfile()); } else { builder = new GeckoDriverService.Builder() .usingFirefoxBinary(options.getBinaryOrNull().orElseGet(FirefoxBinary::new)); } return new DriverCommandExecutor(builder.build()); } private static FirefoxOptions getFirefoxOptions(Capabilities capabilities) { FirefoxOptions options = new FirefoxOptions(); if (capabilities == null) { return options; } Object rawOptions = capabilities.getCapability(FIREFOX_OPTIONS); if (rawOptions != null) { if (rawOptions instanceof Map) { try { @SuppressWarnings("unchecked") Map map = (Map) rawOptions; rawOptions = FirefoxOptions.fromJsonMap(map); } catch (IOException e) { throw new WebDriverException(e); } } if (rawOptions != null && !(rawOptions instanceof FirefoxOptions)) { throw new WebDriverException( "Firefox option was set, but is not a FirefoxOption: " + rawOptions); } options = (FirefoxOptions) rawOptions; } Object marionette = capabilities.getCapability(MARIONETTE); if (marionette instanceof Boolean) { options.setLegacy(!(Boolean) marionette); } return options; } private void warnAboutDeprecatedConstructor(String arguments, String alternative) { LOG.warning(String.format( "The FirefoxDriver constructor taking %s has been deprecated. Please use the " + "FirefoxDriver(FirefoxOptions) constructor, configuring the FirefoxOptions like this: " + "new FirefoxOptions().%s", arguments, alternative)); } @Override public void setFileDetector(FileDetector detector) { throw new WebDriverException( "Setting the file detector only works on remote webdriver instances obtained " + "via RemoteWebDriver"); } private static boolean isLegacy(Capabilities desiredCapabilities) { Boolean forceMarionette = forceMarionetteFromSystemProperty(); if (forceMarionette != null) { return !forceMarionette; } Object marionette = desiredCapabilities.getCapability(MARIONETTE); return marionette instanceof Boolean && ! (Boolean) marionette; } private static Boolean forceMarionetteFromSystemProperty() { String useMarionette = System.getProperty(DRIVER_USE_MARIONETTE); if (useMarionette == null) { return null; } return Boolean.valueOf(useMarionette); } /** * Drops capabilities that we shouldn't send over the wire. * * Used for capabilities which aren't BeanToJson-convertable, and are only used by the local * launcher. */ private static Capabilities dropCapabilities(Capabilities capabilities) { if (capabilities == null) { return new DesiredCapabilities(); } DesiredCapabilities caps; if (isLegacy(capabilities)) { final Set toRemove = Sets.newHashSet(BINARY, PROFILE); caps = new DesiredCapabilities( Maps.filterKeys(capabilities.asMap(), key -> !toRemove.contains(key))); } else { caps = new DesiredCapabilities(capabilities); } // Ensure that the proxy is in a state fit to be sent to the extension Proxy proxy = Proxy.extractFrom(capabilities); if (proxy != null) { caps.setCapability(PROXY, proxy); } return caps; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy