Skip to content

Commit

Permalink
Adding Options object for use with Python FirefoxDriver
Browse files Browse the repository at this point in the history
This allows us to have a ChromeOptions like object for passing things to
GeckoDriver to control different aspects like profile, binary or arguments
for starting the browser.
  • Loading branch information
AutomatedTester committed Mar 15, 2016
1 parent 000621a commit dfab927
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 12 deletions.
102 changes: 102 additions & 0 deletions py/selenium/webdriver/firefox/options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# 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.

import os
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
import base64


class Options(object):

def __init__(self):
self._binary_location = ''
self._profile = None
self._arguments = []
self._extension_files = []
self._extensions = []
self._firefox_options = {}

@property
def binary_location(self):
"""
Returns the location of the binary otherwise an empty string
"""
return self._binary_location

@binary_location.setter
def binary_location(self, value):
"""
Allows you to set where the firefox binary lives
:Args:
- value: path to the firefox binary
"""
self._binary_location = value

@property
def arguments(self):
"""
Returns a list of arguments needed for the browser
"""
return self._arguments

def add_argument(self, argument):
"""
Adds an argument to the list
:Args:
- Sets the arguments
"""
if argument:
self._arguments.append(argument)
else:
raise ValueError("argument can not be null")

@property
def profile(self):
"""
Returns a FirefoxProfile object if one has been set before else None
"""
return self._profile

@profile.setter
def profile(self, value):
if not isinstance(value, FirefoxProfile):
raise WebDriverException("When passing in a value to profile,"
" please pass in a FirefoxProfile object.")
self._profile = value

def to_capabilities(self):
"""
Creates a capabilities with all the options that have been set and
returns a dictionary with everything
"""
firefox = DesiredCapabilities.FIREFOX.copy()
firefox_options = self._firefox_options
if self.binary_location:
firefox_options["binary"] = self.binary_location
if self._profile:
firefox_options["profile"] = self._profile
firefox_options["args"] = self.arguments

firefox["requiredCapabilities"] = firefox_options

return firefox
43 changes: 31 additions & 12 deletions py/selenium/webdriver/firefox/webdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
from .service import Service
from .options import Options


class WebDriver(RemoteWebDriver):
Expand All @@ -40,26 +41,38 @@ class WebDriver(RemoteWebDriver):
NATIVE_EVENTS_ALLOWED = sys.platform != "darwin"

def __init__(self, firefox_profile=None, firefox_binary=None, timeout=30,
capabilities=None, proxy=None, executable_path="wires"):
self.binary = firefox_binary
capabilities=None, proxy=None, executable_path="wires", firefox_options=None):
self.profile = firefox_profile
self.binary = firefox_binary
if firefox_options is None:

if self.profile is None:
self.profile = FirefoxProfile()
if self.profile is None:
self.profile = FirefoxProfile()

self.profile.native_events_enabled = (
self.NATIVE_EVENTS_ALLOWED and self.profile.native_events_enabled)
self.profile.native_events_enabled = (
self.NATIVE_EVENTS_ALLOWED and self.profile.native_events_enabled)

if capabilities is None:
capabilities = DesiredCapabilities.FIREFOX
if capabilities is None:
capabilities = DesiredCapabilities.FIREFOX

if self.binary is None:
self.binary = capabilities.get("binary") or FirefoxBinary()
if self.binary is None:
self.binary = capabilities.get("binary") or FirefoxBinary()

firefox_options = Options()
firefox_options.binary_location = self.binary if isinstance(self.binary, basestring) else self.binary._get_firefox_start_cmd()
firefox_options.profile = self.profile
else:
if capabilities is None:
capabilities = firefox_options.to_capabilities()
else:
capabilities.update(firefox_options.to_capabilities())

# marionette
if capabilities.get("marionette"):
if isinstance(self.binary, FirefoxBinary):
self.binary = self.binary._get_firefox_start_cmd()
self.binary = firefox_options.binary_location
if isinstance(firefox_options.binary_location, FirefoxBinary):
self.binary = firefox_options.binary_location._get_firefox_start_cmd()

self.service = Service(executable_path, firefox_binary=self.binary)
self.service.start()

Expand All @@ -75,6 +88,12 @@ def __init__(self, firefox_profile=None, firefox_binary=None, timeout=30,
if proxy is not None:
proxy.add_to_capabilities(capabilities)

if self.binary is None:
self.binary = firefox_options.binary_location or FirefoxBinary()

if self.profile is None:
self.profile = firefox_options.profile or FirefoxProfile()

executor = ExtensionConnection("127.0.0.1", self.profile,
self.binary, timeout)
RemoteWebDriver.__init__(self,
Expand Down
53 changes: 53 additions & 0 deletions py/test/selenium/webdriver/firefox/mn_options_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# 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.


import pytest

from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

from selenium.test.selenium.webdriver.common.webserver import SimpleWebServer

class TestOptions:

def setup_method(self, method):
self.firefox_capabilities = DesiredCapabilities.FIREFOX
self.firefox_capabilities['marionette'] = True
self.driver = None

def test_we_can_pass_options(self):
options = Options()
self.driver = webdriver.Firefox(firefox_options=options)
self.driver.get(self.webserver.where_is('formPage.html'))
self.driver.find_element_by_id("cheese")

def teardown_method(self, method):
try:

self.driver.quit()
except:
pass # Don't care since we may have killed the browser above


def teardown_module(module):
try:
TestOptions.driver.quit()
except:
pass # Don't Care since we may have killed the browser above

0 comments on commit dfab927

Please sign in to comment.