Repository: robotframework/SeleniumLibrary
Pull request #1391 (2019-05-30 20:17:10)

Changed docs to point Python 3


Patch:
diff --git a/.gitignore b/.gitignore
index 31e12181..7fbb21ab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
 .pydevproject
 .idea
 atest/results
+utest/output_dir
 *.pyc
 *.orig
 *py.class
diff --git a/src/SeleniumLibrary/__init__.py b/src/SeleniumLibrary/__init__.py
index 7d126ff4..8d8e7d52 100644
--- a/src/SeleniumLibrary/__init__.py
+++ b/src/SeleniumLibrary/__init__.py
@@ -293,7 +293,7 @@ class SeleniumLibrary(DynamicCore):
     it is either empty or case-insensitively equal to ``false``, ``no``, ``off``,
      ``0`` or ``none``. Other strings are considered true regardless their value, and
     other argument types are tested using same
-    [https://docs.python.org/2/library/stdtypes.html#truth-value-testing|rules as in Python].
+    [https://docs.python.org/3/library/stdtypes.html#truth-value-testing|rules as in Python].
 
     True examples:
 
diff --git a/src/SeleniumLibrary/keywords/browsermanagement.py b/src/SeleniumLibrary/keywords/browsermanagement.py
index 993a2581..355d0cea 100644
--- a/src/SeleniumLibrary/keywords/browsermanagement.py
+++ b/src/SeleniumLibrary/keywords/browsermanagement.py
@@ -58,7 +58,7 @@ class BrowserManagementKeywords(LibraryComponent):
     @keyword
     def open_browser(self, url, browser='firefox', alias=None,
                      remote_url=False, desired_capabilities=None,
-                     ff_profile_dir=None):
+                     ff_profile_dir=None, service_log_path=None):
         """Opens a new browser instance to the given ``url``.
 
         The ``browser`` argument specifies which browser to use, and the
@@ -117,6 +117,15 @@ class BrowserManagementKeywords(LibraryComponent):
         uses. Notice that prior to SeleniumLibrary 3.0, the library
         contained its own profile that was used by default.
 
+        Optional ``service_log_path`` argument defines the name of the
+        file where to write the browser driver logs. If the
+        ``service_log_path``  argument contain a  marker ``{index}``, it
+        will be automatically replaced with unique running
+        index preventing files to be overwritten. Indices start's from 1,
+        and how they are represented can be customized using Python's
+        [https://docs.python.org/3/library/string.html#format-string-syntax|
+        format string syntax].
+
         Examples:
         | `Open Browser` | http://example.com | Chrome  |
         | `Open Browser` | http://example.com | Firefox | alias=Firefox |
@@ -139,6 +148,7 @@ class BrowserManagementKeywords(LibraryComponent):
         new in SeleniumLibrary 3.1.
 
         Using ``alias`` to decide, is the new browser opened is new
+        in SeleniumLibrary 4.0. Also the ``service_log_path`` is new
         in SeleniumLibrary 4.0.
         """
         index = self.drivers.get_index(alias)
@@ -148,18 +158,20 @@ class BrowserManagementKeywords(LibraryComponent):
             self.go_to(url)
             return index
         return self._make_new_browser(url, browser, alias, remote_url,
-                                      desired_capabilities, ff_profile_dir)
+                                      desired_capabilities, ff_profile_dir,
+                                      service_log_path)
 
     def _make_new_browser(self, url, browser='firefox', alias=None,
                           remote_url=False, desired_capabilities=None,
-                          ff_profile_dir=None):
+                          ff_profile_dir=None, service_log_path=None):
         if is_truthy(remote_url):
             self.info("Opening browser '%s' to base url '%s' through "
                       "remote server at '%s'." % (browser, url, remote_url))
         else:
             self.info("Opening browser '%s' to base url '%s'." % (browser, url))
         driver = self._make_driver(browser, desired_capabilities,
-                                   ff_profile_dir, remote_url)
+                                   ff_profile_dir, remote_url,
+                                   service_log_path)
         driver = self._wrap_event_firing_webdriver(driver)
         try:
             driver.get(url)
@@ -489,10 +501,10 @@ class BrowserManagementKeywords(LibraryComponent):
         self.driver.implicitly_wait(timestr_to_secs(value))
 
     def _make_driver(self, browser, desired_capabilities=None,
-                     profile_dir=None, remote=None):
+                     profile_dir=None, remote=None, service_log_path=None):
         driver = WebDriverCreator(self.log_dir).create_driver(
             browser=browser, desired_capabilities=desired_capabilities,
-            remote_url=remote, profile_dir=profile_dir)
+            remote_url=remote, profile_dir=profile_dir, service_log_path=service_log_path)
         driver.set_script_timeout(self.ctx.timeout)
         driver.implicitly_wait(self.ctx.implicit_wait)
         if self.ctx.speed:
diff --git a/src/SeleniumLibrary/keywords/screenshot.py b/src/SeleniumLibrary/keywords/screenshot.py
index 9a6a5d1f..ff7142d7 100644
--- a/src/SeleniumLibrary/keywords/screenshot.py
+++ b/src/SeleniumLibrary/keywords/screenshot.py
@@ -65,7 +65,7 @@ class ScreenshotKeywords(LibraryComponent):
         ``{index}``, it will be automatically replaced with unique running
         index preventing files to be overwritten. Indices start from 1,
         and how they are represented can be customized using Python's
-        [https://docs.python.org/2/library/string.html#formatstrings|
+        [https://docs.python.org/3/library/string.html#format-string-syntax|
         format string syntax].
 
         An absolute path to the created screenshot file is returned.
diff --git a/src/SeleniumLibrary/keywords/webdrivertools.py b/src/SeleniumLibrary/keywords/webdrivertools.py
index 385e4c2d..78b4f8d7 100644
--- a/src/SeleniumLibrary/keywords/webdrivertools.py
+++ b/src/SeleniumLibrary/keywords/webdrivertools.py
@@ -13,7 +13,7 @@
 # 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 inspect
 import os
 import warnings
 
@@ -50,14 +50,18 @@ class WebDriverCreator(object):
         self.log_dir = log_dir
 
     def create_driver(self, browser, desired_capabilities, remote_url,
-                      profile_dir=None):
+                      profile_dir=None, service_log_path=None):
         creation_method = self._get_creator_method(browser)
         desired_capabilities = self._parse_capabilities(desired_capabilities, browser)
+        service_log_path = self._get_log_path(service_log_path)
+        if service_log_path:
+            logger.info('Browser driver log file created to: %s' % service_log_path)
+            self._create_directory(service_log_path)
         if (creation_method == self.create_firefox
                 or creation_method == self.create_headless_firefox):
             return creation_method(desired_capabilities, remote_url,
-                                   profile_dir)
-        return creation_method(desired_capabilities, remote_url)
+                                   profile_dir, service_log_path)
+        return creation_method(desired_capabilities, remote_url, service_log_path=service_log_path)
 
     def _get_creator_method(self, browser):
         browser = browser.lower().replace(' ', '')
@@ -93,29 +97,28 @@ class WebDriverCreator(object):
             caps['browserName'] = default_capabilities['browserName']
         return {'desired_capabilities': caps}
 
-    def create_chrome(self, desired_capabilities, remote_url, options=None):
+    def create_chrome(self, desired_capabilities, remote_url, options=None, service_log_path=None):
         if is_truthy(remote_url):
             defaul_caps = webdriver.DesiredCapabilities.CHROME.copy()
             desired_capabilities = self._remote_capabilities_resolver(desired_capabilities, defaul_caps)
             return self._remote(desired_capabilities, remote_url, options=options)
-        return webdriver.Chrome(options=options, **desired_capabilities)
+        return webdriver.Chrome(options=options, service_log_path=service_log_path, **desired_capabilities)
 
-    def create_headless_chrome(self, desired_capabilities, remote_url):
+    def create_headless_chrome(self, desired_capabilities, remote_url, service_log_path=None):
         options = webdriver.ChromeOptions()
         # Can be changed to options.headless = True when minimum Selenium version is 3.12.0 or greater.
         options.set_headless()
-        return self.create_chrome(desired_capabilities, remote_url, options)
+        return self.create_chrome(desired_capabilities, remote_url, options, service_log_path)
 
-    def create_firefox(self, desired_capabilities, remote_url, ff_profile_dir,
-                       options=None):
+    def create_firefox(self, desired_capabilities, remote_url, ff_profile_dir, options=None, service_log_path=None):
         profile = self._get_ff_profile(ff_profile_dir)
         if is_truthy(remote_url):
             defaul_caps = webdriver.DesiredCapabilities.FIREFOX.copy()
             desired_capabilities = self._remote_capabilities_resolver(desired_capabilities, defaul_caps)
             return self._remote(desired_capabilities, remote_url,
                                 profile, options)
-        desired_capabilities.update(self._geckodriver_log)
-        return webdriver.Firefox(options=options, firefox_profile=profile,
+        service_log_path = service_log_path if service_log_path else self._geckodriver_log
+        return webdriver.Firefox(options=options, firefox_profile=profile, service_log_path=service_log_path,
                                  **desired_capabilities)
 
     def _get_ff_profile(self, ff_profile_dir):
@@ -125,36 +128,47 @@ class WebDriverCreator(object):
 
     @property
     def _geckodriver_log(self):
-        return {'log_path': os.path.join(self.log_dir, 'geckodriver.log')}
+        log_file = self._get_log_path(os.path.join(self.log_dir, 'geckodriver-{index}.log'))
+        logger.info('Firefox driver log is always forced to to: %s' % log_file)
+        return log_file
 
     def create_headless_firefox(self, desired_capabilities, remote_url,
-                                ff_profile_dir):
+                                ff_profile_dir, service_log_path=None):
         options = webdriver.FirefoxOptions()
         # Can be changed to options.headless = True when minimum Selenium version is 3.12.0 or greater.
         options.set_headless()
-        return self.create_firefox(desired_capabilities, remote_url,
-                                   ff_profile_dir, options)
+        return self.create_firefox(desired_capabilities, remote_url, ff_profile_dir, options, service_log_path)
 
-    def create_ie(self, desired_capabilities, remote_url):
+    def create_ie(self, desired_capabilities, remote_url, service_log_path=None):
         if is_truthy(remote_url):
             defaul_caps = webdriver.DesiredCapabilities.INTERNETEXPLORER.copy()
             desired_capabilities = self._remote_capabilities_resolver(desired_capabilities, defaul_caps)
             return self._remote(desired_capabilities, remote_url)
+        if self._has_service_log_path(webdriver.Ie):
+            return webdriver.Ie(service_log_path=service_log_path, **desired_capabilities)
+        logger.warn('This version of Selenium does not support service_log_path argument.')
         return webdriver.Ie(**desired_capabilities)
 
-    def create_edge(self, desired_capabilities, remote_url):
+    def _has_service_log_path(self, web_driver):
+        signature = inspect.getargspec(web_driver.__init__)
+        return True if 'service_log_path' in signature.args else False
+
+    def create_edge(self, desired_capabilities, remote_url, service_log_path=None):
         if is_truthy(remote_url):
             defaul_caps = webdriver.DesiredCapabilities.EDGE.copy()
             desired_capabilities = self._remote_capabilities_resolver(desired_capabilities, defaul_caps)
             return self._remote(desired_capabilities, remote_url)
+        if self._has_service_log_path(webdriver.Ie):
+            return webdriver.Edge(service_log_path=service_log_path, **desired_capabilities)
+        logger.warn('This version of Selenium does not support service_log_path argument.')
         return webdriver.Edge(**desired_capabilities)
 
-    def create_opera(self, desired_capabilities, remote_url):
+    def create_opera(self, desired_capabilities, remote_url, service_log_path=None):
         if is_truthy(remote_url):
             defaul_caps = webdriver.DesiredCapabilities.OPERA.copy()
             desired_capabilities = self._remote_capabilities_resolver(desired_capabilities, defaul_caps)
             return self._remote(desired_capabilities, remote_url)
-        return webdriver.Opera(**desired_capabilities)
+        return webdriver.Opera(service_log_path=service_log_path, **desired_capabilities)
 
     def create_safari(self, desired_capabilities, remote_url):
         if is_truthy(remote_url):
@@ -163,31 +177,39 @@ class WebDriverCreator(object):
             return self._remote(desired_capabilities, remote_url)
         return webdriver.Safari(**desired_capabilities)
 
-    def create_phantomjs(self, desired_capabilities, remote_url):
+    def create_phantomjs(self, desired_capabilities, remote_url, service_log_path=None):
         warnings.warn('SeleniumLibrary support for PhantomJS has been deprecated, '
                       'please use headlesschrome or headlessfirefox instead.')
         if is_truthy(remote_url):
             defaul_caps = webdriver.DesiredCapabilities.PHANTOMJS.copy()
             desired_capabilities = self._remote_capabilities_resolver(desired_capabilities, defaul_caps)
             return self._remote(desired_capabilities, remote_url)
-        return webdriver.PhantomJS(**desired_capabilities)
+        return webdriver.PhantomJS(service_log_path=service_log_path, **desired_capabilities)
 
-    def create_htmlunit(self, desired_capabilities, remote_url):
+    def create_htmlunit(self, desired_capabilities, remote_url, service_log_path=None):
+        if service_log_path:
+            logger.warn('Htmlunit does not support service_log_path argument.')
         defaul_caps = webdriver.DesiredCapabilities.HTMLUNIT.copy()
         desired_capabilities = self._remote_capabilities_resolver(desired_capabilities, defaul_caps)
         return self._remote(desired_capabilities, remote_url)
 
-    def create_htmlunit_with_js(self, desired_capabilities, remote_url):
+    def create_htmlunit_with_js(self, desired_capabilities, remote_url, service_log_path=None):
+        if service_log_path:
+            logger.warn('Htmlunit does not support service_log_path argument.')
         defaul_caps = webdriver.DesiredCapabilities.HTMLUNITWITHJS.copy()
         desired_capabilities = self._remote_capabilities_resolver(desired_capabilities, defaul_caps)
         return self._remote(desired_capabilities, remote_url)
 
-    def create_android(self, desired_capabilities, remote_url):
+    def create_android(self, desired_capabilities, remote_url, service_log_path=None):
+        if service_log_path:
+            logger.warn('Android does not support service_log_path argument.')
         defaul_caps = webdriver.DesiredCapabilities.ANDROID.copy()
         desired_capabilities = self._remote_capabilities_resolver(desired_capabilities, defaul_caps)
         return self._remote(desired_capabilities, remote_url)
 
-    def create_iphone(self, desired_capabilities, remote_url):
+    def create_iphone(self, desired_capabilities, remote_url, service_log_path=None):
+        if service_log_path:
+            logger.warn('iPhone does not support service_log_path argument.')
         defaul_caps = webdriver.DesiredCapabilities.IPHONE.copy()
         desired_capabilities = self._remote_capabilities_resolver(desired_capabilities, defaul_caps)
         return self._remote(desired_capabilities, remote_url)
@@ -199,6 +221,23 @@ class WebDriverCreator(object):
                                 browser_profile=profile_dir, options=options,
                                 **desired_capabilities)
 
+    def _get_log_path(self, log_file):
+        if is_noney(log_file):
+            return None
+        index = 1
+        while True:
+            formatted = log_file.format(index=index)
+            path = os.path.join(self.log_dir, formatted)
+            # filename didn't contain {index} or unique path was found
+            if formatted == log_file or not os.path.exists(path):
+                return path
+            index += 1
+
+    def _create_directory(self, path):
+        target_dir = os.path.dirname(path)
+        if not os.path.exists(target_dir):
+            os.makedirs(target_dir)
+
 
 class WebDriverCache(ConnectionCache):
 


Test patch:
diff --git a/atest/acceptance/multiple_browsers_service_log_path.robot b/atest/acceptance/multiple_browsers_service_log_path.robot
new file mode 100644
index 00000000..688b23fc
--- /dev/null
+++ b/atest/acceptance/multiple_browsers_service_log_path.robot
@@ -0,0 +1,26 @@
+*** Settings ***
+Suite Teardown    Close All Browsers
+Resource          resource.robot
+
+*** Test Cases ***
+First Browser With Service Log Path
+    [Documentation]
+    ...    LOG 2:2 INFO STARTS: Browser driver log file created to:
+    [Setup]    OperatingSystem.Remove Files    ${OUTPUT DIR}/${BROWSER}.log
+    Open Browser    ${FRONT PAGE}  ${BROWSER}    service_log_path=${BROWSER}.log
+    OperatingSystem.File Should Not Be Empty     ${OUTPUT DIR}/${BROWSER}.log
+
+Second Browser With Service Log Path And Index
+    [Setup]    OperatingSystem.Remove Files    ${OUTPUT DIR}/${BROWSER}-1.log
+    Open Browser    ${FRONT PAGE}  ${BROWSER}    service_log_path=${BROWSER}-{index}.log
+    OperatingSystem.File Should Not Be Empty     ${OUTPUT DIR}/${BROWSER}-1.log
+
+Third Browser With Service Log Path And Index Should Not Overwrite
+    [Setup]    OperatingSystem.Remove Files    ${OUTPUT DIR}/${BROWSER}-2.log
+    Open Browser    ${FRONT PAGE}  ${BROWSER}    service_log_path=${BROWSER}-{index}.log
+    OperatingSystem.File Should Not Be Empty     ${OUTPUT DIR}/${BROWSER}-2.log
+
+Fourth Browser With Service Log Path In Subfolder
+    [Setup]    OperatingSystem.Remove Files    ${OUTPUT DIR}/a_folder/${BROWSER}-1.log
+    Open Browser    ${FRONT PAGE}  ${BROWSER}    service_log_path=a_folder/${BROWSER}-{index}.log
+    OperatingSystem.File Should Not Be Empty     ${OUTPUT DIR}/a_folder/${BROWSER}-1.log
diff --git a/utest/run.py b/utest/run.py
index db7340b1..62212a3c 100755
--- a/utest/run.py
+++ b/utest/run.py
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
 import os
+import shutil
 import sys
 from os.path import abspath, dirname, join
 from unittest import defaultTestLoader, TextTestRunner
@@ -9,6 +10,13 @@ from unittest import defaultTestLoader, TextTestRunner
 CURDIR = dirname(abspath(__file__))
 
 
+def remove_output_dir():
+    output_dir = os.path.join(CURDIR, 'output_dir')
+    if os.path.exists(output_dir):
+        shutil.rmtree(output_dir)
+    os.mkdir(output_dir)
+
+
 def run_unit_tests():
     sys.path.insert(0, join(CURDIR, os.pardir, 'src'))
     try:
@@ -20,4 +28,5 @@ def run_unit_tests():
 
 
 if __name__ == '__main__':
+    remove_output_dir()
     sys.exit(run_unit_tests())
diff --git a/utest/test/keywords/test_browsermanagement.py b/utest/test/keywords/test_browsermanagement.py
index 70114b91..e5bfa456 100644
--- a/utest/test/keywords/test_browsermanagement.py
+++ b/utest/test/keywords/test_browsermanagement.py
@@ -89,7 +89,7 @@ class BrowserManagementTests(unittest.TestCase):
         ctx.event_firing_webdriver = None
         ctx.speed = 5.0
         browser = mock()
-        when(webdriver).Chrome(options=None).thenReturn(browser)
+        when(webdriver).Chrome(options=None, service_log_path=None).thenReturn(browser)
         bm = BrowserManagementKeywords(ctx)
         bm.open_browser('http://robotframework.org/', 'chrome')
         self.assertEqual(browser._speed, 5.0)
@@ -101,7 +101,7 @@ class BrowserManagementTests(unittest.TestCase):
         ctx.event_firing_webdriver = None
         ctx.speed = 0.0
         browser = mock()
-        when(webdriver).Chrome(options=None).thenReturn(browser)
+        when(webdriver).Chrome(options=None, service_log_path=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_keyword_arguments_browsermanagement.py b/utest/test/keywords/test_keyword_arguments_browsermanagement.py
index 8d76a636..b2daef53 100644
--- a/utest/test/keywords/test_keyword_arguments_browsermanagement.py
+++ b/utest/test/keywords/test_keyword_arguments_browsermanagement.py
@@ -22,12 +22,12 @@ class KeywordArgumentsElementTest(unittest.TestCase):
         remote_url = '"http://localhost:4444/wd/hub"'
         browser = mock()
         when(self.brorser)._make_driver('firefox', None,
-                                        None, False).thenReturn(browser)
+                                        None, False, None).thenReturn(browser)
         alias = self.brorser.open_browser(url)
         self.assertEqual(alias, None)
 
         when(self.brorser)._make_driver('firefox', None,
-                                        None, remote_url).thenReturn(browser)
+                                        None, remote_url, None).thenReturn(browser)
         alias = self.brorser.open_browser(url, alias='None',
                                           remote_url=remote_url)
         self.assertEqual(alias, None)
diff --git a/utest/test/keywords/test_webdrivercreator.py b/utest/test/keywords/test_webdrivercreator.py
index 8c5cafa4..65bb0eba 100644
--- a/utest/test/keywords/test_webdrivercreator.py
+++ b/utest/test/keywords/test_webdrivercreator.py
@@ -1,7 +1,7 @@
 import os
 import unittest
 
-from mockito import mock, verify, when, unstub
+from mockito import mock, verify, when, unstub, ANY
 from selenium import webdriver
 
 from SeleniumLibrary.keywords import WebDriverCreator
@@ -108,13 +108,14 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_chrome(self):
         expected_webdriver = mock()
-        when(webdriver).Chrome(options=None).thenReturn(expected_webdriver)
+        when(webdriver).Chrome(options=None, service_log_path=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)
+        when(webdriver).Chrome(desired_capabilities={'key': 'value'},
+                               options=None, service_log_path=None).thenReturn(expected_webdriver)
         driver = self.creator.create_chrome({'desired_capabilities': {'key': 'value'}}, None)
         self.assertEqual(driver, expected_webdriver)
 
@@ -155,7 +156,7 @@ class WebDriverCreatorTests(unittest.TestCase):
         expected_webdriver = mock()
         options = mock()
         when(webdriver).ChromeOptions().thenReturn(options)
-        when(webdriver).Chrome(options=options).thenReturn(expected_webdriver)
+        when(webdriver).Chrome(options=options, service_log_path=None).thenReturn(expected_webdriver)
         driver = self.creator.create_headless_chrome({}, None)
         verify(options).set_headless()
         self.assertEqual(driver, expected_webdriver)
@@ -180,7 +181,7 @@ class WebDriverCreatorTests(unittest.TestCase):
         log_file = self.get_geckodriver_log()
         when(webdriver).Firefox(options=None,
                                 firefox_profile=profile,
-                                log_path=log_file).thenReturn(expected_webdriver)
+                                service_log_path=log_file).thenReturn(expected_webdriver)
         driver = self.creator.create_firefox({}, None, None)
         self.assertEqual(driver, expected_webdriver)
         verify(webdriver).FirefoxProfile()
@@ -227,7 +228,7 @@ class WebDriverCreatorTests(unittest.TestCase):
         profile_dir = '/profile/dir'
         when(webdriver).FirefoxProfile(profile_dir).thenReturn(profile)
         log_file = self.get_geckodriver_log()
-        when(webdriver).Firefox(options=None, log_path=log_file,
+        when(webdriver).Firefox(options=None, service_log_path=log_file,
                                 firefox_profile=profile).thenReturn(expected_webdriver)
         driver = self.creator.create_firefox({}, None, profile_dir)
         self.assertEqual(driver, expected_webdriver)
@@ -239,7 +240,7 @@ class WebDriverCreatorTests(unittest.TestCase):
         options = mock()
         when(webdriver).FirefoxOptions().thenReturn(options)
         log_file = self.get_geckodriver_log()
-        when(webdriver).Firefox(options=options, log_path=log_file,
+        when(webdriver).Firefox(options=options, service_log_path=log_file,
                                 firefox_profile=profile).thenReturn(expected_webdriver)
         driver = self.creator.create_headless_firefox({}, None, None)
         self.assertEqual(driver, expected_webdriver)
@@ -278,6 +279,7 @@ class WebDriverCreatorTests(unittest.TestCase):
     def test_ie(self):
         expected_webdriver = mock()
         when(webdriver).Ie().thenReturn(expected_webdriver)
+        when(self.creator)._has_service_log_path(ANY).thenReturn(False)
         driver = self.creator.create_ie({}, None)
         self.assertEqual(driver, expected_webdriver)
 
@@ -317,7 +319,8 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_edge(self):
         expected_webdriver = mock()
-        when(webdriver).Edge().thenReturn(expected_webdriver)
+        when(webdriver).Edge(service_log_path=None).thenReturn(expected_webdriver)
+        when(self.creator)._has_service_log_path(ANY).thenReturn(True)
         driver = self.creator.create_edge({}, None)
         self.assertEqual(driver, expected_webdriver)
 
@@ -353,7 +356,7 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_opera(self):
         expected_webdriver = mock()
-        when(webdriver).Opera().thenReturn(expected_webdriver)
+        when(webdriver).Opera(service_log_path=None).thenReturn(expected_webdriver)
         driver = self.creator.create_opera({}, None)
         self.assertEqual(driver, expected_webdriver)
 
@@ -425,7 +428,7 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_phantomjs(self):
         expected_webdriver = mock()
-        when(webdriver).PhantomJS().thenReturn(expected_webdriver)
+        when(webdriver).PhantomJS(service_log_path=None).thenReturn(expected_webdriver)
         driver = self.creator.create_phantomjs({}, None)
         self.assertEqual(driver, expected_webdriver)
 
@@ -551,7 +554,7 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_create_driver_chrome(self):
         expected_webdriver = mock()
-        when(webdriver).Chrome(options=None).thenReturn(expected_webdriver)
+        when(webdriver).Chrome(options=None, service_log_path=None).thenReturn(expected_webdriver)
         for browser in ['chrome', 'googlechrome', 'gc']:
             driver = self.creator.create_driver(browser, None, None)
             self.assertEqual(driver, expected_webdriver)
@@ -561,7 +564,7 @@ class WebDriverCreatorTests(unittest.TestCase):
         profile = mock()
         when(webdriver).FirefoxProfile().thenReturn(profile)
         log_file = self.get_geckodriver_log()
-        when(webdriver).Firefox(options=None, log_path=log_file,
+        when(webdriver).Firefox(options=None, service_log_path=log_file,
                                 firefox_profile=profile).thenReturn(expected_webdriver)
         for browser in ['ff', 'firefox']:
             driver = self.creator.create_driver(browser, None, None, None)
@@ -569,10 +572,11 @@ class WebDriverCreatorTests(unittest.TestCase):
 
     def test_create_driver_ie(self):
         expected_webdriver = mock()
+        when(self.creator)._has_service_log_path(ANY).thenReturn(False)
         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 get_geckodriver_log(self):
-        return os.path.join(self.log_dir, 'geckodriver.log')
+        return os.path.join(self.log_dir, 'geckodriver-1.log')
diff --git a/utest/test/keywords/test_webdrivercreator_service_log_path.py b/utest/test/keywords/test_webdrivercreator_service_log_path.py
new file mode 100644
index 00000000..45e33068
--- /dev/null
+++ b/utest/test/keywords/test_webdrivercreator_service_log_path.py
@@ -0,0 +1,148 @@
+import os
+import unittest
+
+from mockito import mock, when, unstub, ANY
+from selenium import webdriver
+
+from SeleniumLibrary.keywords import WebDriverCreator
+
+
+class WebDriverCreatorServiceLogPathTests(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        curr_dir = os.path.dirname(os.path.abspath(__file__))
+        cls.output_dir = os.path.abspath(
+            os.path.join(curr_dir, '..', '..', 'output_dir'))
+        cls.creator = WebDriverCreator(cls.output_dir)
+
+    def tearDown(self):
+        unstub()
+
+    def test_no_log_file(self):
+        self.assertEqual(self.creator._get_log_path(None), None)
+        self.assertEqual(self.creator._get_log_path('NoNe'), None)
+
+    def test_log_file_with_rf_file_separator(self):
+        log_file = '/path/to/own_name.txt'
+        file_name = self.creator._get_log_path(log_file)
+        log_file = log_file.replace('/', os.sep)
+        self.assertEqual(file_name, log_file)
+
+    def test_log_file_with_index(self):
+        log_file = os.path.join(self.output_dir, 'firefox-{index}.log')
+        file_name = self.creator._get_log_path(log_file)
+        self.assertEqual(file_name, log_file.format(index='1'))
+
+    def test_log_file_with_index_exist(self):
+        log_file = os.path.join(self.output_dir, 'firefox-{index}.log')
+        with open(os.path.join(self.output_dir, log_file.format(index='1')), 'w') as file:
+            file.close()
+        file_name = self.creator._get_log_path(log_file)
+        self.assertEqual(file_name, log_file.format(index='2'))
+
+    def test_create_chrome_with_service_log_path_none(self):
+        expected_webdriver = mock()
+        when(webdriver).Chrome(options=None, service_log_path=None).thenReturn(expected_webdriver)
+        driver = self.creator.create_chrome({}, None, service_log_path=None)
+        self.assertEqual(driver, expected_webdriver)
+
+    def test_create_chrome_with_service_log_path_real_path(self):
+        log_file = os.path.join(self.output_dir, 'firefox-{index}.log')
+        expected_webdriver = mock()
+        when(webdriver).Chrome(options=None, service_log_path=log_file).thenReturn(expected_webdriver)
+        driver = self.creator.create_chrome({}, None, service_log_path=log_file)
+        self.assertEqual(driver, expected_webdriver)
+
+    def test_create_headlesschrome_with_service_log_path_real_path(self):
+        log_file = os.path.join(self.output_dir, 'firefox-{index}.log')
+        expected_webdriver = mock()
+        options = mock()
+        when(webdriver).ChromeOptions().thenReturn(options)
+        when(webdriver).Chrome(options=options, service_log_path=log_file).thenReturn(expected_webdriver)
+        driver = self.creator.create_headless_chrome({}, None, service_log_path=log_file)
+        self.assertEqual(driver, expected_webdriver)
+
+    def test_create_firefox_with_service_log_path_none(self):
+        log_file = os.path.join(self.output_dir, 'geckodriver-1.log')
+        expected_webdriver = mock()
+        profile = mock()
+        when(webdriver).FirefoxProfile().thenReturn(profile)
+        when(webdriver).Firefox(options=None, firefox_profile=profile,
+                                service_log_path=log_file).thenReturn(expected_webdriver)
+        driver = self.creator.create_firefox({}, None, None, service_log_path=None)
+        self.assertEqual(driver, expected_webdriver)
+
+    def test_create_firefox_with_service_log_path_real_path(self):
+        log_file = os.path.join(self.output_dir, 'firefox-{index}.log')
+        expected_webdriver = mock()
+        profile = mock()
+        when(webdriver).FirefoxProfile().thenReturn(profile)
+        when(webdriver).Firefox(options=None, firefox_profile=profile,
+                                service_log_path=log_file).thenReturn(expected_webdriver)
+        driver = self.creator.create_firefox({}, None, ff_profile_dir=None, service_log_path=log_file)
+        self.assertEqual(driver, expected_webdriver)
+
+    def test_create_headlessfirefox_with_service_log_path_real_path(self):
+        log_file = os.path.join(self.output_dir, 'firefox-{index}.log')
+        expected_webdriver = mock()
+        profile = mock()
+        when(webdriver).FirefoxProfile().thenReturn(profile)
+        options = mock()
+        when(webdriver).FirefoxOptions().thenReturn(options)
+        when(webdriver).Firefox(options=options, firefox_profile=profile,
+                                service_log_path=log_file).thenReturn(expected_webdriver)
+        driver = self.creator.create_headless_firefox({}, None, ff_profile_dir=None, service_log_path=log_file)
+        self.assertEqual(driver, expected_webdriver)
+
+    def test_create_ie_with_service_log_path_real_path(self):
+        log_file = os.path.join(self.output_dir, 'ie-1.log')
+        expected_webdriver = mock()
+        when(self.creator)._has_service_log_path(ANY).thenReturn(True)
+        when(webdriver).Ie(service_log_path=log_file).thenReturn(expected_webdriver)
+        driver = self.creator.create_ie({}, None, service_log_path=log_file)
+        self.assertEqual(driver, expected_webdriver)
+
+    def test_create_ie_with_service_log_path_old_selenium(self):
+        log_file = os.path.join(self.output_dir, 'ie-1.log')
+        expected_webdriver = mock()
+        when(self.creator)._has_service_log_path(ANY).thenReturn(False)
+        when(webdriver).Ie().thenReturn(expected_webdriver)
+        driver = self.creator.create_ie({}, None, service_log_path=log_file)
+        self.assertEqual(driver, expected_webdriver)
+
+    def test_has_service_log_path(self):
+        status = self.creator._has_service_log_path(webdriver.Ie)
+        self.assertTrue(status)
+        status = self.creator._has_service_log_path(webdriver.Safari)
+        self.assertFalse(status)
+
+    def test_create_edge_with_service_log_path_real_path(self):
+        log_file = os.path.join(self.output_dir, 'ie-1.log')
+        expected_webdriver = mock()
+        when(self.creator)._has_service_log_path(ANY).thenReturn(True)
+        when(webdriver).Edge(service_log_path=log_file).thenReturn(expected_webdriver)
+        driver = self.creator.create_edge({}, None, service_log_path=log_file)
+        self.assertEqual(driver, expected_webdriver)
+
+    def test_create_edge_with_service_log_path_old_selenium(self):
+        log_file = os.path.join(self.output_dir, 'ie-1.log')
+        expected_webdriver = mock()
+        when(self.creator)._has_service_log_path(ANY).thenReturn(False)
+        when(webdriver).Edge().thenReturn(expected_webdriver)
+        driver = self.creator.create_edge({}, None, service_log_path=log_file)
+        self.assertEqual(driver, expected_webdriver)
+
+    def test_create_opera_with_service_log_path_real_path(self):
+        log_file = os.path.join(self.output_dir, 'ie-1.log')
+        expected_webdriver = mock()
+        when(webdriver).Opera(service_log_path=log_file).thenReturn(expected_webdriver)
+        driver = self.creator.create_opera({}, None, service_log_path=log_file)
+        self.assertEqual(driver, expected_webdriver)
+
+    def test_create_phantomjs_with_service_log_path_real_path(self):
+        log_file = os.path.join(self.output_dir, 'ie-1.log')
+        expected_webdriver = mock()
+        when(webdriver).PhantomJS(service_log_path=log_file).thenReturn(expected_webdriver)
+        driver = self.creator.create_phantomjs({}, None, service_log_path=log_file)
+        self.assertEqual(driver, expected_webdriver)