diff --git a/src/SeleniumLibrary/keywords/__init__.py b/src/SeleniumLibrary/keywords/__init__.py index a3236bcf0..cbaa29fc1 100644 --- a/src/SeleniumLibrary/keywords/__init__.py +++ b/src/SeleniumLibrary/keywords/__init__.py @@ -26,4 +26,5 @@ from .selectelement import SelectElementKeywords from .tableelement import TableElementKeywords from .waiting import WaitingKeywords +from .webdrivercreator import WebDriverCreator from .window import WindowKeywords diff --git a/src/SeleniumLibrary/keywords/browsermanagement.py b/src/SeleniumLibrary/keywords/browsermanagement.py index 3227c9cdd..cbd1121a2 100644 --- a/src/SeleniumLibrary/keywords/browsermanagement.py +++ b/src/SeleniumLibrary/keywords/browsermanagement.py @@ -14,40 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os.path import time import types -from robot.utils import NormalizedDict from selenium import webdriver from SeleniumLibrary.base import keyword, LibraryComponent from SeleniumLibrary.locators import WindowManager -from SeleniumLibrary.utils import (is_falsy, is_truthy, is_noney, secs_to_timestr, - timestr_to_secs, SELENIUM_VERSION) - - -ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) -FIREFOX_PROFILE_DIR = os.path.join(ROOT_DIR, 'resources', 'firefoxprofile') -BROWSER_NAMES = NormalizedDict({ - 'ff': "_make_ff", - 'firefox': "_make_ff", - 'ie': "_make_ie", - 'internetexplorer': "_make_ie", - 'googlechrome': "_make_chrome", - 'gc': "_make_chrome", - 'chrome': "_make_chrome", - 'opera': "_make_opera", - 'phantomjs': "_make_phantomjs", - 'htmlunit': "_make_htmlunit", - 'htmlunitwithjs': "_make_htmlunitwithjs", - 'android': "_make_android", - 'iphone': "_make_iphone", - 'safari': "_make_safari", - 'edge': "_make_edge", - 'headlessfirefox': '_make_headless_ff', - 'headlesschrome': '_make_headless_chrome' -}) +from SeleniumLibrary.utils import (is_truthy, is_noney, secs_to_timestr, + timestr_to_secs) + +from .webdrivercreator import WebDriverCreator class BrowserManagementKeywords(LibraryComponent): @@ -146,8 +123,7 @@ def open_browser(self, url, browser='firefox', alias=None, "remote server at '%s'." % (browser, url, remote_url)) else: self.info("Opening browser '%s' to base url '%s'." % (browser, url)) - browser_name = browser - driver = self._make_driver(browser_name, desired_capabilities, + driver = self._make_driver(browser, desired_capabilities, ff_profile_dir, remote_url) try: driver.get(url) @@ -307,8 +283,8 @@ def title_should_be(self, title, message=None): """Verifies that current page title equals ``title``. The ``message`` argument can be used to override the default error - message. - + message. + ``message`` argument is new in SeleniumLibrary 3.1. """ actual = self.get_title() @@ -441,145 +417,17 @@ def set_browser_implicit_wait(self, value): """ self.driver.implicitly_wait(timestr_to_secs(value)) - def _get_driver_creation_function(self, browser_name): - try: - func_name = BROWSER_NAMES[browser_name] - except KeyError: - raise ValueError(browser_name + " is not a supported browser.") - return getattr(self, func_name) - - def _make_driver(self, browser_name, desired_capabilities=None, + def _make_driver(self, browser, desired_capabilities=None, profile_dir=None, remote=None): - creation_func = self._get_driver_creation_function(browser_name) - driver = creation_func(remote, desired_capabilities, profile_dir) + driver = WebDriverCreator(self.log_dir).create_driver( + browser=browser, desired_capabilities=desired_capabilities, + remote_url=remote, profile_dir=profile_dir) driver.set_script_timeout(self.ctx.timeout) driver.implicitly_wait(self.ctx.implicit_wait) if self.ctx.speed: self._monkey_patch_speed(driver) return driver - def _make_ff(self, remote, desired_capabilities, profile_dir, options=None): - if is_falsy(profile_dir): - profile = webdriver.FirefoxProfile() - else: - profile = webdriver.FirefoxProfile(profile_dir) - if is_truthy(remote): - driver = self._create_remote_web_driver( - webdriver.DesiredCapabilities.FIREFOX, remote, - desired_capabilities, profile, options=options) - else: - driver = webdriver.Firefox(firefox_profile=profile, - options=options, - **self._geckodriver_log_config) - return driver - - def _make_headless_ff(self, remote, desired_capabilities, profile_dir): - options = webdriver.FirefoxOptions() - options.set_headless() - return self._make_ff(remote, desired_capabilities, profile_dir, options=options) - - def _make_ie(self, remote, desired_capabilities, profile_dir): - return self._generic_make_driver( - webdriver.Ie, webdriver.DesiredCapabilities.INTERNETEXPLORER, - remote, desired_capabilities) - - def _make_chrome(self, remote, desired_capabilities, profile_dir, options=None): - return self._generic_make_driver( - webdriver.Chrome, webdriver.DesiredCapabilities.CHROME, remote, - desired_capabilities, options=options) - - def _make_headless_chrome(self, remote, desired_capabilities, profile_dir): - options = webdriver.ChromeOptions() - options.set_headless() - return self._make_chrome(remote, desired_capabilities, profile_dir, options) - - def _make_opera(self, remote, desired_capabilities, profile_dir): - return self._generic_make_driver( - webdriver.Opera, webdriver.DesiredCapabilities.OPERA, remote, - desired_capabilities) - - def _make_phantomjs(self, remote, desired_capabilities, profile_dir): - return self._generic_make_driver( - webdriver.PhantomJS, webdriver.DesiredCapabilities.PHANTOMJS, - remote, desired_capabilities) - - def _make_htmlunit(self, remote, desired_capabilities, profile_dir): - return self._generic_make_driver( - webdriver.Remote, webdriver.DesiredCapabilities.HTMLUNIT, remote, - desired_capabilities) - - def _make_htmlunitwithjs(self, remote, desired_capabilities, profile_dir): - return self._generic_make_driver( - webdriver.Remote, webdriver.DesiredCapabilities.HTMLUNITWITHJS, - remote, desired_capabilities) - - def _make_android(self, remote, desired_capabilities, profile_dir): - return self._generic_make_driver( - webdriver.Remote, webdriver.DesiredCapabilities.ANDROID, remote, - desired_capabilities) - - def _make_iphone(self, remote, desired_capabilities, profile_dir): - return self._generic_make_driver( - webdriver.Remote, webdriver.DesiredCapabilities.IPHONE, remote, - desired_capabilities) - - def _make_safari(self, remote, desired_capabilities, profile_dir): - return self._generic_make_driver( - webdriver.Safari, webdriver.DesiredCapabilities.SAFARI, remote, - desired_capabilities) - - def _make_edge(self, remote, desired_capabilities, profile_dir): - return self._generic_make_driver( - webdriver.Edge, webdriver.DesiredCapabilities.EDGE, remote, - desired_capabilities) - - def _generic_make_driver(self, webdriver_type, desired_cap_type, - remote_url, desired_caps, options=None): - """Generic driver creation - - Most of the make driver functions just call this function which - creates the appropriate driver - """ - if is_falsy(remote_url): - if options is None: - driver = webdriver_type() - else: - driver = webdriver_type(options=options) - else: - driver = self._create_remote_web_driver(desired_cap_type, - remote_url, desired_caps, - options=options) - return driver - - def _create_remote_web_driver(self, capabilities_type, remote_url, - desired_capabilities=None, profile=None, - options=None): - '''parses the string based desired_capabilities if neccessary and - creates the associated remote web driver''' - - desired_capabilities_object = capabilities_type.copy() - if not isinstance(desired_capabilities, dict): - desired_capabilities = self._parse_capabilities_string(desired_capabilities) - desired_capabilities_object.update(desired_capabilities or {}) - return webdriver.Remote(desired_capabilities=desired_capabilities_object, - command_executor=str(remote_url), browser_profile=profile, - options=options) - - def _parse_capabilities_string(self, capabilities_string): - '''parses the string based desired_capabilities which should be in the form - key1:val1,key2:val2 - ''' - desired_capabilities = {} - - if is_falsy(capabilities_string): - return desired_capabilities - - for cap in capabilities_string.split(","): - (key, value) = cap.split(":", 1) - desired_capabilities[key.strip()] = value.strip() - - return desired_capabilities - def _monkey_patch_speed(self, driver): def execute(self, driver_command, params=None): result = self._base_execute(driver_command, params) @@ -591,9 +439,3 @@ def execute(self, driver_command, params=None): driver._base_execute = driver.execute driver.execute = types.MethodType(execute, driver) driver._speed = self.ctx.speed - - @property - def _geckodriver_log_config(self): - if SELENIUM_VERSION.major == '3': - return {'log_path': os.path.join(self.log_dir, 'geckodriver.log')} - return {} diff --git a/src/SeleniumLibrary/keywords/waiting.py b/src/SeleniumLibrary/keywords/waiting.py index 539667fed..d5b6dde40 100644 --- a/src/SeleniumLibrary/keywords/waiting.py +++ b/src/SeleniumLibrary/keywords/waiting.py @@ -18,7 +18,7 @@ from SeleniumLibrary.base import LibraryComponent, keyword from SeleniumLibrary.errors import ElementNotFound -from SeleniumLibrary.utils import is_noney, is_truthy, secs_to_timestr +from SeleniumLibrary.utils import is_noney, secs_to_timestr class WaitingKeywords(LibraryComponent): diff --git a/src/SeleniumLibrary/keywords/webdrivercreator.py b/src/SeleniumLibrary/keywords/webdrivercreator.py new file mode 100644 index 000000000..70c48bf30 --- /dev/null +++ b/src/SeleniumLibrary/keywords/webdrivercreator.py @@ -0,0 +1,193 @@ +# Copyright 2008-2011 Nokia Networks +# Copyright 2011-2016 Ryan Tomac, Ed Manlove and contributors +# Copyright 2016- Robot Framework Foundation +# +# Licensed 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 copy +import os + +from selenium import webdriver + +from SeleniumLibrary.utils import is_falsy, is_truthy, SELENIUM_VERSION + + +class WebDriverCreator(object): + + browser_names = { + 'googlechrome': "chrome", + 'gc': "chrome", + 'chrome': "chrome", + 'headlesschrome': 'headless_chrome', + 'ff': 'firefox', + 'firefox': 'firefox', + 'headlessfirefox': 'headless_firefox', + 'ie': 'ie', + 'internetexplorer': 'ie', + 'edge': 'edge', + 'opera': 'opera', + 'safari': 'safari', + 'phantomjs': 'phantomjs', + 'htmlunit': 'htmlunit', + 'htmlunitwithjs': 'htmlunit_with_js', + 'android': 'android', + 'iphone': 'iphone' + } + + def __init__(self, log_dir): + self.log_dir = log_dir + + 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) + 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) + + def _get_creator_method(self, browser): + browser = browser.lower().replace(' ', '') + if browser in self.browser_names: + return getattr(self, 'create_{}'.format(self.browser_names[browser])) + raise ValueError('{} is not a supported browser.'.format(browser)) + + def _parse_capabilities(self, capabilities): + if isinstance(capabilities, dict): + return capabilities + desired_capabilities = {} + if is_falsy(capabilities): + return desired_capabilities + for part in capabilities.split(','): + key, value = part.split(':') + desired_capabilities[key.strip()] = value.strip() + return 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) + capabilities = self._combine_capabilites(default, desired_capabilities) + if SELENIUM_VERSION.major >= '3' and SELENIUM_VERSION.minor >= '8': + return webdriver.Chrome(desired_capabilities=capabilities, options=options) + return webdriver.Chrome(desired_capabilities=capabilities) + + def create_headless_chrome(self, desired_capabilities, remote_url): + if SELENIUM_VERSION.major >= '3' and SELENIUM_VERSION.minor >= '8': + options = webdriver.ChromeOptions() + options.set_headless() + else: + options=None + return self.create_chrome(desired_capabilities, remote_url, options) + + 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, profile) + capabilities = self._combine_capabilites(default, desired_capabilities) + 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) + + def _get_ff_profile(self, ff_profile_dir): + if is_falsy(ff_profile_dir): + return webdriver.FirefoxProfile() + return webdriver.FirefoxProfile(ff_profile_dir) + + @property + def _geckodriver_log(self): + if SELENIUM_VERSION.major >= '3': + return {'log_path': os.path.join(self.log_dir, 'geckodriver.log')} + return {} + + def create_headless_firefox(self, desired_capabilities, remote_url, + ff_profile_dir): + if SELENIUM_VERSION.major >= '3' and SELENIUM_VERSION.minor >= '8': + options = webdriver.FirefoxOptions() + options.set_headless() + else: + options = None + return self.create_firefox(desired_capabilities, remote_url, + 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) + + 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) + + 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) + + 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) + + 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) + + def create_htmlunit(self, desired_capabilities, remote_url): + default = webdriver.DesiredCapabilities.HTMLUNIT + return self._remote(default, 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) + + def create_android(self, desired_capabilities, remote_url): + default = webdriver.DesiredCapabilities.ANDROID + return self._remote(default, desired_capabilities, remote_url) + + def create_iphone(self, desired_capabilities, remote_url): + default = webdriver.DesiredCapabilities.IPHONE + return self._remote(default, desired_capabilities, remote_url) + + def _remote(self, default_capabilities, user_capabilities, remote_url, + profile_dir=None): + remote_url = str(remote_url) + capabilities = self._combine_capabilites(default_capabilities, + user_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 diff --git a/test/unit/keywords/test_browsermanagement.py b/test/unit/keywords/test_browsermanagement.py index 6ad0d665e..d2fb471f4 100644 --- a/test/unit/keywords/test_browsermanagement.py +++ b/test/unit/keywords/test_browsermanagement.py @@ -4,96 +4,11 @@ from selenium import webdriver from SeleniumLibrary.keywords import BrowserManagementKeywords +from SeleniumLibrary.utils import SELENIUM_VERSION class BrowserManagementTests(unittest.TestCase): - def test_create_firefox_browser(self): - test_browsers = ( - (webdriver.Firefox, "ff"), - (webdriver.Firefox, "firEfOx") - ) - - for test_browser in test_browsers: - self.verify_browser(*test_browser) - - def test_create_ie_browser(self): - test_browsers = ( - (webdriver.Ie, "ie"), - (webdriver.Ie, "Internet Explorer") - ) - - for test_browser in test_browsers: - self.verify_browser(*test_browser) - - def test_create_chrome_browser(self): - test_browsers = ( - (webdriver.Chrome, "gOOglEchrOmE"), - (webdriver.Chrome, "gc"), - (webdriver.Chrome, "chrome") - ) - - for test_browser in test_browsers: - self.verify_browser(*test_browser) - - def test_create_opera_browser(self): - self.verify_browser(webdriver.Opera, "OPERA") - - def test_create_phantomjs_browser(self): - self.verify_browser(webdriver.PhantomJS, "PHANTOMJS") - - def test_create_remote_browser(self): - self.verify_browser( - webdriver.Remote, "chrome", remote="http://127.0.0.1/wd/hub" - ) - - def test_create_htmlunit_browser(self): - self.verify_browser(webdriver.Remote, "htmlunit") - - def test_create_htmlunitwihtjs_browser(self): - self.verify_browser(webdriver.Remote, "htmlunitwithjs") - - def test_parse_capabilities_string(self): - ctx = mock() - bm = BrowserManagementKeywords(ctx) - expected_caps = "key1:val1,key2:val2" - capabilities = bm._parse_capabilities_string(expected_caps) - self.assertTrue("val1", capabilities["key1"]) - self.assertTrue("val2", capabilities["key2"]) - self.assertTrue(2, len(capabilities)) - unstub() - - def test_parse_complex_capabilities_string(self): - ctx = mock() - bm = BrowserManagementKeywords(ctx) - expected_caps = "proxyType:manual,httpProxy:IP:port" - capabilities = bm._parse_capabilities_string(expected_caps) - self.assertTrue("manual", capabilities["proxyType"]) - self.assertTrue("IP:port", capabilities["httpProxy"]) - self.assertTrue(2, len(capabilities)) - unstub() - - def test_create_remote_browser_with_desired_prefs(self): - expected_caps = {"key1": "val1", "key2": "val2"} - self.verify_browser( - webdriver.Remote, "chrome", remote="http://127.0.0.1/wd/hub", - desired_capabilities=expected_caps - ) - - def test_create_remote_browser_with_string_desired_prefs(self): - expected_caps = "key1:val1,key2:val2" - self.verify_browser( - webdriver.Remote, "chrome", remote="http://127.0.0.1/wd/hub", - desired_capabilities=expected_caps) - - def test_capabilities_attribute_not_modified(self): - expected_caps = {"some_cap": "42"} - self.verify_browser( - webdriver.Remote, "chrome", remote="http://127.0.0.1/wd/hub", - desired_capabilities=expected_caps - ) - self.assertFalse("some_cap" in webdriver.DesiredCapabilities.CHROME) - def test_set_selenium_timeout_only_affects_open_browsers(self): ctx = mock() ctx.timeout = 5.0 @@ -144,7 +59,12 @@ def test_open_browser_speed(self): ctx = mock() ctx.speed = 5.0 browser = mock() - when(webdriver).Chrome().thenReturn(browser) + 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) bm = BrowserManagementKeywords(ctx) bm.open_browser('http://robotframework.org/', 'chrome') self.assertEqual(browser._speed, 5.0) @@ -154,28 +74,13 @@ def test_create_webdriver_speed(self): ctx = mock() ctx.speed = 0.0 browser = mock() - when(webdriver).Chrome().thenReturn(browser) + 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) bm = BrowserManagementKeywords(ctx) bm.open_browser('http://robotframework.org/', 'chrome') verify(browser, times=0).__call__('_speed') unstub() - - def verify_browser(self, webdriver_type, browser_name, **kw): - # todo try lambda *x: was_called = true - ctx = mock() - bm = BrowserManagementKeywords(ctx) - old_init = webdriver_type.__init__ - webdriver_type.__init__ = self.mock_init - - try: - self.was_called = False - bm._make_driver(browser_name, **kw) - except AttributeError: - pass #kinda dangerous but I'm too lazy to mock out all the set_timeout calls - finally: - webdriver_type.__init__ = old_init - self.assertTrue(self.was_called) - unstub() - - def mock_init(self, *args, **kw): - self.was_called = True diff --git a/test/unit/utils/test_webdrivercreator.py b/test/unit/utils/test_webdrivercreator.py new file mode 100644 index 000000000..8d5d78311 --- /dev/null +++ b/test/unit/utils/test_webdrivercreator.py @@ -0,0 +1,330 @@ +import unittest + +from mockito import mock, verify, when, unstub +from selenium import webdriver + +from SeleniumLibrary.utils import SELENIUM_VERSION +from SeleniumLibrary.keywords import WebDriverCreator + + +class WebDriverCreatorTests(unittest.TestCase): + + @classmethod + def setUpClass(cls): + cls.creator = WebDriverCreator('/log/dir') + + def tearDown(self): + unstub() + + def test_get_creator_method(self): + method = self.creator._get_creator_method('chrome') + self.assertTrue(method) + + method = self.creator._get_creator_method('Chrome') + self.assertTrue(method) + + method = self.creator._get_creator_method('Fire Fox') + self.assertTrue(method) + + with self.assertRaisesRegexp(ValueError, 'foobar is not a supported browser.'): + self.creator._get_creator_method('foobar') + + def test_parse_capabilities(self): + caps = self.creator._parse_capabilities('key1:value1,key2:value2') + expected = {'key1': 'value1', 'key2': 'value2'} + self.assertDictEqual(caps, expected) + + caps = self.creator._parse_capabilities(expected) + self.assertDictEqual(caps, expected) + + caps = self.creator._parse_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'} + self.assertDictEqual(caps, expected) + + caps = self.creator._parse_capabilities('') + self.assertDictEqual(caps, {}) + + caps = self.creator._parse_capabilities({}) + self.assertDictEqual(caps, {}) + + def test_chrome(self): + expected_webdriver = mock() + caps = webdriver.DesiredCapabilities.CHROME + if SELENIUM_VERSION.major >= '3' and SELENIUM_VERSION.minor >= '8': + when(webdriver).Chrome(desired_capabilities=caps, + options=None).thenReturn(expected_webdriver) + else: + when(webdriver).Chrome(desired_capabilities=caps).thenReturn(expected_webdriver) + driver = self.creator.create_chrome({}, 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).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) + if SELENIUM_VERSION.major >= '3' and SELENIUM_VERSION.minor >= '8': + when(webdriver).Chrome(desired_capabilities=caps, + options=options).thenReturn(expected_webdriver) + else: + when(webdriver).Chrome(desired_capabilities=caps).thenReturn(expected_webdriver) + driver = self.creator.create_headless_chrome({}, None) + if SELENIUM_VERSION.major >= '3' and SELENIUM_VERSION.minor >= '8': + verify(options).set_headless() + else: + verify(options, times=0).set_headless() + self.assertEqual(driver, expected_webdriver) + + def test_firefox(self): + expected_webdriver = mock() + profile = mock() + when(webdriver).FirefoxProfile().thenReturn(profile) + caps = webdriver.DesiredCapabilities.FIREFOX + if SELENIUM_VERSION.major >= '3' and SELENIUM_VERSION.minor >= '8': + when(webdriver).Firefox(capabilities=caps, + options=None, + firefox_profile=profile, + log_path='/log/dir/geckodriver.log').thenReturn(expected_webdriver) + else: + when(webdriver).Firefox(capabilities=caps, + firefox_profile=profile).thenReturn(expected_webdriver) + driver = self.creator.create_firefox({}, None, None) + self.assertEqual(driver, expected_webdriver) + verify(webdriver).FirefoxProfile() + + def test_firefox_remote(self): + url = 'http://localhost:4444/wd/hub' + 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).thenReturn(expected_webdriver) + driver = self.creator.create_firefox({}, url, None) + self.assertEqual(driver, expected_webdriver) + + def test_firefox_profile(self): + expected_webdriver = mock() + profile = mock() + when(webdriver).FirefoxProfile('/profile/dir').thenReturn(profile) + caps = webdriver.DesiredCapabilities.FIREFOX + if SELENIUM_VERSION.major >= '3' and SELENIUM_VERSION.minor >= '8': + when(webdriver).Firefox(capabilities=caps, + options=None, + log_path='/log/dir/geckodriver.log', + firefox_profile=profile).thenReturn(expected_webdriver) + else: + when(webdriver).Firefox(capabilities=caps, + 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) + if SELENIUM_VERSION.major >= '3' and SELENIUM_VERSION.minor >= '8': + options = mock() + when(webdriver).FirefoxOptions().thenReturn(options) + when(webdriver).Firefox(capabilities=caps, + options=options, + log_path='/log/dir/geckodriver.log', + firefox_profile=profile).thenReturn(expected_webdriver) + else: + when(webdriver).Firefox(capabilities=caps, + firefox_profile=profile).thenReturn(expected_webdriver) + driver = self.creator.create_headless_firefox({}, None, None) + self.assertEqual(driver, expected_webdriver) + + def test_ie(self): + expected_webdriver = mock() + caps = webdriver.DesiredCapabilities.INTERNETEXPLORER + when(webdriver).Ie(capabilities=caps).thenReturn(expected_webdriver) + driver = self.creator.create_ie({}, 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).thenReturn(expected_webdriver) + driver = self.creator.create_ie({}, url) + self.assertEqual(driver, expected_webdriver) + + def test_edge(self): + expected_webdriver = mock() + caps = webdriver.DesiredCapabilities.EDGE + when(webdriver).Edge(capabilities=caps).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).thenReturn(expected_webdriver) + driver = self.creator.create_edge({}, url) + self.assertEqual(driver, expected_webdriver) + + def test_opera(self): + expected_webdriver = mock() + caps = webdriver.DesiredCapabilities.OPERA + when(webdriver).Opera(desired_capabilities=caps).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).thenReturn(expected_webdriver) + driver = self.creator.create_opera({}, url) + self.assertEqual(driver, expected_webdriver) + + def test_safari(self): + expected_webdriver = mock() + caps = webdriver.DesiredCapabilities.SAFARI + when(webdriver).Safari(desired_capabilities=caps).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).thenReturn(expected_webdriver) + driver = self.creator.create_safari({}, url) + self.assertEqual(driver, expected_webdriver) + + def test_phantomjs(self): + expected_webdriver = mock() + caps = webdriver.DesiredCapabilities.PHANTOMJS + when(webdriver).PhantomJS(desired_capabilities=caps).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).thenReturn(expected_webdriver) + driver = self.creator.create_phantomjs({}, url) + self.assertEqual(driver, expected_webdriver) + + def test_htmlunit(self): + expected_webdriver = mock() + caps = webdriver.DesiredCapabilities.HTMLUNIT + when(webdriver).Remote(command_executor='None', + desired_capabilities=caps, + browser_profile=None).thenReturn(expected_webdriver) + driver = self.creator.create_htmlunit({}, None) + self.assertEqual(driver, expected_webdriver) + + 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).thenReturn(expected_webdriver) + driver = self.creator.create_htmlunit_with_js({}, None) + self.assertEqual(driver, expected_webdriver) + + def test_android(self): + expected_webdriver = mock() + caps = webdriver.DesiredCapabilities.ANDROID + when(webdriver).Remote(command_executor='None', + desired_capabilities=caps, + browser_profile=None).thenReturn(expected_webdriver) + driver = self.creator.create_android({}, None) + self.assertEqual(driver, expected_webdriver) + + def test_iphone(self): + expected_webdriver = mock() + caps = webdriver.DesiredCapabilities.IPHONE + when(webdriver).Remote(command_executor='None', + desired_capabilities=caps, + browser_profile=None).thenReturn(expected_webdriver) + driver = self.creator.create_iphone({}, None) + self.assertEqual(driver, expected_webdriver) + + def test_create_driver_chrome(self): + expected_webdriver = mock() + caps = webdriver.DesiredCapabilities.CHROME + if SELENIUM_VERSION.major >= '3' and SELENIUM_VERSION.minor >= '8': + when(webdriver).Chrome(desired_capabilities=caps, + options=None).thenReturn(expected_webdriver) + else: + when(webdriver).Chrome(desired_capabilities=caps).thenReturn(expected_webdriver) + for browser in ['chrome', 'googlechrome', 'gc']: + driver = self.creator.create_driver(browser, None, None) + self.assertEqual(driver, expected_webdriver) + + def test_create_driver_firefox(self): + expected_webdriver = mock() + profile = mock() + when(webdriver).FirefoxProfile().thenReturn(profile) + caps = webdriver.DesiredCapabilities.FIREFOX + if SELENIUM_VERSION.major >= '3' and SELENIUM_VERSION.minor >= '8': + when(webdriver).Firefox(capabilities=caps, + options=None, + log_path='/log/dir/geckodriver.log', + firefox_profile=profile).thenReturn(expected_webdriver) + else: + when(webdriver).Firefox(capabilities=caps, + firefox_profile=profile).thenReturn(expected_webdriver) + for browser in ['ff', 'firefox']: + driver = self.creator.create_driver(browser, None, None, None) + self.assertEqual(driver, expected_webdriver) + + def test_create_driver_ie(self): + expected_webdriver = mock() + caps = webdriver.DesiredCapabilities.INTERNETEXPLORER + when(webdriver).Ie(capabilities=caps).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')