Firefox specific functionality

These are capabilities and features specific to Mozilla Firefox browsers.

Selenium 4 requires Firefox 78 or greater. It is recommended to always use the latest version of geckodriver.

Options

Capabilities common to all browsers are described on the Options page.

Capabilities unique to Firefox can be found at Mozilla’s page for firefoxOptions

Starting a Firefox session with basic defined options looks like this:

35
38
Show full example
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;





public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);driver.quit();
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());

    driver.quit();
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver();

    ((HasContext) driver).setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, ((HasContext) driver).getContext(),
            "The context should be 'chrome'"
    );

    driver.quit();
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);

    driver.quit();
  }
}
9
12
<details class="mt-3">
  <summary>Show full example</summary>
  <div class="pt-2">
    <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-py" data-lang="py"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span> <span style="color:#000">os</span>

import subprocess import sys import pytest from selenium import webdriver def test_basic_options(): options = webdriver.FirefoxOptions() driver = webdriver.Firefox(options=options) driver.quit() def test_arguments(): options = webdriver.FirefoxOptions() options.add_argument("-headless") driver = webdriver.Firefox(options=options) driver.quit() def test_set_browser_location(firefox_bin): options = webdriver.FirefoxOptions() options.binary_location = firefox_bin driver = webdriver.Firefox(options=options) driver.quit() def test_log_to_file(log_path): service = webdriver.FirefoxService(log_output=log_path, service_args=['–log', 'debug']) driver = webdriver.Firefox(service=service) driver.get("https://www.selenium.dev") with open(log_path, 'r') as fp: assert "geckodriver INFO Listening on" in fp.readline() driver.quit() def test_log_to_stdout(capfd): service = webdriver.FirefoxService(log_output=subprocess.STDOUT) driver = webdriver.Firefox(service=service) out, err = capfd.readouterr() assert "geckodriver INFO Listening on" in out driver.quit() def test_log_level(log_path): service = webdriver.FirefoxService(log_output=log_path, service_args=['–log', 'debug']) driver = webdriver.Firefox(service=service) with open(log_path, 'r') as f: assert '\tDEBUG' in f.read() driver.quit() def test_log_truncation(log_path): service = webdriver.FirefoxService(service_args=['–log-no-truncate', '–log', 'debug'], log_output=log_path) driver = webdriver.Firefox(service=service) with open(log_path, 'r') as f: assert ' … ' not in f.read() driver.quit() def test_profile_location(temp_dir): service = webdriver.FirefoxService(service_args=['–profile-root', temp_dir]) driver = webdriver.Firefox(service=service) profile_name = driver.capabilities.get('moz:profile').replace('\', '/').split('/')[-1] assert profile_name in os.listdir(temp_dir) driver.quit() def test_install_addon(firefox_driver, addon_path_xpi): driver = firefox_driver driver.install_addon(addon_path_xpi) driver.get("https://www.selenium.dev/selenium/web/blank.html") injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example") assert injected.text == "Content injected by webextensions-selenium-example" def test_uninstall_addon(firefox_driver, addon_path_xpi): driver = firefox_driver id = driver.install_addon(addon_path_xpi) driver.uninstall_addon(id) driver.get("https://www.selenium.dev/selenium/web/blank.html") assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0 def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir): driver = firefox_driver driver.install_addon(addon_path_dir, temporary=True) driver.get("https://www.selenium.dev/selenium/web/blank.html") injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example") assert injected.text == "Content injected by webextensions-selenium-example" def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash): driver = firefox_driver driver.install_addon(addon_path_dir_slash, temporary=True) driver.get("https://www.selenium.dev/selenium/web/blank.html") injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example") assert injected.text == "Content injected by webextensions-selenium-example" def test_full_page_screenshot(firefox_driver): driver = firefox_driver driver.get("https://www.selenium.dev") driver.save_full_page_screenshot("full_page_screenshot.png") assert os.path.exists("full_page_screenshot.png") driver.quit() def test_set_context(firefox_driver): driver = firefox_driver with driver.context(driver.CONTEXT_CHROME): driver.execute_script("console.log('Inside Chrome context');") # Check if the context is back to content assert driver.execute("GET_CONTEXT")["value"] == "content" def test_firefox_profile(): from selenium.webdriver.firefox.options import Options from selenium.webdriver.firefox.firefox_profile import FirefoxProfile options = Options() firefox_profile = FirefoxProfile() firefox_profile.set_preference("javascript.enabled", False) options.profile = firefox_profile driver = webdriver.Firefox(options=options) driver.quit()

<div class="text-end pb-2 mt-2">
  <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/display_full//examples/python/tests/browsers/test_firefox.py#L10-L11" target="_blank">
    <i class="fas fa-external-link-alt pl-2"></i>
    <strong>View full example on GitHub</strong>
  </a>
</div>
33
36
Show full example
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        [Ignore("Not implemented")]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            //service.LogFile = _logLocation

            driver = new FirefoxDriver(service);
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        [Ignore("Not implemented")]
        public void LogsToConsole()
        {
            var stringWriter = new StringWriter();
            var originalOutput = Console.Out;
            Console.SetOut(stringWriter);

            var service = FirefoxDriverService.CreateDefaultService();
            //service.LogToConsole = true;

            driver = new FirefoxDriver(service);
            Assert.IsTrue(stringWriter.ToString().Contains("geckodriver	INFO	Listening on"));
            Console.SetOut(originalOutput);
            stringWriter.Dispose();
        }

        [TestMethod]
        [Ignore("You can set it, just can't see it")]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            //service.LogFile = _logLocation

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        [Ignore("Not implemented")]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            //service.TruncateLogs = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        [Ignore("Not implemented")]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            // service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + "/" + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (_logLocation != null && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath != null && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPath();
        }
    }
}
9
12
Show full example
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
9
14
Show full example
const {Browser, Builder} = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');


describe('Open Firefox', function () {
  let driver;

  before(async function () {
    let options = new firefox.Options();
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Firefox test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});