[py] allow setting capabilities within options classes

Cr-Mirrored-From: https://chromium.googlesource.com/external/github.com/SeleniumHQ/selenium
Cr-Mirrored-Commit: f23b516bf418752c0b557bc8f73d576cec706c14
diff --git a/selenium/webdriver/chrome/options.py b/selenium/webdriver/chrome/options.py
index 318b769..9d2bbbd 100644
--- a/selenium/webdriver/chrome/options.py
+++ b/selenium/webdriver/chrome/options.py
@@ -33,6 +33,7 @@
         self._extensions = []
         self._experimental_options = {}
         self._debugger_address = None
+        self._caps = DesiredCapabilities.CHROME.copy()
 
     @property
     def binary_location(self):
@@ -52,6 +53,14 @@
         self._binary_location = value
 
     @property
+    def capabilities(self):
+        return self._caps
+
+    def set_capability(self, name, value):
+        """Sets a capability."""
+        self._caps[name] = value
+
+    @property
     def debugger_address(self):
         """
         Returns the address of the remote devtools instance
@@ -188,8 +197,7 @@
 
             returns a dictionary with everything
         """
-        caps = DesiredCapabilities.CHROME.copy()
-
+        caps = self._caps
         chrome_options = self.experimental_options.copy()
         chrome_options["extensions"] = self.extensions
         if self.binary_location:
diff --git a/selenium/webdriver/edge/options.py b/selenium/webdriver/edge/options.py
index 24052a8..3964c52 100644
--- a/selenium/webdriver/edge/options.py
+++ b/selenium/webdriver/edge/options.py
@@ -22,6 +22,7 @@
 
     def __init__(self):
         self._page_load_strategy = "normal"
+        self._caps = DesiredCapabilities.EDGE.copy()
 
     @property
     def page_load_strategy(self):
@@ -33,13 +34,21 @@
             raise ValueError("Page Load Strategy should be 'normal', 'eager' or 'none'.")
         self._page_load_strategy = value
 
+    @property
+    def capabilities(self):
+        return self._caps
+
+    def set_capability(self, name, value):
+        """Sets a capability."""
+        self._caps[name] = value
+
     def to_capabilities(self):
         """
             Creates a capabilities with all the options that have been set and
 
             returns a dictionary with everything
         """
-        edge = DesiredCapabilities.EDGE.copy()
-        edge['pageLoadStrategy'] = self._page_load_strategy
+        caps = self._caps
+        caps['pageLoadStrategy'] = self._page_load_strategy
 
-        return edge
+        return caps
diff --git a/selenium/webdriver/firefox/options.py b/selenium/webdriver/firefox/options.py
index e9fb024..fd7b2d1 100644
--- a/selenium/webdriver/firefox/options.py
+++ b/selenium/webdriver/firefox/options.py
@@ -41,6 +41,7 @@
         self._preferences = {}
         self._profile = None
         self._proxy = None
+        self._caps = DesiredCapabilities.FIREFOX.copy()
         self._arguments = []
         self.log = Log()
 
@@ -70,6 +71,22 @@
         self.binary = value
 
     @property
+    def accept_insecure_certs(self):
+        return self._caps.get('acceptInsecureCerts')
+
+    @accept_insecure_certs.setter
+    def accept_insecure_certs(self, value):
+        self._caps['acceptInsecureCerts'] = value
+
+    @property
+    def capabilities(self):
+        return self._caps
+
+    def set_capability(self, name, value):
+        """Sets a capability."""
+        self._caps[name] = value
+
+    @property
     def preferences(self):
         """Returns a dict of preferences."""
         return self._preferences
@@ -150,7 +167,7 @@
         # so if a binary or profile has _not_ been set,
         # it will defer to geckodriver to find the system Firefox
         # and generate a fresh profile.
-        caps = DesiredCapabilities.FIREFOX.copy()
+        caps = self._caps
         opts = {}
 
         if self._binary is not None:
diff --git a/selenium/webdriver/ie/options.py b/selenium/webdriver/ie/options.py
index ff217d6..4dc82fd 100644
--- a/selenium/webdriver/ie/options.py
+++ b/selenium/webdriver/ie/options.py
@@ -47,6 +47,7 @@
         self._arguments = []
         self._options = {}
         self._additional = {}
+        self._caps = DesiredCapabilities.INTERNETEXPLORER.copy()
 
     @property
     def arguments(self):
@@ -65,6 +66,14 @@
         return self._options
 
     @property
+    def capabilities(self):
+        return self._caps
+
+    def set_capability(self, name, value):
+        """Sets a capability."""
+        self._caps[name] = value
+
+    @property
     def browser_attach_timeout(self):
         """ Returns the options Browser Attach Timeout in milliseconds """
         return self._options.get(self.BROWSER_ATTACH_TIMEOUT)
@@ -328,7 +337,7 @@
 
     def to_capabilities(self):
         """ Marshals the IE options to a the correct object """
-        caps = DesiredCapabilities.INTERNETEXPLORER.copy()
+        caps = self._caps
 
         opts = self._options.copy()
         if len(self._arguments) > 0:
diff --git a/selenium/webdriver/opera/options.py b/selenium/webdriver/opera/options.py
index a27fd22..3115356 100644
--- a/selenium/webdriver/opera/options.py
+++ b/selenium/webdriver/opera/options.py
@@ -27,6 +27,15 @@
         self._android_package_name = ''
         self._android_device_socket = ''
         self._android_command_line_file = ''
+        self._caps = DesiredCapabilities.OPERA.copy()
+
+    @property
+    def capabilities(self):
+        return self._caps
+
+    def set_capability(self, name, value):
+        """Sets a capability."""
+        self._caps[name] = value
 
     @property
     def android_package_name(self):
@@ -86,7 +95,7 @@
             returns a dictionary with everything
         """
         capabilities = ChromeOptions.to_capabilities(self)
-        capabilities.update(DesiredCapabilities.OPERA)
+        capabilities.update(self._caps)
         opera_options = capabilities[self.KEY]
 
         if self.android_package_name:
diff --git a/selenium/webdriver/webkitgtk/options.py b/selenium/webdriver/webkitgtk/options.py
index b8df73b..5752910 100644
--- a/selenium/webdriver/webkitgtk/options.py
+++ b/selenium/webdriver/webkitgtk/options.py
@@ -25,6 +25,15 @@
         self._binary_location = ''
         self._arguments = []
         self._overlay_scrollbars_enabled = True
+        self._caps = DesiredCapabilities.WEBKITGTK.copy()
+
+    @property
+    def capabilities(self):
+        return self._caps
+
+    def set_capability(self, name, value):
+        """Sets a capability."""
+        self._caps[name] = value
 
     @property
     def binary_location(self):
@@ -84,7 +93,7 @@
         Creates a capabilities with all the options that have been set and
         returns a dictionary with everything
         """
-        caps = DesiredCapabilities.WEBKITGTK.copy()
+        caps = self._caps
 
         browser_options = {}
         if self.binary_location: