def config(): root_path = os.path.dirname(os.path.realpath(__file__)) conf_properties_file = os.path.join(root_path, 'conf', 'properties.cfg') config = ExtendedConfigParser() config.read(conf_properties_file) yield config # Remove used environment properties after test global environment_properties for env_property in environment_properties: try: del os.environ[env_property] except KeyError: pass environment_properties = []
def configure_properties(self, tc_config_prop_filenames=None, behave_properties=None): """Configure selenium instance properties :param tc_config_prop_filenames: test case specific properties filenames :param behave_properties: dict with behave user data properties """ prop_filenames = DriverWrappersPool.get_configured_value( 'Config_prop_filenames', tc_config_prop_filenames, 'properties.cfg;local-properties.cfg') prop_filenames = [ os.path.join(DriverWrappersPool.config_directory, filename) for filename in prop_filenames.split(';') ] prop_filenames = ';'.join(prop_filenames) # Configure config only if properties filename has changed if self.config_properties_filenames != prop_filenames: # Initialize the config object self.config = ExtendedConfigParser.get_config_from_file( prop_filenames) self.config_properties_filenames = prop_filenames # Override properties with system properties self.config.update_properties(os.environ) # Override properties with behave userdata properties if behave_properties: self.config.update_properties(behave_properties)
def test_a_toolium_param(): """ Verification of a mapped parameter as TOOLIUM """ config_file_path = os.path.join("toolium", "test", "resources", "toolium.cfg") dataset.toolium_config = ExtendedConfigParser.get_config_from_file(config_file_path) result = map_param("[TOOLIUM:TestExecution_environment]") expected = "QA" assert expected == result
def test_before_feature(start_driver): # Create context mock context = mock.MagicMock() context.toolium_config = ExtendedConfigParser() feature = mock.MagicMock() feature.tags = ['a', 'b'] before_feature(context, feature) # Check that start_driver is not called start_driver.assert_not_called()
def test_before_scenario_no_driver(start_driver, add_assert_screenshot_methods): # Create context mock context = mock.MagicMock() context.toolium_config = ExtendedConfigParser() scenario = mock.MagicMock() scenario.tags = ['a', 'no_driver', 'b'] before_scenario(context, scenario) # Check that start_driver is called start_driver.assert_called_once_with(context, True)
def test_before_scenario_reset_driver(start_driver, DriverWrappersPool, add_assert_screenshot_methods): # Create context mock context = mock.MagicMock() context.toolium_config = ExtendedConfigParser() scenario = mock.MagicMock() scenario.tags = ['a', 'reset_driver', 'b'] before_scenario(context, scenario) # Check that start_driver and stop drivers are called start_driver.assert_called_once_with(context, False) DriverWrappersPool.stop_drivers.assert_called_once_with()
def test_before_feature_reuse_driver_no_driver(start_driver): # Create context mock context = mock.MagicMock() context.toolium_config = ExtendedConfigParser() feature = mock.MagicMock() feature.tags = ['a', 'reuse_driver', 'b', 'no_driver'] before_feature(context, feature) # Check that start_driver is called when reuse_driver tag, with True no_driver param start_driver.assert_called_once_with(context, True) assert context.reuse_driver_from_tags is True
def configure_properties(self, tc_config_prop_filenames=None): """Configure selenium instance properties :param tc_config_prop_filenames: test case specific properties filenames """ prop_filenames = DriverWrappersPool.get_configured_value('Config_prop_filenames', tc_config_prop_filenames, 'properties.cfg;local-properties.cfg') prop_filenames = [os.path.join(DriverWrappersPool.config_directory, filename) for filename in prop_filenames.split(';')] prop_filenames = ';'.join(prop_filenames) # Configure config only if properties filename has changed if self.config_properties_filenames != prop_filenames: # Initialize the config object self.config = ExtendedConfigParser.get_config_from_file(prop_filenames) self.config_properties_filenames = prop_filenames # Override properties with system properties self.config.update_from_system_properties()
def configure_properties(self, tc_config_prop_filenames=None, behave_properties=None): """Configure selenium instance properties :param tc_config_prop_filenames: test case specific properties filenames :param behave_properties: dict with behave user data properties """ prop_filenames = DriverWrappersPool.get_configured_value( 'TOOLIUM_CONFIG_PROPERTIES_FILENAMES', 'Config_prop_filenames', tc_config_prop_filenames, 'properties.cfg;local-properties.cfg') prop_filenames = [ os.path.join(DriverWrappersPool.config_directory, filename) for filename in prop_filenames.split(';') ] prop_filenames = ';'.join(prop_filenames) # Configure config only if properties filename has changed if self.config_properties_filenames != prop_filenames: # Initialize the config object self.config = ExtendedConfigParser.get_config_from_file( prop_filenames) self.config_properties_filenames = prop_filenames # Override properties with system properties [Deprecated: use toolium system properties] self.config.update_properties(os.environ) # Override properties with toolium system properties self.config.update_toolium_system_properties(os.environ) # Override properties with behave userdata properties if behave_properties: self.config.update_properties(behave_properties) # Modify config properties before driver creation self.finalize_properties_configuration()
def config(): root_path = os.path.dirname(os.path.realpath(__file__)) conf_properties_file = os.path.join(root_path, 'conf', 'properties.cfg') config = ExtendedConfigParser() config.read(conf_properties_file) return config
def setUp(self): root_path = os.path.dirname(os.path.realpath(__file__)) conf_properties_file = os.path.join(root_path, 'conf', 'properties.cfg') self.config = ExtendedConfigParser() self.config.read(conf_properties_file)
class ExtendedConfigParserTests(unittest.TestCase): """ :type config: toolium.config_parser.ExtendedConfigParser or configparser.ConfigParser """ def setUp(self): root_path = os.path.dirname(os.path.realpath(__file__)) conf_properties_file = os.path.join(root_path, 'conf', 'properties.cfg') self.config = ExtendedConfigParser() self.config.read(conf_properties_file) @data(*optional_values) @unpack def test_get_optional(self, section, option, default, response): if default: assert_equal(response, self.config.get_optional(section, option, default)) else: assert_equal(response, self.config.get_optional(section, option)) @data(*optional_boolean_values) @unpack def test_getboolean_optional(self, section, option, default, response): if default: assert_equal( response, self.config.getboolean_optional(section, option, default)) else: assert_equal(response, self.config.getboolean_optional(section, option)) def test_deepcopy(self): section = 'AppiumCapabilities' option = 'automationName' orig_value = 'Appium' new_value = 'Selendroid' # Check previous value assert_equal(orig_value, self.config.get(section, option)) # Copy config object and modify a property new_config = self.config.deepcopy() new_config.set(section, option, new_value) # Check that the value has no changed in original config assert_equal(orig_value, self.config.get(section, option)) assert_equal(new_value, new_config.get(section, option)) def test_update_from_system_properties(self): section = 'AppiumCapabilities' option = 'platformName' orig_value = 'Android' new_value = 'iOS' # Check previous value assert_equal(orig_value, self.config.get(section, option)) # Change system property and update config os.environ[section + '_' + option] = new_value self.config.update_from_system_properties() # Check the new config value assert_equal(new_value, self.config.get(section, option))
def config(): config_parser = ExtendedConfigParser() config_parser.add_section('Server') config_parser.add_section('Driver') return config_parser
class ExtendedConfigParserTests(unittest.TestCase): """ :type config: toolium.config_parser.ExtendedConfigParser or configparser.ConfigParser """ def setUp(self): root_path = os.path.dirname(os.path.realpath(__file__)) conf_properties_file = os.path.join(root_path, 'conf', 'properties.cfg') self.config = ExtendedConfigParser() self.config.read(conf_properties_file) @data(*optional_values) @unpack def test_get_optional(self, section, option, default, response): if default: assert_equal(response, self.config.get_optional(section, option, default)) else: assert_equal(response, self.config.get_optional(section, option)) @data(*optional_boolean_values) @unpack def test_getboolean_optional(self, section, option, default, response): if default: assert_equal(response, self.config.getboolean_optional(section, option, default)) else: assert_equal(response, self.config.getboolean_optional(section, option)) def test_deepcopy(self): section = 'AppiumCapabilities' option = 'automationName' orig_value = 'Appium' new_value = 'Selendroid' # Check previous value assert_equal(orig_value, self.config.get(section, option)) # Copy config object and modify a property new_config = self.config.deepcopy() new_config.set(section, option, new_value) # Check that the value has no changed in original config assert_equal(orig_value, self.config.get(section, option)) assert_equal(new_value, new_config.get(section, option)) def test_update_from_system_properties(self): section = 'AppiumCapabilities' option = 'platformName' orig_value = 'Android' new_value = 'iOS' # Check previous value assert_equal(orig_value, self.config.get(section, option)) # Change system property and update config os.environ[section + '_' + option] = new_value self.config.update_from_system_properties() # Check the new config value assert_equal(new_value, self.config.get(section, option))
def setUp(self): self.config = ExtendedConfigParser() self.config.add_section('Server') self.config.add_section('Driver')
class ConfigDriverTests(unittest.TestCase): """ :type config: toolium.config_parser.ExtendedConfigParser or configparser.ConfigParser """ def setUp(self): self.config = ExtendedConfigParser() self.config.add_section('Server') self.config.add_section('Driver') def test_create_driver_local_not_configured(self): self.config.set('Driver', 'type', 'firefox') config_driver = ConfigDriver(self.config) config_driver._create_local_driver = lambda: 'local driver mock' config_driver._create_remote_driver = lambda: 'remote driver mock' driver = config_driver.create_driver() assert_equal(driver, 'local driver mock') def test_create_driver_local(self): self.config.set('Server', 'enabled', 'false') self.config.set('Driver', 'type', 'firefox') config_driver = ConfigDriver(self.config) config_driver._create_local_driver = lambda: 'local driver mock' config_driver._create_remote_driver = lambda: 'remote driver mock' driver = config_driver.create_driver() assert_equal(driver, 'local driver mock') def test_create_driver_remote(self): self.config.set('Server', 'enabled', 'true') self.config.set('Driver', 'type', 'firefox') config_driver = ConfigDriver(self.config) config_driver._create_local_driver = lambda: 'local driver mock' config_driver._create_remote_driver = lambda: 'remote driver mock' driver = config_driver.create_driver() assert_equal(driver, 'remote driver mock') @mock.patch('toolium.config_driver.webdriver') def test_create_local_driver_firefox(self, webdriver_mock): self.config.set('Driver', 'type', 'firefox') config_driver = ConfigDriver(self.config) config_driver._create_firefox_profile = lambda: 'firefox profile' config_driver._create_local_driver() webdriver_mock.Firefox.assert_called_once_with(capabilities=DesiredCapabilities.FIREFOX, firefox_profile='firefox profile') @mock.patch('toolium.config_driver.webdriver') def test_create_local_driver_chrome(self, webdriver_mock): self.config.set('Driver', 'type', 'chrome') self.config.set('Driver', 'chrome_driver_path', '/tmp/driver') config_driver = ConfigDriver(self.config) config_driver._create_chrome_options = lambda: 'chrome options' config_driver._create_local_driver() webdriver_mock.Chrome.assert_called_once_with('/tmp/driver', desired_capabilities=DesiredCapabilities.CHROME, chrome_options='chrome options') @mock.patch('toolium.config_driver.webdriver') def test_create_local_driver_safari(self, webdriver_mock): self.config.set('Driver', 'type', 'safari') config_driver = ConfigDriver(self.config) config_driver._create_local_driver() webdriver_mock.Safari.assert_called_once_with(desired_capabilities=DesiredCapabilities.SAFARI) @mock.patch('toolium.config_driver.webdriver') def test_create_local_driver_opera(self, webdriver_mock): self.config.set('Driver', 'type', 'opera') self.config.set('Driver', 'opera_driver_path', '/tmp/driver') config_driver = ConfigDriver(self.config) config_driver._create_local_driver() webdriver_mock.Opera.assert_called_once_with(desired_capabilities=DesiredCapabilities.OPERA, executable_path='/tmp/driver') @mock.patch('toolium.config_driver.webdriver') def test_create_local_driver_iexplore(self, webdriver_mock): self.config.set('Driver', 'type', 'iexplore') self.config.set('Driver', 'explorer_driver_path', '/tmp/driver') config_driver = ConfigDriver(self.config) config_driver._create_local_driver() webdriver_mock.Ie.assert_called_once_with('/tmp/driver', capabilities=DesiredCapabilities.INTERNETEXPLORER) @mock.patch('toolium.config_driver.webdriver') def test_create_local_driver_edge(self, webdriver_mock): self.config.set('Driver', 'type', 'edge') self.config.set('Driver', 'edge_driver_path', '/tmp/driver') config_driver = ConfigDriver(self.config) config_driver._create_local_driver() webdriver_mock.Edge.assert_called_once_with('/tmp/driver', capabilities=DesiredCapabilities.EDGE) @mock.patch('toolium.config_driver.webdriver') def test_create_local_driver_phantomjs(self, webdriver_mock): self.config.set('Driver', 'type', 'phantomjs') self.config.set('Driver', 'phantomjs_driver_path', '/tmp/driver') config_driver = ConfigDriver(self.config) config_driver._create_local_driver() webdriver_mock.PhantomJS.assert_called_once_with(desired_capabilities=DesiredCapabilities.PHANTOMJS, executable_path='/tmp/driver') def test_create_local_driver_android(self): self.config.set('Driver', 'type', 'android') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver = lambda: 'remote driver mock' driver = config_driver._create_local_driver() assert_equal(driver, 'remote driver mock') def test_create_local_driver_ios(self): self.config.set('Driver', 'type', 'ios') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver = lambda: 'remote driver mock' driver = config_driver._create_local_driver() assert_equal(driver, 'remote driver mock') def test_create_local_driver_iphone(self): self.config.set('Driver', 'type', 'iphone') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver = lambda: 'remote driver mock' driver = config_driver._create_local_driver() assert_equal(driver, 'remote driver mock') def test_create_local_driver_unknown_driver(self): self.config.set('Driver', 'type', 'unknown') config_driver = ConfigDriver(self.config) with assert_raises(Exception) as cm: config_driver._create_local_driver() assert_equal('Unknown driver unknown', str(cm.exception)) @mock.patch('toolium.config_driver.webdriver') def test_create_local_driver_capabilities(self, webdriver_mock): self.config.set('Driver', 'type', 'firefox') self.config.add_section('Capabilities') self.config.set('Capabilities', 'version', '45') config_driver = ConfigDriver(self.config) config_driver._create_firefox_profile = lambda: 'firefox profile' config_driver._create_local_driver() capabilities = DesiredCapabilities.FIREFOX capabilities['version'] = '45' webdriver_mock.Firefox.assert_called_once_with(capabilities=capabilities, firefox_profile='firefox profile') @mock.patch('toolium.config_driver.webdriver') def test_create_remote_driver_firefox(self, webdriver_mock): self.config.set('Server', 'host', '10.20.30.40') self.config.set('Server', 'port', '5555') self.config.set('Driver', 'type', 'firefox') config_driver = ConfigDriver(self.config) # Firefox profile mock class ProfileMock(object): encoded = 'encoded profile' config_driver._create_firefox_profile = mock.MagicMock(return_value=ProfileMock()) config_driver._create_remote_driver() capabilities = DesiredCapabilities.FIREFOX capabilities['firefox_profile'] = 'encoded profile' webdriver_mock.Remote.assert_called_once_with(command_executor='http://10.20.30.40:5555/wd/hub', desired_capabilities=capabilities) @mock.patch('toolium.config_driver.webdriver') def test_create_remote_driver_chrome(self, webdriver_mock): self.config.set('Server', 'host', '10.20.30.40') self.config.set('Server', 'port', '5555') self.config.set('Driver', 'type', 'chrome') config_driver = ConfigDriver(self.config) # Chrome options mock chrome_options = mock.MagicMock() chrome_options.to_capabilities.return_value = {'chromeOptions': 'chrome options'} config_driver._create_chrome_options = mock.MagicMock(return_value=chrome_options) config_driver._create_remote_driver() capabilities = DesiredCapabilities.CHROME capabilities['chromeOptions'] = 'chrome options' webdriver_mock.Remote.assert_called_once_with(command_executor='http://10.20.30.40:5555/wd/hub', desired_capabilities=capabilities) @mock.patch('toolium.config_driver.webdriver') def test_create_remote_driver_safari(self, webdriver_mock): self.config.set('Server', 'host', '10.20.30.40') self.config.set('Server', 'port', '5555') self.config.set('Driver', 'type', 'safari') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver() capabilities = DesiredCapabilities.SAFARI webdriver_mock.Remote.assert_called_once_with(command_executor='http://10.20.30.40:5555/wd/hub', desired_capabilities=capabilities) @mock.patch('toolium.config_driver.webdriver') def test_create_remote_driver_opera(self, webdriver_mock): self.config.set('Server', 'host', '10.20.30.40') self.config.set('Server', 'port', '5555') self.config.set('Driver', 'type', 'opera') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver() capabilities = DesiredCapabilities.OPERA capabilities['opera.autostart'] = True capabilities['opera.arguments'] = '-fullscreen' webdriver_mock.Remote.assert_called_once_with(command_executor='http://10.20.30.40:5555/wd/hub', desired_capabilities=capabilities) @mock.patch('toolium.config_driver.webdriver') def test_create_remote_driver_iexplore(self, webdriver_mock): self.config.set('Server', 'host', '10.20.30.40') self.config.set('Server', 'port', '5555') self.config.set('Driver', 'type', 'iexplore') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver() capabilities = DesiredCapabilities.INTERNETEXPLORER webdriver_mock.Remote.assert_called_once_with(command_executor='http://10.20.30.40:5555/wd/hub', desired_capabilities=capabilities) @mock.patch('toolium.config_driver.webdriver') def test_create_remote_driver_edge(self, webdriver_mock): self.config.set('Server', 'host', '10.20.30.40') self.config.set('Server', 'port', '5555') self.config.set('Driver', 'type', 'edge') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver() capabilities = DesiredCapabilities.EDGE webdriver_mock.Remote.assert_called_once_with(command_executor='http://10.20.30.40:5555/wd/hub', desired_capabilities=capabilities) @mock.patch('toolium.config_driver.webdriver') def test_create_remote_driver_phantomjs(self, webdriver_mock): self.config.set('Server', 'host', '10.20.30.40') self.config.set('Server', 'port', '5555') self.config.set('Driver', 'type', 'phantomjs') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver() capabilities = DesiredCapabilities.PHANTOMJS webdriver_mock.Remote.assert_called_once_with(command_executor='http://10.20.30.40:5555/wd/hub', desired_capabilities=capabilities) @mock.patch('toolium.config_driver.appiumdriver') def test_create_remote_driver_android(self, appiumdriver_mock): self.config.set('Server', 'host', '10.20.30.40') self.config.set('Server', 'port', '5555') self.config.set('Driver', 'type', 'android') self.config.add_section('AppiumCapabilities') self.config.set('AppiumCapabilities', 'automationName', 'Appium') self.config.set('AppiumCapabilities', 'platformName', 'Android') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver() capabilities = {'automationName': 'Appium', 'platformName': 'Android'} appiumdriver_mock.Remote.assert_called_once_with(command_executor='http://10.20.30.40:5555/wd/hub', desired_capabilities=capabilities) @mock.patch('toolium.config_driver.appiumdriver') def test_create_remote_driver_ios(self, appiumdriver_mock): self.config.set('Server', 'host', '10.20.30.40') self.config.set('Server', 'port', '5555') self.config.set('Driver', 'type', 'ios') self.config.add_section('AppiumCapabilities') self.config.set('AppiumCapabilities', 'automationName', 'Appium') self.config.set('AppiumCapabilities', 'platformName', 'iOS') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver() capabilities = {'automationName': 'Appium', 'platformName': 'iOS'} appiumdriver_mock.Remote.assert_called_once_with(command_executor='http://10.20.30.40:5555/wd/hub', desired_capabilities=capabilities) @mock.patch('toolium.config_driver.appiumdriver') def test_create_remote_driver_iphone(self, appiumdriver_mock): self.config.set('Server', 'host', '10.20.30.40') self.config.set('Server', 'port', '5555') self.config.set('Driver', 'type', 'iphone') self.config.add_section('AppiumCapabilities') self.config.set('AppiumCapabilities', 'automationName', 'Appium') self.config.set('AppiumCapabilities', 'platformName', 'iOS') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver() capabilities = {'automationName': 'Appium', 'platformName': 'iOS'} appiumdriver_mock.Remote.assert_called_once_with(command_executor='http://10.20.30.40:5555/wd/hub', desired_capabilities=capabilities) @mock.patch('toolium.config_driver.webdriver') def test_create_remote_driver_version_platform(self, webdriver_mock): self.config.set('Server', 'host', '10.20.30.40') self.config.set('Server', 'port', '5555') self.config.set('Driver', 'type', 'iexplore-11-on-WIN10') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver() capabilities = DesiredCapabilities.INTERNETEXPLORER capabilities['version'] = '11' capabilities['platform'] = 'WIN10' webdriver_mock.Remote.assert_called_once_with(command_executor='http://10.20.30.40:5555/wd/hub', desired_capabilities=capabilities) @mock.patch('toolium.config_driver.webdriver') def test_create_remote_driver_version(self, webdriver_mock): self.config.set('Server', 'host', '10.20.30.40') self.config.set('Server', 'port', '5555') self.config.set('Driver', 'type', 'iexplore-11') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver() capabilities = DesiredCapabilities.INTERNETEXPLORER capabilities['version'] = '11' webdriver_mock.Remote.assert_called_once_with(command_executor='http://10.20.30.40:5555/wd/hub', desired_capabilities=capabilities) @mock.patch('toolium.config_driver.webdriver') def test_create_remote_driver_capabilities(self, webdriver_mock): self.config.set('Server', 'host', '10.20.30.40') self.config.set('Server', 'port', '5555') self.config.set('Driver', 'type', 'iexplore-11') self.config.add_section('Capabilities') self.config.set('Capabilities', 'version', '11') config_driver = ConfigDriver(self.config) config_driver._create_remote_driver() capabilities = DesiredCapabilities.INTERNETEXPLORER capabilities['version'] = '11' webdriver_mock.Remote.assert_called_once_with(command_executor='http://10.20.30.40:5555/wd/hub', desired_capabilities=capabilities) def test_convert_property_type_true(self): config_driver = ConfigDriver(self.config) value = 'True' assert_equal(config_driver._convert_property_type(value), True) def test_convert_property_type_false(self): config_driver = ConfigDriver(self.config) value = 'False' assert_equal(config_driver._convert_property_type(value), False) def test_convert_property_type_dict(self): config_driver = ConfigDriver(self.config) value = "{'a': 5}" assert_equal(config_driver._convert_property_type(value), {'a': 5}) def test_convert_property_type_int(self): config_driver = ConfigDriver(self.config) value = '5' assert_equal(config_driver._convert_property_type(value), 5) def test_convert_property_type_str(self): config_driver = ConfigDriver(self.config) value = 'string' assert_equal(config_driver._convert_property_type(value), value) @mock.patch('toolium.config_driver.webdriver') def test_create_firefox_profile(self, webdriver_mock): self.config.add_section('Firefox') self.config.set('Firefox', 'profile', '/tmp') self.config.add_section('FirefoxPreferences') self.config.set('FirefoxPreferences', 'browser.download.folderList', '2') self.config.add_section('FirefoxExtensions') self.config.set('FirefoxExtensions', 'firebug', 'resources/firebug-3.0.0-beta.3.xpi') config_driver = ConfigDriver(self.config) config_driver._create_firefox_profile() webdriver_mock.FirefoxProfile.assert_called_once_with(profile_directory='/tmp') webdriver_mock.FirefoxProfile().set_preference.assert_called_once_with('browser.download.folderList', 2) webdriver_mock.FirefoxProfile().update_preferences.assert_called_once_with() webdriver_mock.FirefoxProfile().add_extension.assert_called_once_with('resources/firebug-3.0.0-beta.3.xpi') @mock.patch('toolium.config_driver.webdriver') def test_create_chrome_options(self, webdriver_mock): self.config.add_section('ChromePreferences') self.config.set('ChromePreferences', 'download.default_directory', '/tmp') self.config.add_section('ChromeMobileEmulation') self.config.set('ChromeMobileEmulation', 'deviceName', 'Google Nexus 5') self.config.add_section('ChromeArguments') self.config.set('ChromeArguments', 'lang', 'es') config_driver = ConfigDriver(self.config) config_driver._create_chrome_options() webdriver_mock.ChromeOptions.assert_called_once_with() webdriver_mock.ChromeOptions().add_experimental_option.assert_has_calls( [mock.call('prefs', {'download.default_directory': '/tmp'}), mock.call('mobileEmulation', {'deviceName': 'Google Nexus 5'})]) webdriver_mock.ChromeOptions().add_argument.assert_called_once_with('lang=es')
class DriverWrapper(object): """Wrapper with the webdriver and the configuration needed to execute tests :type driver: selenium.webdriver.remote.webdriver.WebDriver or appium.webdriver.webdriver.WebDriver :type config: toolium.config_parser.ExtendedConfigParser or configparser.ConfigParser :type utils: toolium.utils.driver_utils.Utils :type app_strings: dict :type session_id: str :type remote_node: str :type remote_node_video_enabled: bool :type logger: logging.Logger :type config_properties_filenames: str :type config_log_filename: str :type output_log_filename: str :type visual_baseline_directory: str :type baseline_name: str """ driver = None #: webdriver instance config = ExtendedConfigParser() #: driver configuration utils = None #: test utils instance app_strings = None #: mobile application strings session_id = None #: remote webdriver session id server_type = None #: remote server type remote_node = None #: remote grid node remote_node_video_enabled = False #: True if the remote grid node has the video recorder enabled logger = None #: logger instance # Configuration and output files config_properties_filenames = None #: configuration filenames separated by commas config_log_filename = None #: configuration log file output_log_filename = None #: output log file visual_baseline_directory = None #: folder with the baseline images baseline_name = None #: baseline name def __init__(self): if not DriverWrappersPool.is_empty(): # Copy config object and other properties from default driver default_wrapper = DriverWrappersPool.get_default_wrapper() self.config = default_wrapper.config.deepcopy() self.logger = default_wrapper.logger self.config_properties_filenames = default_wrapper.config_properties_filenames self.config_log_filename = default_wrapper.config_log_filename self.output_log_filename = default_wrapper.output_log_filename self.visual_baseline_directory = default_wrapper.visual_baseline_directory self.baseline_name = default_wrapper.baseline_name # Create utils instance and add wrapper to the pool self.utils = Utils(self) DriverWrappersPool.add_wrapper(self) def configure_logger(self, tc_config_log_filename=None, tc_output_log_filename=None): """Configure selenium instance logger :param tc_config_log_filename: test case specific logging config file :param tc_output_log_filename: test case specific output logger file """ # Get config logger filename config_log_filename = DriverWrappersPool.get_configured_value( 'TOOLIUM_CONFIG_LOG_FILENAME', 'Config_log_filename', tc_config_log_filename, 'logging.conf') config_log_filename = os.path.join(DriverWrappersPool.config_directory, config_log_filename) # Configure logger only if logging filename has changed if self.config_log_filename != config_log_filename: # Get output logger filename output_log_filename = DriverWrappersPool.get_configured_value( 'TOOLIUM_OUTPUT_LOG_FILENAME', 'Output_log_filename', tc_output_log_filename, 'toolium.log') output_log_filename = os.path.join( DriverWrappersPool.output_directory, output_log_filename) output_log_filename = output_log_filename.replace('\\', '\\\\') try: logging.config.fileConfig(config_log_filename, {'logfilename': output_log_filename}, False) except Exception as exc: print( "[WARN] Error reading logging config file '{}': {}".format( config_log_filename, exc)) self.config_log_filename = config_log_filename self.output_log_filename = output_log_filename self.logger = logging.getLogger(__name__) def configure_properties(self, tc_config_prop_filenames=None, behave_properties=None): """Configure selenium instance properties :param tc_config_prop_filenames: test case specific properties filenames :param behave_properties: dict with behave user data properties """ prop_filenames = DriverWrappersPool.get_configured_value( 'TOOLIUM_CONFIG_PROPERTIES_FILENAMES', 'Config_prop_filenames', tc_config_prop_filenames, 'properties.cfg;local-properties.cfg') prop_filenames = [ os.path.join(DriverWrappersPool.config_directory, filename) for filename in prop_filenames.split(';') ] prop_filenames = ';'.join(prop_filenames) # Configure config only if properties filename has changed if self.config_properties_filenames != prop_filenames: # Initialize the config object self.config = ExtendedConfigParser.get_config_from_file( prop_filenames) self.config_properties_filenames = prop_filenames # Override properties with system properties [Deprecated: use toolium system properties] self.config.update_properties(os.environ) # Override properties with toolium system properties self.config.update_toolium_system_properties(os.environ) # Override properties with behave userdata properties if behave_properties: self.config.update_properties(behave_properties) # Modify config properties before driver creation self.finalize_properties_configuration() def finalize_properties_configuration(self): # Override method if config properties (self.config object) need custom modifications before driver creation pass def configure_visual_baseline(self): """Configure baseline directory""" # Get baseline name and translate config variables baseline_name = self.config.get_optional('VisualTests', 'baseline_name', '{Driver_type}') baseline_name = self.config.translate_config_variables(baseline_name) # Configure baseline directory if baseline name has changed if self.baseline_name != baseline_name: self.baseline_name = baseline_name self.visual_baseline_directory = os.path.join( DriverWrappersPool.visual_baseline_directory, get_valid_filename(baseline_name)) def update_visual_baseline(self): """Configure baseline directory after driver is created""" # Update baseline with real platformVersion value if '{PlatformVersion}' in self.baseline_name: try: platform_version = self.driver.desired_capabilities[ 'platformVersion'] except KeyError: platform_version = None self.baseline_name = self.baseline_name.replace( '{PlatformVersion}', str(platform_version)) self.visual_baseline_directory = os.path.join( DriverWrappersPool.visual_baseline_directory, self.baseline_name) # Update baseline with real version value if '{Version}' in self.baseline_name: try: splitted_version = self.driver.desired_capabilities[ 'version'].split('.') version = '.'.join(splitted_version[:2]) except KeyError: version = None self.baseline_name = self.baseline_name.replace( '{Version}', str(version)) self.visual_baseline_directory = os.path.join( DriverWrappersPool.visual_baseline_directory, self.baseline_name) # Update baseline with remote node value if '{RemoteNode}' in self.baseline_name: self.baseline_name = self.baseline_name.replace( '{RemoteNode}', str(self.remote_node)) self.visual_baseline_directory = os.path.join( DriverWrappersPool.visual_baseline_directory, self.baseline_name) def configure(self, tc_config_files, is_selenium_test=True, behave_properties=None): """Configure initial selenium instance using logging and properties files for Selenium or Appium tests :param tc_config_files: test case specific config files :param is_selenium_test: true if test is a selenium or appium test case :param behave_properties: dict with behave user data properties """ # Configure config and output directories DriverWrappersPool.configure_common_directories(tc_config_files) # Configure logger self.configure_logger(tc_config_files.config_log_filename, tc_config_files.output_log_filename) # Initialize the config object self.configure_properties(tc_config_files.config_properties_filenames, behave_properties) # Configure visual directories if is_selenium_test: driver_info = self.config.get('Driver', 'type') DriverWrappersPool.configure_visual_directories(driver_info) self.configure_visual_baseline() def connect(self): """Set up the selenium driver and connect to the server :returns: selenium driver """ if not self.config.get('Driver', 'type') or self.config.get( 'Driver', 'type') in ['api', 'no_driver']: return None self.driver = ConfigDriver(self.config, self.utils).create_driver() # Save session id and remote node to download video after the test execution self.session_id = self.driver.session_id self.server_type, self.remote_node = self.utils.get_remote_node() self.remote_node_video_enabled = self.utils.is_remote_video_enabled( self.server_type, self.remote_node) # Save app_strings in mobile tests if (self.is_mobile_test() and not self.is_web_test() and self.config.getboolean_optional( 'Driver', 'appium_app_strings')): self.app_strings = self.driver.app_strings() # Resize and move browser self.resize_window() # Log window size window_size = self.utils.get_window_size() self.logger.debug('Window size: %s x %s', window_size['width'], window_size['height']) # Update baseline self.update_visual_baseline() # Discard previous logcat logs self.utils.discard_logcat_logs() # Set implicitly wait timeout self.utils.set_implicitly_wait() return self.driver def resize_window(self): """Resize and move browser window""" if self.is_maximizable(): # Configure window bounds bounds_x, bounds_y = self.get_config_window_bounds() self.driver.set_window_position(bounds_x, bounds_y) self.logger.debug('Window bounds: %s x %s', bounds_x, bounds_y) # Set window size or maximize window_width = self.config.get_optional('Driver', 'window_width') window_height = self.config.get_optional('Driver', 'window_height') if window_width and window_height: self.driver.set_window_size(window_width, window_height) else: self.driver.maximize_window() def get_config_window_bounds(self): """Reads bounds from config and, if monitor is specified, modify the values to match with the specified monitor :return: coords X and Y where set the browser window. """ bounds_x = int(self.config.get_optional('Driver', 'bounds_x') or 0) bounds_y = int(self.config.get_optional('Driver', 'bounds_y') or 0) monitor_index = int( self.config.get_optional('Driver', 'monitor') or -1) if monitor_index > -1: try: monitor = screeninfo.get_monitors()[monitor_index] bounds_x += monitor.x bounds_y += monitor.y except NotImplementedError: self.logger.warning( 'Current environment doesn\'t support get_monitors') return bounds_x, bounds_y def is_android_test(self): """Check if actual test must be executed in an Android mobile :returns: True if test must be executed in an Android mobile """ return self.utils.get_driver_name() == 'android' def is_ios_test(self): """Check if actual test must be executed in an iOS mobile :returns: True if test must be executed in an iOS mobile """ return self.utils.get_driver_name() in ('ios', 'iphone') def is_mobile_test(self): """Check if actual test must be executed in a mobile :returns: True if test must be executed in a mobile """ return self.is_android_test() or self.is_ios_test() def is_web_test(self): """Check if actual test must be executed in a browser :returns: True if test must be executed in a browser """ appium_browser_name = self.config.get_optional('AppiumCapabilities', 'browserName') return not self.is_mobile_test() or appium_browser_name not in (None, '') def is_android_web_test(self): """Check if actual test must be executed in a browser of an Android mobile :returns: True if test must be executed in a browser of an Android mobile """ return self.is_android_test() and self.is_web_test() def is_ios_web_test(self): """Check if actual test must be executed in a browser of an iOS mobile :returns: True if test must be executed in a browser of an iOS mobile """ return self.is_ios_test() and self.is_web_test() def is_maximizable(self): """Check if the browser is maximizable :returns: True if the browser is maximizable """ return not self.is_mobile_test() def should_reuse_driver(self, scope, test_passed, context=None): """Check if the driver should be reused :param scope: execution scope (function, module, class or session) :param test_passed: True if the test has passed :param context: behave context :returns: True if the driver should be reused """ reuse_driver = self.config.getboolean_optional('Driver', 'reuse_driver') reuse_driver_session = self.config.getboolean_optional( 'Driver', 'reuse_driver_session') restart_driver_after_failure = (self.config.getboolean_optional( 'Driver', 'restart_driver_after_failure') or self.config.getboolean_optional( 'Driver', 'restart_driver_fail')) if context and scope == 'function': reuse_driver = reuse_driver or (hasattr(context, 'reuse_driver_from_tags') and context.reuse_driver_from_tags) return (((reuse_driver and scope == 'function') or (reuse_driver_session and scope != 'session')) and (test_passed or not restart_driver_after_failure)) def get_driver_platform(self): """ Get driver platform where tests are running :return: platform name """ platform = '' if 'platform' in self.driver.desired_capabilities: platform = self.driver.desired_capabilities['platform'] elif 'platformName' in self.driver.desired_capabilities: platform = self.driver.desired_capabilities['platformName'] return platform
class DriverWrapper(object): """Wrapper with the webdriver and the configuration needed to execute tests :type driver: selenium.webdriver.remote.webdriver.WebDriver or appium.webdriver.webdriver.WebDriver :type config: toolium.config_parser.ExtendedConfigParser or configparser.ConfigParser :type utils: toolium.utils.Utils :type app_strings: dict :type session_id: str :type remote_node: str :type remote_node_video_enabled: bool :type logger: logging.Logger :type config_properties_filenames: str :type config_log_filename: str :type output_log_filename: str :type visual_baseline_directory: str :type baseline_name: str """ driver = None #: webdriver instance config = ExtendedConfigParser() #: driver configuration utils = None #: test utils instance app_strings = None #: mobile application strings session_id = None #: remote webdriver session id remote_node = None #: remote grid node remote_node_video_enabled = False #: True if the remote grid node has the video recorder enabled logger = None #: logger instance # Configuration and output files config_properties_filenames = None #: configuration filenames separated by commas config_log_filename = None #: configuration log file output_log_filename = None #: output log file visual_baseline_directory = None #: folder with the baseline images baseline_name = None #: baseline name def __init__(self): if not DriverWrappersPool.is_empty(): # Copy config object and other properties from default driver default_wrapper = DriverWrappersPool.get_default_wrapper() self.config = default_wrapper.config.deepcopy() self.logger = default_wrapper.logger self.config_properties_filenames = default_wrapper.config_properties_filenames self.config_log_filename = default_wrapper.config_log_filename self.output_log_filename = default_wrapper.output_log_filename self.visual_baseline_directory = default_wrapper.visual_baseline_directory self.baseline_name = default_wrapper.baseline_name # Create utils instance and add wrapper to the pool self.utils = Utils(self) DriverWrappersPool.add_wrapper(self) def configure_logger(self, tc_config_log_filename=None, tc_output_log_filename=None): """Configure selenium instance logger :param tc_config_log_filename: test case specific logging config file :param tc_output_log_filename: test case specific output logger file """ # Get config logger filename config_log_filename = DriverWrappersPool.get_configured_value('Config_log_filename', tc_config_log_filename, 'logging.conf') config_log_filename = os.path.join(DriverWrappersPool.config_directory, config_log_filename) # Configure logger only if logging filename has changed if self.config_log_filename != config_log_filename: # Get output logger filename output_log_filename = DriverWrappersPool.get_configured_value('Output_log_filename', tc_output_log_filename, 'toolium.log') output_log_filename = os.path.join(DriverWrappersPool.output_directory, output_log_filename) output_log_filename = output_log_filename.replace('\\', '\\\\') try: logging.config.fileConfig(config_log_filename, {'logfilename': output_log_filename}, False) except Exception as exc: print("[WARN] Error reading logging config file '{}': {}".format(config_log_filename, exc)) self.config_log_filename = config_log_filename self.output_log_filename = output_log_filename self.logger = logging.getLogger(__name__) def configure_properties(self, tc_config_prop_filenames=None, behave_properties=None): """Configure selenium instance properties :param tc_config_prop_filenames: test case specific properties filenames :param behave_properties: dict with behave user data properties """ prop_filenames = DriverWrappersPool.get_configured_value('Config_prop_filenames', tc_config_prop_filenames, 'properties.cfg;local-properties.cfg') prop_filenames = [os.path.join(DriverWrappersPool.config_directory, filename) for filename in prop_filenames.split(';')] prop_filenames = ';'.join(prop_filenames) # Configure config only if properties filename has changed if self.config_properties_filenames != prop_filenames: # Initialize the config object self.config = ExtendedConfigParser.get_config_from_file(prop_filenames) self.config_properties_filenames = prop_filenames # Override properties with system properties self.config.update_properties(os.environ) # Override properties with behave userdata properties if behave_properties: self.config.update_properties(behave_properties) def configure_visual_baseline(self): """Configure baseline directory""" # Get baseline name baseline_name = self.config.get_optional('VisualTests', 'baseline_name', '{Driver_type}') for section in self.config.sections(): for option in self.config.options(section): option_value = self.config.get(section, option).replace('-', '_').replace(' ', '_') baseline_name = baseline_name.replace('{{{0}_{1}}}'.format(section, option), option_value) # Configure baseline directory if baseline name has changed if self.baseline_name != baseline_name: self.baseline_name = baseline_name self.visual_baseline_directory = os.path.join(DriverWrappersPool.visual_baseline_directory, baseline_name) def update_visual_baseline(self): """Configure baseline directory after driver is created""" # Update baseline with real platformVersion value if '{PlatformVersion}' in self.baseline_name: try: platform_version = self.driver.desired_capabilities['platformVersion'] except KeyError: platform_version = None self.baseline_name = self.baseline_name.replace('{PlatformVersion}', str(platform_version)) self.visual_baseline_directory = os.path.join(DriverWrappersPool.visual_baseline_directory, self.baseline_name) # Update baseline with real version value if '{Version}' in self.baseline_name: try: splitted_version = self.driver.desired_capabilities['version'].split('.') version = '.'.join(splitted_version[:2]) except KeyError: version = None self.baseline_name = self.baseline_name.replace('{Version}', str(version)) self.visual_baseline_directory = os.path.join(DriverWrappersPool.visual_baseline_directory, self.baseline_name) # Update baseline with remote node value if '{RemoteNode}' in self.baseline_name: self.baseline_name = self.baseline_name.replace('{RemoteNode}', str(self.remote_node)) self.visual_baseline_directory = os.path.join(DriverWrappersPool.visual_baseline_directory, self.baseline_name) def configure(self, is_selenium_test=True, tc_config_files=None, behave_properties=None): """Configure initial selenium instance using logging and properties files for Selenium or Appium tests :param is_selenium_test: true if test is a selenium or appium test case :param tc_config_files: test case specific config files :param behave_properties: dict with behave user data properties """ # Initialize config files tc_config_files = self._initialize_config_files(tc_config_files) # Configure config and output directories DriverWrappersPool.configure_common_directories(tc_config_files) # Configure logger self.configure_logger(tc_config_files.config_log_filename, tc_config_files.output_log_filename) # Initialize the config object self.configure_properties(tc_config_files.config_properties_filenames, behave_properties) # Configure visual directories if is_selenium_test: driver_info = self.config.get('Driver', 'type').replace('-', '_') DriverWrappersPool.configure_visual_directories(driver_info) self.configure_visual_baseline() @staticmethod def _initialize_config_files(tc_config_files=None): """Initialize config files and update config files names with the environment :param tc_config_files: test case specific config files :returns: initialized config files object """ # Initialize config files if tc_config_files is None: tc_config_files = ConfigFiles() # Update properties and log file names if an environment is configured env = DriverWrappersPool.get_configured_value('Config_environment', None, None) if env: # Update config properties filenames prop_filenames = tc_config_files.config_properties_filenames new_prop_filenames_list = prop_filenames.split(';') if prop_filenames else ['properties.cfg'] base = new_prop_filenames_list[0].split('.')[0] ext = new_prop_filenames_list[0].split('.')[1] new_prop_filenames_list.append('{}-{}.{}'.format(env, base, ext)) new_prop_filenames_list.append('local-{}-{}.{}'.format(env, base, ext)) tc_config_files.set_config_properties_filenames(*new_prop_filenames_list) # Update output log filename output_log_filename = tc_config_files.output_log_filename base = output_log_filename.split('.')[0] if output_log_filename else 'toolium' ext = output_log_filename.split('.')[1] if output_log_filename else 'log' tc_config_files.set_output_log_filename('{}_{}.{}'.format(base, env, ext)) return tc_config_files def connect(self, maximize=True): """Set up the selenium driver and connect to the server :param maximize: True if the driver should be maximized :returns: selenium driver """ if not self.config.get('Driver', 'type'): return None self.driver = ConfigDriver(self.config).create_driver() # Save session id and remote node to download video after the test execution self.session_id = self.driver.session_id self.remote_node = self.utils.get_remote_node() self.remote_node_video_enabled = self.utils.is_remote_video_enabled(self.remote_node) # Save app_strings in mobile tests if self.is_mobile_test() and not self.is_web_test() and self.config.getboolean_optional('Driver', 'appium_app_strings'): self.app_strings = self.driver.app_strings() # Maximize browser if maximize and self.is_maximizable(): # Set window size or maximize window_width = self.config.get_optional('Driver', 'window_width') window_height = self.config.get_optional('Driver', 'window_height') if window_width and window_height: self.driver.set_window_size(window_width, window_height) else: self.driver.maximize_window() # Log window size window_size = self.utils.get_window_size() self.logger.debug('Window size: %s x %s', window_size['width'], window_size['height']) # Update baseline self.update_visual_baseline() # Discard previous logcat logs self.utils.discard_logcat_logs() # Set implicitly wait timeout self.utils.set_implicitly_wait() return self.driver def is_android_test(self): """Check if actual test must be executed in an Android mobile :returns: true if test must be executed in an Android mobile """ driver_name = self.config.get('Driver', 'type').split('-')[0] return driver_name == 'android' def is_ios_test(self): """Check if actual test must be executed in an iOS mobile :returns: true if test must be executed in an iOS mobile """ driver_name = self.config.get('Driver', 'type').split('-')[0] return driver_name in ('ios', 'iphone') def is_mobile_test(self): """Check if actual test must be executed in a mobile :returns: true if test must be executed in a mobile """ return self.is_android_test() or self.is_ios_test() def is_web_test(self): """Check if actual test must be executed in a browser :returns: true if test must be executed in a browser """ appium_browser_name = self.config.get_optional('AppiumCapabilities', 'browserName') return not self.is_mobile_test() or appium_browser_name not in (None, '') def is_android_web_test(self): """Check if actual test must be executed in a browser of an Android mobile :returns: true if test must be executed in a browser of an Android mobile """ return self.is_android_test() and self.is_web_test() def is_ios_web_test(self): """Check if actual test must be executed in a browser of an iOS mobile :returns: true if test must be executed in a browser of an iOS mobile """ return self.is_ios_test() and self.is_web_test() def is_maximizable(self): """Check if the browser is maximizable :returns: true if the browser is maximizable """ return not self.is_mobile_test()