Skip to content

Commit dfab927

Browse files
Adding Options object for use with Python FirefoxDriver
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.
1 parent 000621a commit dfab927

File tree

3 files changed

+186
-12
lines changed

3 files changed

+186
-12
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Licensed to the Software Freedom Conservancy (SFC) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The SFC licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
import os
19+
from selenium.common.exceptions import WebDriverException
20+
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
21+
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
22+
import base64
23+
24+
25+
class Options(object):
26+
27+
def __init__(self):
28+
self._binary_location = ''
29+
self._profile = None
30+
self._arguments = []
31+
self._extension_files = []
32+
self._extensions = []
33+
self._firefox_options = {}
34+
35+
@property
36+
def binary_location(self):
37+
"""
38+
Returns the location of the binary otherwise an empty string
39+
"""
40+
return self._binary_location
41+
42+
@binary_location.setter
43+
def binary_location(self, value):
44+
"""
45+
Allows you to set where the firefox binary lives
46+
47+
:Args:
48+
- value: path to the firefox binary
49+
"""
50+
self._binary_location = value
51+
52+
@property
53+
def arguments(self):
54+
"""
55+
Returns a list of arguments needed for the browser
56+
"""
57+
return self._arguments
58+
59+
def add_argument(self, argument):
60+
"""
61+
Adds an argument to the list
62+
63+
:Args:
64+
- Sets the arguments
65+
"""
66+
if argument:
67+
self._arguments.append(argument)
68+
else:
69+
raise ValueError("argument can not be null")
70+
71+
@property
72+
def profile(self):
73+
"""
74+
Returns a FirefoxProfile object if one has been set before else None
75+
76+
"""
77+
return self._profile
78+
79+
@profile.setter
80+
def profile(self, value):
81+
if not isinstance(value, FirefoxProfile):
82+
raise WebDriverException("When passing in a value to profile,"
83+
" please pass in a FirefoxProfile object.")
84+
self._profile = value
85+
86+
def to_capabilities(self):
87+
"""
88+
Creates a capabilities with all the options that have been set and
89+
90+
returns a dictionary with everything
91+
"""
92+
firefox = DesiredCapabilities.FIREFOX.copy()
93+
firefox_options = self._firefox_options
94+
if self.binary_location:
95+
firefox_options["binary"] = self.binary_location
96+
if self._profile:
97+
firefox_options["profile"] = self._profile
98+
firefox_options["args"] = self.arguments
99+
100+
firefox["requiredCapabilities"] = firefox_options
101+
102+
return firefox

py/selenium/webdriver/firefox/webdriver.py

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
3333
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
3434
from .service import Service
35+
from .options import Options
3536

3637

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

4243
def __init__(self, firefox_profile=None, firefox_binary=None, timeout=30,
43-
capabilities=None, proxy=None, executable_path="wires"):
44-
self.binary = firefox_binary
44+
capabilities=None, proxy=None, executable_path="wires", firefox_options=None):
4545
self.profile = firefox_profile
46+
self.binary = firefox_binary
47+
if firefox_options is None:
4648

47-
if self.profile is None:
48-
self.profile = FirefoxProfile()
49+
if self.profile is None:
50+
self.profile = FirefoxProfile()
4951

50-
self.profile.native_events_enabled = (
51-
self.NATIVE_EVENTS_ALLOWED and self.profile.native_events_enabled)
52+
self.profile.native_events_enabled = (
53+
self.NATIVE_EVENTS_ALLOWED and self.profile.native_events_enabled)
5254

53-
if capabilities is None:
54-
capabilities = DesiredCapabilities.FIREFOX
55+
if capabilities is None:
56+
capabilities = DesiredCapabilities.FIREFOX
5557

56-
if self.binary is None:
57-
self.binary = capabilities.get("binary") or FirefoxBinary()
58+
if self.binary is None:
59+
self.binary = capabilities.get("binary") or FirefoxBinary()
60+
61+
firefox_options = Options()
62+
firefox_options.binary_location = self.binary if isinstance(self.binary, basestring) else self.binary._get_firefox_start_cmd()
63+
firefox_options.profile = self.profile
64+
else:
65+
if capabilities is None:
66+
capabilities = firefox_options.to_capabilities()
67+
else:
68+
capabilities.update(firefox_options.to_capabilities())
5869

5970
# marionette
6071
if capabilities.get("marionette"):
61-
if isinstance(self.binary, FirefoxBinary):
62-
self.binary = self.binary._get_firefox_start_cmd()
72+
self.binary = firefox_options.binary_location
73+
if isinstance(firefox_options.binary_location, FirefoxBinary):
74+
self.binary = firefox_options.binary_location._get_firefox_start_cmd()
75+
6376
self.service = Service(executable_path, firefox_binary=self.binary)
6477
self.service.start()
6578

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

91+
if self.binary is None:
92+
self.binary = firefox_options.binary_location or FirefoxBinary()
93+
94+
if self.profile is None:
95+
self.profile = firefox_options.profile or FirefoxProfile()
96+
7897
executor = ExtensionConnection("127.0.0.1", self.profile,
7998
self.binary, timeout)
8099
RemoteWebDriver.__init__(self,
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Licensed to the Software Freedom Conservancy (SFC) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The SFC licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
19+
import pytest
20+
21+
from selenium import webdriver
22+
from selenium.webdriver.firefox.options import Options
23+
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
24+
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
25+
26+
from selenium.test.selenium.webdriver.common.webserver import SimpleWebServer
27+
28+
class TestOptions:
29+
30+
def setup_method(self, method):
31+
self.firefox_capabilities = DesiredCapabilities.FIREFOX
32+
self.firefox_capabilities['marionette'] = True
33+
self.driver = None
34+
35+
def test_we_can_pass_options(self):
36+
options = Options()
37+
self.driver = webdriver.Firefox(firefox_options=options)
38+
self.driver.get(self.webserver.where_is('formPage.html'))
39+
self.driver.find_element_by_id("cheese")
40+
41+
def teardown_method(self, method):
42+
try:
43+
44+
self.driver.quit()
45+
except:
46+
pass # Don't care since we may have killed the browser above
47+
48+
49+
def teardown_module(module):
50+
try:
51+
TestOptions.driver.quit()
52+
except:
53+
pass # Don't Care since we may have killed the browser above

0 commit comments

Comments
 (0)