Repository: robotframework/SeleniumLibrary
Pull request #1241 (2018-11-23 09:01:41)

Cover Element should cover all matching elements
For specific element we'll need to use specific locator


Patch:
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 3972c345..05a24933 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -88,6 +88,12 @@ We do, however, recommend to create dedicated branches for pull requests
 instead of creating them based on the master branch. This is especially
 important if you plan to work on multiple pull requests at the same time.
 
+This project requires that pull request contains linear history of commits and
+we do not allow that pull request contains merge commits or other noise. This helps
+the review process and makes the maintenance easier for the project administrators.
+Generally it is recommended to do `git pull --rebase`  instead of the `git pull --merge`
+when there is need pull changes from upstream.
+
 Coding conventions
 ------------------
 
diff --git a/src/SeleniumLibrary/keywords/element.py b/src/SeleniumLibrary/keywords/element.py
index 9de1dd4d..23a9b52d 100644
--- a/src/SeleniumLibrary/keywords/element.py
+++ b/src/SeleniumLibrary/keywords/element.py
@@ -17,9 +17,11 @@
 from selenium.webdriver.common.action_chains import ActionChains
 from selenium.webdriver.common.keys import Keys
 
+
 from SeleniumLibrary.base import LibraryComponent, keyword
 from SeleniumLibrary.utils import (is_falsy, is_noney, is_truthy,
                                    plural_or_not as s)
+from SeleniumLibrary.errors import ElementNotFound
 
 
 class ElementKeywords(LibraryComponent):
@@ -430,7 +432,7 @@ class ElementKeywords(LibraryComponent):
 
     @keyword
     def cover_element(self, locator):
-        """Will cover element identified by ``locator`` with a blue div without breaking page layout.
+        """Will cover elements identified by ``locator`` with a blue div without breaking page layout.
         
         See the `Locating elements` section for details about the locator
         syntax.
@@ -440,8 +442,12 @@ class ElementKeywords(LibraryComponent):
         Example:
         |`Cover Element` | css:div#container |
         """
-        element = self.find_element(locator)
-        script = """
+        elements = self.find_elements(locator)
+        if not elements:
+            raise ElementNotFound("No element with locator '%s' found."
+                                  % locator)
+        for element in elements:
+            script = """
 old_element = arguments[0];
 let newDiv = document.createElement('div');
 newDiv.setAttribute("name", "covered");
@@ -455,7 +461,7 @@ old_element.parentNode.insertBefore(newDiv, old_element);
 old_element.remove();
 newDiv.parentNode.style.overflow = 'hidden';
         """
-        self.driver.execute_script(script, element)
+            self.driver.execute_script(script, element)
 
     @keyword
     def get_value(self, locator):
diff --git a/src/SeleniumLibrary/keywords/webdrivertools.py b/src/SeleniumLibrary/keywords/webdrivertools.py
index 3aa14dc8..e6da3016 100644
--- a/src/SeleniumLibrary/keywords/webdrivertools.py
+++ b/src/SeleniumLibrary/keywords/webdrivertools.py
@@ -50,7 +50,7 @@ class WebDriverCreator(object):
     def create_driver(self, browser, desired_capabilities, remote_url,
                       profile_dir=None):
         creation_method = self._get_creator_method(browser)
-        desired_capabilities = self._parse_capabilities(desired_capabilities)
+        desired_capabilities = self._parse_capabilities(desired_capabilities, browser)
         if (creation_method == self.create_firefox
                 or creation_method == self.create_headless_firefox):
             return creation_method(desired_capabilities, remote_url,
@@ -63,7 +63,7 @@ class WebDriverCreator(object):
             return getattr(self, 'create_{}'.format(self.browser_names[browser]))
         raise ValueError('{} is not a supported browser.'.format(browser))
 
-    def _parse_capabilities(self, capabilities):
+    def _parse_capabilities(self, capabilities, browser=None):
         if isinstance(capabilities, dict):
             return capabilities
         desired_capabilities = {}
@@ -72,18 +72,21 @@ class WebDriverCreator(object):
         for part in capabilities.split(','):
             key, value = part.split(':')
             desired_capabilities[key.strip()] = value.strip()
-        return desired_capabilities
+        browser_alias = {'googlechrome': "chrome", 'gc': "chrome",
+                         'headlesschrome': 'chrome', 'ff': 'firefox',
+                         'headlessfirefox': 'firefox',
+                         'internetexplorer': 'ie'}
+        browser = browser_alias.get(browser, browser)
+        if browser in ['ie', 'firefox', 'edge']:
+            return {'capabilities': desired_capabilities}
+        return {'desired_capabilities': desired_capabilities}
 
     def create_chrome(self, desired_capabilities, remote_url, options=None):
-        default = webdriver.DesiredCapabilities.CHROME
         if is_truthy(remote_url):
-            return self._remote(default, desired_capabilities, remote_url,
-                                options=options)
-        capabilities = self._combine_capabilites(default, desired_capabilities)
+            return self._remote(desired_capabilities, remote_url, options=options)
         if SELENIUM_VERSION.major >= 3 and SELENIUM_VERSION.minor >= 8:
-            return webdriver.Chrome(desired_capabilities=capabilities,
-                                    options=options)
-        return webdriver.Chrome(desired_capabilities=capabilities)
+            return webdriver.Chrome(options=options, **desired_capabilities)
+        return webdriver.Chrome(**desired_capabilities)
 
     def create_headless_chrome(self, desired_capabilities, remote_url):
         if SELENIUM_VERSION.major >= 3 and SELENIUM_VERSION.minor >= 8:
@@ -95,19 +98,16 @@ class WebDriverCreator(object):
 
     def create_firefox(self, desired_capabilities, remote_url, ff_profile_dir,
                        options=None):
-        default = webdriver.DesiredCapabilities.FIREFOX
         profile = self._get_ff_profile(ff_profile_dir)
         if is_truthy(remote_url):
-            return self._remote(default, desired_capabilities, remote_url,
+            return self._remote(desired_capabilities, remote_url,
                                 profile, options)
-        capabilities = self._combine_capabilites(default, desired_capabilities)
+        desired_capabilities.update(self._geckodriver_log)
         if SELENIUM_VERSION.major >= 3 and SELENIUM_VERSION.minor >= 8:
-            return webdriver.Firefox(capabilities=capabilities, options=options,
-                                     firefox_profile=profile,
-                                     **self._geckodriver_log)
-        return webdriver.Firefox(capabilities=capabilities,
-                                 firefox_profile=profile,
-                                 **self._geckodriver_log)
+            return webdriver.Firefox(options=options, firefox_profile=profile,
+                                     **desired_capabilities)
+        return webdriver.Firefox(firefox_profile=profile,
+                                 **desired_capabilities)
 
     def _get_ff_profile(self, ff_profile_dir):
         if is_falsy(ff_profile_dir):
@@ -131,73 +131,54 @@ class WebDriverCreator(object):
                                    ff_profile_dir, options)
 
     def create_ie(self, desired_capabilities, remote_url):
-        default = webdriver.DesiredCapabilities.INTERNETEXPLORER
         if is_truthy(remote_url):
-            return self._remote(default, desired_capabilities, remote_url)
-        capabilities = self._combine_capabilites(default, desired_capabilities)
-        return webdriver.Ie(capabilities=capabilities)
+            return self._remote(desired_capabilities, remote_url)
+        return webdriver.Ie(**desired_capabilities)
 
     def create_edge(self, desired_capabilities, remote_url):
-        default = webdriver.DesiredCapabilities.EDGE
         if is_truthy(remote_url):
-            return self._remote(default, desired_capabilities, remote_url)
-        capabilities = self._combine_capabilites(default, desired_capabilities)
-        return webdriver.Edge(capabilities=capabilities)
+            return self._remote(desired_capabilities, remote_url)
+        return webdriver.Edge(**desired_capabilities)
 
     def create_opera(self, desired_capabilities, remote_url):
-        default = webdriver.DesiredCapabilities.OPERA
         if is_truthy(remote_url):
-            return self._remote(default, desired_capabilities, remote_url)
-        capabilities = self._combine_capabilites(default, desired_capabilities)
-        return webdriver.Opera(desired_capabilities=capabilities)
+            return self._remote(desired_capabilities, remote_url)
+        return webdriver.Opera(**desired_capabilities)
 
     def create_safari(self, desired_capabilities, remote_url):
-        default = webdriver.DesiredCapabilities.SAFARI
         if is_truthy(remote_url):
-            return self._remote(default, desired_capabilities, remote_url)
-        capabilities = self._combine_capabilites(default, desired_capabilities)
-        return webdriver.Safari(desired_capabilities=capabilities)
+            return self._remote(desired_capabilities, remote_url)
+        return webdriver.Safari(**desired_capabilities)
 
     def create_phantomjs(self, desired_capabilities, remote_url):
-        default = webdriver.DesiredCapabilities.PHANTOMJS
         if is_truthy(remote_url):
-            return self._remote(default, desired_capabilities, remote_url)
-        capabilities = self._combine_capabilites(default, desired_capabilities)
-        return webdriver.PhantomJS(desired_capabilities=capabilities)
+            return self._remote(desired_capabilities, remote_url)
+        return webdriver.PhantomJS(**desired_capabilities)
 
     def create_htmlunit(self, desired_capabilities, remote_url):
-        default = webdriver.DesiredCapabilities.HTMLUNIT
-        return self._remote(default, desired_capabilities, remote_url)
+        return self._remote(desired_capabilities, remote_url)
 
     def create_htmlunit_with_js(self, desired_capabilities, remote_url):
-        default = webdriver.DesiredCapabilities.HTMLUNITWITHJS
-        return self._remote(default, desired_capabilities, remote_url)
+        return self._remote(desired_capabilities, remote_url)
 
     def create_android(self, desired_capabilities, remote_url):
-        default = webdriver.DesiredCapabilities.ANDROID
-        return self._remote(default, desired_capabilities, remote_url)
+        return self._remote(desired_capabilities, remote_url)
 
     def create_iphone(self, desired_capabilities, remote_url):
-        default = webdriver.DesiredCapabilities.IPHONE
-        return self._remote(default, desired_capabilities, remote_url)
+        return self._remote(desired_capabilities, remote_url)
 
-    def _remote(self, default_capabilities, user_capabilities, remote_url,
+    def _remote(self, desired_capabilities, remote_url,
                 profile_dir=None, options=None):
         remote_url = str(remote_url)
-        capabilities = self._combine_capabilites(default_capabilities,
-                                                 user_capabilities)
+        if 'capabilities' in desired_capabilities:
+            desired_capabilities['desired_capabilities'] = desired_capabilities.pop('capabilities')
         if SELENIUM_VERSION.major >= 3 and SELENIUM_VERSION.minor >= 8:
             return webdriver.Remote(command_executor=remote_url,
-                                    desired_capabilities=capabilities,
-                                    browser_profile=profile_dir, options=options)
+                                    browser_profile=profile_dir, options=options,
+                                    **desired_capabilities)
         return webdriver.Remote(command_executor=remote_url,
-                                desired_capabilities=capabilities,
-                                browser_profile=profile_dir)
-
-    def _combine_capabilites(self, default, user):
-        default = default.copy()
-        default.update(user)
-        return default
+                                browser_profile=profile_dir,
+                                **desired_capabilities)
 
 
 class WebDriverCache(ConnectionCache):


Test patch:
diff --git a/atest/README.rst b/atest/README.rst
index 72af08df..a8cbf7f7 100644
--- a/atest/README.rst
+++ b/atest/README.rst
@@ -22,7 +22,7 @@ acceptance tests with Robot Framework. This includes:
 
 To run unit and acceptance tests, run::
 
-    python test/run.py <browser>
+    python atest/run.py <browser>
 
 Acceptance tests are executed using Robot Framework and results verified
 automatically afterwards using `robotstatuschecker`_ tool. Please visit
@@ -69,16 +69,20 @@ Examples::
 To run just the unit tests, run::
 
     python utest/run.py
+    
+To full list of options run::
+
+    python atest/run.py --help
 
 Travis CI integration
 ---------------------
 `Travis CI`_ is used to automatically test all new pull request to the
 repository. The detailed information about execution matrix can be found
 from the `.travis.yam`_. Generally speaking the test are automatically run
-by using Chrome and Firefox browsers. The project uses Python 2.7, Python 3.3,
-Python 3.6 and PyPy 3.5 for test execution. The project uses Selenium 2.53.6
-and latest available Selenium 3 version for test execution. Test uses
-Robot Framework versions 2.8.7, 2.9.2 and 3.0.2 for acceptance test execution.
+by using Chrome and Firefox browsers. The project uses Python 2.7, Python 3.4,
+Python 3.6 and PyPy 3.5 for test execution. The project uses and latest available 
+Selenium 3 version for test execution. Test uses Robot Framework versions 
+2.9.2 and 3.0.2 for acceptance test execution.
 
 .. _browser driver: https://github.com/robotframework/SeleniumLibrary#browser-drivers
 .. _PATH: https://en.wikipedia.org/wiki/PATH_(variable)
diff --git a/atest/acceptance/keywords/content_assertions.robot b/atest/acceptance/keywords/content_assertions.robot
index 1da28e50..4a9c02fb 100644
--- a/atest/acceptance/keywords/content_assertions.robot
+++ b/atest/acceptance/keywords/content_assertions.robot
@@ -374,5 +374,5 @@ Page Should Not Contain Button In Input Tag
 Get All Links
     [Setup]    Go To Page "links.html"
     ${links}=    Get All Links
-    Length Should Be    ${links}    19
+    Length Should Be    ${links}    20
     List Should Contain Value    ${links}    bold_id
diff --git a/atest/acceptance/keywords/counting_elements.robot b/atest/acceptance/keywords/counting_elements.robot
index fd27d3c4..f5561b6c 100644
--- a/atest/acceptance/keywords/counting_elements.robot
+++ b/atest/acceptance/keywords/counting_elements.robot
@@ -9,12 +9,12 @@ Get Matching XPath Count
     [Documentation]    Deprecated
     [Setup]    Go To Page "links.html"
     ${count}=    Get Matching XPath Count    //a
-    Should Be Equal    ${count}    19
+    Should Be Equal    ${count}    20
     ${count}=    Get Matching XPath Count    //a    ${True}
-    Should Be Equal    ${count}    19
+    Should Be Equal    ${count}    20
     Should Be String    ${count}
     ${count}=    Get Matching XPath Count    //a    ${False}
-    Should Be Equal    ${count}    ${19}
+    Should Be Equal    ${count}    ${20}
     Should Not Be String    ${count}
     ${count}=    Get Matching XPath Count    //div[@id="first_div"]/a
     Should Be Equal    ${count}    2
diff --git a/atest/acceptance/keywords/elements.robot b/atest/acceptance/keywords/elements.robot
index eecadf17..7dc23851 100644
--- a/atest/acceptance/keywords/elements.robot
+++ b/atest/acceptance/keywords/elements.robot
@@ -7,7 +7,7 @@ Library           String
 *** Test Cases ***
 Get Elements
     @{links}=    Get WebElements    //div[@id="div_id"]/a
-    Length Should Be    ${links}    11
+    Length Should Be    ${links}    12
     ${no_elements} =     Get WebElements    id:non_existing_elem
     Should Be Empty    ${no_elements}
 
@@ -107,3 +107,19 @@ Cover Element
     Cover Element  //img[@src="image.jpg"]
     Element Should Not be Visible  //img[@src="image.jpg"]
     Element Should be Visible  //div[@name="covered"]
+
+Cover Element should cover all matching elements
+    Cover Element  //img[@src="image.jpg"]
+    Element Should Not be Visible  //img[@src="image.jpg"]
+    ${count}  Get Element Count  //div[@name="covered"]
+    Should Be equal As Integers  ${count}  2
+
+Cover Element can cover just one element
+    Cover Element  (//img[@src="image.jpg"])[1]
+    Element Should be Visible  //img[@src="image.jpg"]
+    ${count}  Get Element Count  //div[@name="covered"]
+    Should Be equal As Integers  ${count}  1
+
+Cover Elements should throw exception when locator is invalid
+    Run Keyword And Expect Error  No element with locator '//img[@src="inexistent"]' found.
+    ...  Cover Element  //img[@src="inexistent"]
\ No newline at end of file
diff --git a/atest/resources/html/links.html b/atest/resources/html/links.html
index edddc64c..bf38d6a4 100644
--- a/atest/resources/html/links.html
+++ b/atest/resources/html/links.html
@@ -10,6 +10,7 @@
       <a href="http://www.google.com">Absolute external link</a><br/>
       <a id="some_id" href="broken.html">Link with id</a><br/>
       <a href="index.html"><img src="image.jpg" id="image_id"/></a><br/>
+      <a href="index.html"><img src="image.jpg" id="image1_id"/></a><br/>
       <a href="index.html"><img src="robot.png" alt="tooltip"/></a><br/>
       <a href="index.html" id="foo"><img src="robot.png"/>Text and image</a><br/>
       <a href="index.html">Link with double " quote</a><br/>
diff --git a/atest/run.py b/atest/run.py
index 60af2658..23ad3ca3 100755
--- a/atest/run.py
+++ b/atest/run.py
@@ -158,7 +158,7 @@ def get_sauce_conf(browser, sauce_username, sauce_key):
             sauce_username, sauce_key
         ),
         '--variable',
-        'DESIRED_CAPABILITIES:build:{0}-{1},tunnel-identifier:{0}'.format(
+        'DESIRED_CAPABILITIES:build:{0}-{1},tunnel-identifier:{0},browserName:{1}'.format(
             TRAVIS_JOB_NUMBER, browser
         )
     ]
diff --git a/utest/test/keywords/test_browsermanagement.py b/utest/test/keywords/test_browsermanagement.py
index 19473a00..e92c9a12 100644
--- a/utest/test/keywords/test_browsermanagement.py
+++ b/utest/test/keywords/test_browsermanagement.py
@@ -59,12 +59,7 @@ class BrowserManagementTests(unittest.TestCase):
         ctx = mock()
         ctx.speed = 5.0
         browser = mock()
-        caps = webdriver.DesiredCapabilities.CHROME
-        if SELENIUM_VERSION.major >= 3 and SELENIUM_VERSION.minor >= 8:
-            when(webdriver).Chrome(desired_capabilities=caps,
-                                   options=None).thenReturn(browser)
-        else:
-            when(webdriver).Chrome(desired_capabilities=caps).thenReturn(browser)
+        when(webdriver).Chrome(options=None).thenReturn(browser)
         bm = BrowserManagementKeywords(ctx)
         bm.open_browser('http://robotframework.org/', 'chrome')
         self.assertEqual(browser._speed, 5.0)
@@ -74,12 +69,7 @@ class BrowserManagementTests(unittest.TestCase):
         ctx = mock()
         ctx.speed = 0.0
         browser = mock()
-        caps = webdriver.DesiredCapabilities.CHROME
-        if SELENIUM_VERSION.major >= 3 and SELENIUM_VERSION.minor >= 8:
-            when(webdriver).Chrome(desired_capabilities=caps,
-                                   options=None).thenReturn(browser)
-        else:
-            when(webdriver).Chrome(desired_capabilities=caps).thenReturn(browser)
+        when(webdriver).Chrome(options=None).thenReturn(browser)
         bm = BrowserManagementKeywords(ctx)
         bm.open_browser('http://robotframework.org/', 'chrome')
         verify(browser, times=0).__call__('_speed')
diff --git a/utest/test/keywords/test_webdrivercreator.py b/utest/test/keywords/test_webdrivercreator.py
index d19e9e3c..7d7bea45 100644
--- a/utest/test/keywords/test_webdrivercreator.py
+++ b/utest/test/keywords/test_webdrivercreator.py
@@ -4,7 +4,6 @@ import unittest
 from mockito import mock, verify, when, unstub
 from selenium import webdriver
 
-from SeleniumLibrary.utils import SELENIUM_VERSION
 from SeleniumLibrary.keywords import WebDriverCreator
 
 
@@ -33,17 +32,31 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_parse_capabilities(self):
         caps = self.creator._parse_capabilities('key1:value1,key2:value2')
-        expected = {'key1': 'value1', 'key2': 'value2'}
+        expected = {'desired_capabilities': {'key1': 'value1', 'key2': 'value2'}}
+        self.assertDictEqual(caps, expected)
+
+        caps = self.creator._parse_capabilities('key1:value1,key2:value2', 'ie')
+        expected = {'capabilities': {'key1': 'value1', 'key2': 'value2'}}
+        self.assertDictEqual(caps, expected)
+
+        caps = self.creator._parse_capabilities('key1:value1,key2:value2', 'firefox')
+        self.assertDictEqual(caps, expected)
+
+        caps = self.creator._parse_capabilities('key1:value1,key2:value2', 'ff')
+        self.assertDictEqual(caps, expected)
+
+        caps = self.creator._parse_capabilities('key1:value1,key2:value2', 'edge')
         self.assertDictEqual(caps, expected)
 
         caps = self.creator._parse_capabilities(expected)
         self.assertDictEqual(caps, expected)
 
         caps = self.creator._parse_capabilities('key1 : value1 , key2: value2')
+        expected = {'desired_capabilities': {'key1': 'value1', 'key2': 'value2'}}
         self.assertDictEqual(caps, expected)
 
         caps = self.creator._parse_capabilities(' key 1 : value 1 , key2:value2')
-        expected = {'key 1': 'value 1', 'key2': 'value2'}
+        expected = {'desired_capabilities': {'key 1': 'value 1', 'key2': 'value2'}}
         self.assertDictEqual(caps, expected)
 
         caps = self.creator._parse_capabilities('')
@@ -54,43 +67,41 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_chrome(self):
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.CHROME
-        when(webdriver).Chrome(desired_capabilities=caps,
-                               options=None).thenReturn(expected_webdriver)
+        when(webdriver).Chrome(options=None).thenReturn(expected_webdriver)
         driver = self.creator.create_chrome({}, None)
         self.assertEqual(driver, expected_webdriver)
 
+    def test_chrome_with_desired_capabilities(self):
+        expected_webdriver = mock()
+        when(webdriver).Chrome(desired_capabilities={'key': 'value'}, options=None).thenReturn(expected_webdriver)
+        driver = self.creator.create_chrome({'desired_capabilities': {'key': 'value'}}, None)
+        self.assertEqual(driver, expected_webdriver)
+
     def test_chrome_remote(self):
         url = 'http://localhost:4444/wd/hub'
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.CHROME
         when(webdriver).Remote(command_executor=url,
-                               desired_capabilities=caps,
                                browser_profile=None,
                                options=None).thenReturn(expected_webdriver)
         driver = self.creator.create_chrome({}, url)
         self.assertEqual(driver, expected_webdriver)
 
     def test_chrome_healdless(self):
-        caps = webdriver.DesiredCapabilities.CHROME
         expected_webdriver = mock()
         options = mock()
         when(webdriver).ChromeOptions().thenReturn(options)
-        when(webdriver).Chrome(desired_capabilities=caps,
-                               options=options).thenReturn(expected_webdriver)
+        when(webdriver).Chrome(options=options).thenReturn(expected_webdriver)
         driver = self.creator.create_headless_chrome({}, None)
         verify(options).set_headless()
         self.assertEqual(driver, expected_webdriver)
 
     def test_chrome_healdless_with_grid(self):
-        caps = webdriver.DesiredCapabilities.CHROME
         expected_webdriver = mock()
         options = mock()
         when(webdriver).ChromeOptions().thenReturn(options)
         remote_url = 'localhost:4444'
         when(webdriver).Remote(command_executor=remote_url,
-                               desired_capabilities=caps, options=options,
-                               browser_profile=None,).thenReturn(expected_webdriver)
+                               options=options, browser_profile=None).thenReturn(expected_webdriver)
         driver = self.creator.create_headless_chrome({}, remote_url)
         verify(options).set_headless()
         self.assertEqual(driver, expected_webdriver)
@@ -99,9 +110,8 @@ class WebDriverCreatorTests(unittest.TestCase):
         expected_webdriver = mock()
         profile = mock()
         when(webdriver).FirefoxProfile().thenReturn(profile)
-        caps = webdriver.DesiredCapabilities.FIREFOX
         log_file = self.get_geckodriver_log()
-        when(webdriver).Firefox(capabilities=caps, options=None,
+        when(webdriver).Firefox(options=None,
                                 firefox_profile=profile,
                                 log_path=log_file).thenReturn(expected_webdriver)
         driver = self.creator.create_firefox({}, None, None)
@@ -113,9 +123,7 @@ class WebDriverCreatorTests(unittest.TestCase):
         profile = mock()
         when(webdriver).FirefoxProfile().thenReturn(profile)
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.FIREFOX
         when(webdriver).Remote(command_executor=url,
-                               desired_capabilities=caps,
                                browser_profile=profile,
                                options=None).thenReturn(expected_webdriver)
         driver = self.creator.create_firefox({}, url, None)
@@ -126,56 +134,58 @@ class WebDriverCreatorTests(unittest.TestCase):
         profile = mock()
         profile_dir = '/profile/dir'
         when(webdriver).FirefoxProfile(profile_dir).thenReturn(profile)
-        caps = webdriver.DesiredCapabilities.FIREFOX
         log_file = self.get_geckodriver_log()
-        when(webdriver).Firefox(capabilities=caps, options=None,
-                                log_path=log_file,
+        when(webdriver).Firefox(options=None, log_path=log_file,
                                 firefox_profile=profile).thenReturn(expected_webdriver)
         driver = self.creator.create_firefox({}, None, profile_dir)
         self.assertEqual(driver, expected_webdriver)
 
     def test_firefox_headless(self):
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.FIREFOX
         profile = mock()
         when(webdriver).FirefoxProfile().thenReturn(profile)
         options = mock()
         when(webdriver).FirefoxOptions().thenReturn(options)
         log_file = self.get_geckodriver_log()
-        when(webdriver).Firefox(capabilities=caps, options=options,
-                                log_path=log_file,
+        when(webdriver).Firefox(options=options, log_path=log_file,
                                 firefox_profile=profile).thenReturn(expected_webdriver)
         driver = self.creator.create_headless_firefox({}, None, None)
         self.assertEqual(driver, expected_webdriver)
 
     def test_firefox_healdless_with_grid(self):
-        caps = webdriver.DesiredCapabilities.FIREFOX
         expected_webdriver = mock()
         options = mock()
         when(webdriver).FirefoxOptions().thenReturn(options)
         profile = mock()
         when(webdriver).FirefoxProfile().thenReturn(profile)
         remote_url = 'localhost:4444'
-        when(webdriver).Remote(command_executor=remote_url,
-                               desired_capabilities=caps, options=options,
+        when(webdriver).Remote(command_executor=remote_url, options=options,
+                               desired_capabilities={'key': 'value'},
                                browser_profile=profile,).thenReturn(expected_webdriver)
-        driver = self.creator.create_headless_firefox({}, remote_url, None)
+        driver = self.creator.create_headless_firefox({'capabilities': {'key': 'value'}}, remote_url, None)
         verify(options).set_headless()
         self.assertEqual(driver, expected_webdriver)
 
+        when(webdriver).Remote(command_executor=remote_url, options=options,
+                               browser_profile=profile, ).thenReturn(expected_webdriver)
+        driver = self.creator.create_headless_firefox({}, remote_url, None)
+        self.assertEqual(driver, expected_webdriver)
+        verify(options, times=2).set_headless()
+
     def test_ie(self):
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.INTERNETEXPLORER
-        when(webdriver).Ie(capabilities=caps).thenReturn(expected_webdriver)
+        when(webdriver).Ie().thenReturn(expected_webdriver)
         driver = self.creator.create_ie({}, None)
         self.assertEqual(driver, expected_webdriver)
 
+        when(webdriver).Ie(capabilities={'key': 'value'}).thenReturn(expected_webdriver)
+        driver = self.creator.create_ie({'capabilities': {'key': 'value'}}, None)
+        self.assertEqual(driver, expected_webdriver)
+
     def test_ie_remote(self):
         url = 'http://localhost:4444/wd/hub'
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.INTERNETEXPLORER
         when(webdriver).Remote(command_executor=url,
-                               desired_capabilities=caps,
                                browser_profile=None,
                                options=None).thenReturn(expected_webdriver)
         driver = self.creator.create_ie({}, url)
@@ -183,17 +193,14 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_edge(self):
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.EDGE
-        when(webdriver).Edge(capabilities=caps).thenReturn(expected_webdriver)
+        when(webdriver).Edge().thenReturn(expected_webdriver)
         driver = self.creator.create_edge({}, None)
         self.assertEqual(driver, expected_webdriver)
 
     def test_edge_remote(self):
         url = 'http://localhost:4444/wd/hub'
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.EDGE
         when(webdriver).Remote(command_executor=url,
-                               desired_capabilities=caps,
                                browser_profile=None,
                                options=None).thenReturn(expected_webdriver)
         driver = self.creator.create_edge({}, url)
@@ -201,17 +208,14 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_opera(self):
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.OPERA
-        when(webdriver).Opera(desired_capabilities=caps).thenReturn(expected_webdriver)
+        when(webdriver).Opera().thenReturn(expected_webdriver)
         driver = self.creator.create_opera({}, None)
         self.assertEqual(driver, expected_webdriver)
 
     def test_opera_remote(self):
         url = 'http://localhost:4444/wd/hub'
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.OPERA
         when(webdriver).Remote(command_executor=url,
-                               desired_capabilities=caps,
                                browser_profile=None,
                                options=None).thenReturn(expected_webdriver)
         driver = self.creator.create_opera({}, url)
@@ -219,17 +223,14 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_safari(self):
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.SAFARI
-        when(webdriver).Safari(desired_capabilities=caps).thenReturn(expected_webdriver)
+        when(webdriver).Safari().thenReturn(expected_webdriver)
         driver = self.creator.create_safari({}, None)
         self.assertEqual(driver, expected_webdriver)
 
     def test_safari_remote(self):
         url = 'http://localhost:4444/wd/hub'
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.SAFARI
         when(webdriver).Remote(command_executor=url,
-                               desired_capabilities=caps,
                                browser_profile=None,
                                options=None).thenReturn(expected_webdriver)
         driver = self.creator.create_safari({}, url)
@@ -237,17 +238,14 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_phantomjs(self):
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.PHANTOMJS
-        when(webdriver).PhantomJS(desired_capabilities=caps).thenReturn(expected_webdriver)
+        when(webdriver).PhantomJS().thenReturn(expected_webdriver)
         driver = self.creator.create_phantomjs({}, None)
         self.assertEqual(driver, expected_webdriver)
 
     def test_phantomjs_remote(self):
         url = 'http://localhost:4444/wd/hub'
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.PHANTOMJS
         when(webdriver).Remote(command_executor=url,
-                               desired_capabilities=caps,
                                browser_profile=None,
                                options=None).thenReturn(expected_webdriver)
         driver = self.creator.create_phantomjs({}, url)
@@ -255,9 +253,7 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_htmlunit(self):
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.HTMLUNIT
         when(webdriver).Remote(command_executor='None',
-                               desired_capabilities=caps,
                                browser_profile=None,
                                options=None).thenReturn(expected_webdriver)
         driver = self.creator.create_htmlunit({}, None)
@@ -265,9 +261,7 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_htmlunit_with_js(self):
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.HTMLUNITWITHJS
         when(webdriver).Remote(command_executor='None',
-                               desired_capabilities=caps,
                                browser_profile=None,
                                options=None).thenReturn(expected_webdriver)
         driver = self.creator.create_htmlunit_with_js({}, None)
@@ -275,9 +269,7 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_android(self):
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.ANDROID
         when(webdriver).Remote(command_executor='None',
-                               desired_capabilities=caps,
                                browser_profile=None,
                                options=None).thenReturn(expected_webdriver)
         driver = self.creator.create_android({}, None)
@@ -285,9 +277,7 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_iphone(self):
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.IPHONE
         when(webdriver).Remote(command_executor='None',
-                               desired_capabilities=caps,
                                browser_profile=None,
                                options=None).thenReturn(expected_webdriver)
         driver = self.creator.create_iphone({}, None)
@@ -295,9 +285,7 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_create_driver_chrome(self):
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.CHROME
-        when(webdriver).Chrome(desired_capabilities=caps,
-                                   options=None).thenReturn(expected_webdriver)
+        when(webdriver).Chrome(options=None).thenReturn(expected_webdriver)
         for browser in ['chrome', 'googlechrome', 'gc']:
             driver = self.creator.create_driver(browser, None, None)
             self.assertEqual(driver, expected_webdriver)
@@ -306,10 +294,8 @@ class WebDriverCreatorTests(unittest.TestCase):
         expected_webdriver = mock()
         profile = mock()
         when(webdriver).FirefoxProfile().thenReturn(profile)
-        caps = webdriver.DesiredCapabilities.FIREFOX
         log_file = self.get_geckodriver_log()
-        when(webdriver).Firefox(capabilities=caps, options=None,
-                                log_path=log_file,
+        when(webdriver).Firefox(options=None, log_path=log_file,
                                 firefox_profile=profile).thenReturn(expected_webdriver)
         for browser in ['ff', 'firefox']:
             driver = self.creator.create_driver(browser, None, None, None)
@@ -317,31 +303,10 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_create_driver_ie(self):
         expected_webdriver = mock()
-        caps = webdriver.DesiredCapabilities.INTERNETEXPLORER
-        when(webdriver).Ie(capabilities=caps).thenReturn(expected_webdriver)
+        when(webdriver).Ie().thenReturn(expected_webdriver)
         for browser in ['ie', 'Internet Explorer']:
             driver = self.creator.create_driver(browser, None, None)
             self.assertEqual(driver, expected_webdriver)
 
-    def test_combine_capabilites(self):
-        default = webdriver.DesiredCapabilities.CHROME.copy()
-        user = {'platform': 'Linux'}
-        combined = self.creator._combine_capabilites(default, user)
-        expected = default.copy()
-        expected['platform'] = 'Linux'
-        self.assertDictEqual(combined, expected)
-
-        combined = self.creator._combine_capabilites(default, {})
-        self.assertDictEqual(combined, default)
-
-        combined = self.creator._combine_capabilites({}, {})
-        self.assertDictEqual(combined, {})
-
-        with self.assertRaises(AttributeError):
-            self.creator._combine_capabilites('foo', 'bar')
-
-        with self.assertRaises(ValueError):
-            self.creator._combine_capabilites({}, 'bar')
-
     def get_geckodriver_log(self):
         return os.path.join(self.log_dir, 'geckodriver.log')